diff --git a/SkywardHub.pro b/SkywardHub.pro index 97a8c79b4df4e46bfc718c5424d863d5bc98c1b2..18856e2e63494db082069f63479ecedab9e311f4 100644 --- a/SkywardHub.pro +++ b/SkywardHub.pro @@ -126,7 +126,6 @@ HEADERS += \ FORMS += \ src/shared/Modules/ValuesConverterViewer/ValuesConverterViewerModule.ui \ src/shared/Modules/ValuesConverterViewer/ValuesViewerConfigPanel.ui \ - src/shared/Modules/OutgoingMessagesViewer/OutgoingMessagesViewerModule.ui \ src/shared/Modules/TimerController/TimerControllerModule.ui \ src/shared/Modules/FileStream/FileStreamModule.ui \ src/shared/Modules/Test/TestModule.ui \ diff --git a/src/shared/Modules/OutgoingMessagesViewer/OutgoingMessagesViewerModule.cpp b/src/shared/Modules/OutgoingMessagesViewer/OutgoingMessagesViewerModule.cpp index 7be4f30fbfee0ab866173d302f8f741b90eb17ff..6c2f80af613f3749adc1b6247bc306f8bb9c9cab 100644 --- a/src/shared/Modules/OutgoingMessagesViewer/OutgoingMessagesViewerModule.cpp +++ b/src/shared/Modules/OutgoingMessagesViewer/OutgoingMessagesViewerModule.cpp @@ -19,145 +19,189 @@ #include "OutgoingMessagesViewerModule.h" #include <Core/MessageBroker/MessageBroker.h> +#include <Modules/SkywardHubStrings.h> +#include <QDebug> #include <QTableWidgetItem> -#include "Modules/SkywardHubStrings.h" -#include "ui_OutgoingMessagesViewerModule.h" - -OutgoingMessagesViewerModule::OutgoingMessagesViewerModule() - : Module(ModuleId::OUTGOING_MESSAGES_VIEWER), - ui(new Ui::OutgoingMessagesViewerModule) +OutgoingMessagesViewerModule::OutgoingMessagesViewerModule(QWidget* parent) + : DefaultModule(parent) { - ui->setupUi(this); + setupUi(); + defaultContextMenuSetup(); - MessageBroker::getInstance().subscribe( + // Subscribe to commands, ACKs and NACKs + getCore()->getMessageBroker()->subscribe( Filter::fromString(SkywardHubStrings::logCommandsTopic), this, [this](const Message& message, const Filter& filter) - { addMsgSent(message); }); - - MessageBroker::getInstance().subscribe( + { handleMsg(message); }); + getCore()->getMessageBroker()->subscribe( Filter::fromString(SkywardHubStrings::mavlink_received_msg_ACK_topic), - this, - [this](const Message& message, const Filter& filter) + this, [this](const Message& message, const Filter& filter) { handleAck(message); }); MessageBroker::getInstance().subscribe( Filter::fromString(SkywardHubStrings::mavlink_received_msg_NACK_topic), - this, - [this](const Message& message, const Filter& filter) + this, [this](const Message& message, const Filter& filter) { handleNack(message); }); MessageBroker::getInstance().subscribe( Filter::fromString(SkywardHubStrings::mavlink_received_msg_WACK_topic), - this, - [this](const Message& message, const Filter& filter) + this, [this](const Message& message, const Filter& filter) { handleWack(message); }); } -OutgoingMessagesViewerModule::~OutgoingMessagesViewerModule() { delete ui; } +QWidget* OutgoingMessagesViewerModule::toWidget() { return this; } -void OutgoingMessagesViewerModule::addMsgSent(const Message& msg) +XmlObject OutgoingMessagesViewerModule::toXmlObject() { - int row = updateVerticalHeaders(msg); - int column = 0; - - QString msgName = computeMsgName(msg); - QTableWidgetItem* newItem = new QTableWidgetItem(msgName); - newItem->setBackground(QBrush(QColor(80, 80, 80))); - newItem->setForeground(QBrush(QColor(0, 0, 0))); - ui->tableWidget->setItem(row, column, newItem); - registerMessage(newItem, msg); + return XmlObject(getName(ModuleId::OUTCOMINGMESSAGEVIEWER)); } -QString OutgoingMessagesViewerModule::computeMsgName(const Message& msg) +void OutgoingMessagesViewerModule::fromXmlObject(const XmlObject& xmlObject) { - return msg.getField("name").toString(); + Q_UNUSED(xmlObject); } -void OutgoingMessagesViewerModule::handleAck(const Message& ack) +void OutgoingMessagesViewerModule::setupUi() { - for (int i = 0; i < messages.count(); i++) + QHBoxLayout* outerLayout = new QHBoxLayout; + outerLayout->setContentsMargins(0, 0, 0, 0); + + table = new QTableWidget; + outerLayout->addWidget(table); + table->setColumnCount(2); + table->verticalHeader()->setVisible(false); + table->horizontalHeader()->setVisible(false); + table->horizontalHeader()->setSectionResizeMode( + 0, QHeaderView::ResizeToContents); + table->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch); + table->verticalScrollBar()->setVisible(false); + table->setSelectionMode(QAbstractItemView::NoSelection); + + setLayout(outerLayout); +} + +void OutgoingMessagesViewerModule::resizeEvent(QResizeEvent* event) +{ + if (table->rowCount() == 0) { - Message msg = messages[i].getMsg(); + return; + } - // Color the message the ack is for by checking the message id and - // sequence number - if (msg.getField("message_id") == ack.getField("recv_msgid")) - if (msg.getField("sequence_number") == ack.getField("seq_ack")) - messages[i].getItem()->setBackground(QBrush(QColor(0, 255, 0))); + int totalHeight = table->viewport()->height(); + int contentHeight = table->rowCount() * table->rowHeight(0); + + if (contentHeight <= totalHeight) + { + // Calculate how many rows can fit in the available space + int rowsToAdd = (totalHeight - contentHeight) / table->rowHeight(0); + + // Calculate how many messages are available and not shown + int rowsAvailable = messages.count() - table->rowCount(); + + // Add rows to fill the available space + for (int i = 0; i < std::min(rowsToAdd, rowsAvailable); i++) + { + addMessageToTable(messages.at(table->rowCount()), + table->rowCount()); + } + } + else + { + // Calculate how many rows need to be removed + int rowsToRemove = + (contentHeight - totalHeight) / table->rowHeight(0) + 1; + + // Remove rows that don't fit + int newRowCount = table->rowCount() - rowsToRemove; + table->setRowCount(newRowCount); } } -void OutgoingMessagesViewerModule::handleNack(const Message& nack) +void OutgoingMessagesViewerModule::handleMsg(const Message& msg) { - for (int i = 0; i < messages.count(); i++) - { - Message msg = messages[i].getMsg(); + // First register the message into the list + messages.prepend({QDateTime::currentDateTime(), msg}); - // Color the message the nack is for by checking the message id and - // sequence number - if (msg.getField("message_id") == nack.getField("recv_msgid")) - if (msg.getField("sequence_number") == nack.getField("seq_ack")) - messages[i].getItem()->setBackground(QBrush(QColor(255, 0, 0))); + // Check if the list is overgrowing + if (messages.count() > maxListSize) + { + messages.removeLast(); } + + // Insert the message into the table + addMessageToTable(messages.first()); + + // Update the table size + resizeEvent(); } -void OutgoingMessagesViewerModule::handleWack(const Message& wack) +void OutgoingMessagesViewerModule::handleAck(const Message& ack) { + // Color the message the ack is for with green background for (int i = 0; i < messages.count(); i++) { - Message msg = messages[i].getMsg(); - - // Color the message the wack is for by checking the message id and - // sequence number - if (msg.getField("message_id") == wack.getField("recv_msgid")) - if (msg.getField("sequence_number") == wack.getField("seq_ack")) - messages[i].getItem()->setBackground( - QBrush(QColor(255, 255, 255))); + Message msg = messages.at(i).second; + + if (msg.getField("message_id") == ack.getField("recv_msgid") && + msg.getField("sequence_number") == ack.getField("seq_ack")) + { + if (table->rowCount() > i) + { + table->item(i, 1)->setBackground(QBrush(QColor(0, 255, 0))); + } + } } } -int OutgoingMessagesViewerModule::updateVerticalHeaders(const Message& msg) +void OutgoingMessagesViewerModule::handleNack(const Message& nack) { - int row = 0; // Insert on top - QTime time(0, 0, 0, 0); - time = time.addMSecs(msg.getField("timestamp").getInteger()); - - QString headerTxt = time.toString("hh.mm.ss (zzz)"); - ui->tableWidget->insertRow(row); - QTableWidgetItem* header = new QTableWidgetItem(headerTxt); - ui->tableWidget->setVerticalHeaderItem(row, header); - - int rowCount = ui->tableWidget->rowCount(); - if (rowCount > maxSize && rowCount > 0) + // Color the message the nack is for with red background + for (int i = 0; i < messages.count(); i++) { - ui->tableWidget->removeRow(rowCount - 1); + Message msg = messages.at(i).second; + + if (msg.getField("message_id") == nack.getField("recv_msgid") && + msg.getField("sequence_number") == nack.getField("seq_ack")) + { + if (table->rowCount() > i) + { + table->item(i, 1)->setBackground(QBrush(QColor(255, 0, 0))); + } + } } - - return row; } -void OutgoingMessagesViewerModule::registerMessage(QTableWidgetItem* item, - const Message& msg) +void OutgoingMessagesViewerModule::handleWack(const Message& nack) { - messages.prepend(MessageLog(item, msg)); - if (messages.count() > maxSize) + // Color the message the wack is for with white background + for (int i = 0; i < messages.count(); i++) { - messages.removeLast(); + Message msg = messages.at(i).second; + + if (msg.getField("message_id") == nack.getField("recv_msgid") && + msg.getField("sequence_number") == nack.getField("seq_ack")) + { + if (table->rowCount() > i) + { + table->item(i, 1)->setBackground(QBrush(QColor(255, 255, 255))); + } + } } } -// ____________________ MESSAGE LOG CLASS _______________________________ - -MessageLog::MessageLog(QTableWidgetItem* item, const Message& msg) +void OutgoingMessagesViewerModule::addMessageToTable( + const QPair<QDateTime, Message>& msg, int row) { - setItem(item); - setMsg(msg); + // Prepare the row items + auto dateTxt = new QTableWidgetItem(msg.first.toString("hh.mm.ss")); + auto msgName = new QTableWidgetItem(msg.second.getField("name").toString()); + msgName->setBackground(QBrush(QColor(80, 80, 80))); + msgName->setForeground(QBrush(QColor(0, 0, 0))); + + // Add a new row + table->insertRow(row); + + // Fill the row with data + table->setItem(row, 0, dateTxt); + table->setItem(row, 1, msgName); } - -QTableWidgetItem* MessageLog::getItem() const { return item; } - -void MessageLog::setItem(QTableWidgetItem* value) { item = value; } - -Message MessageLog::getMsg() const { return msg; } - -void MessageLog::setMsg(const Message& value) { msg = value; } diff --git a/src/shared/Modules/OutgoingMessagesViewer/OutgoingMessagesViewerModule.h b/src/shared/Modules/OutgoingMessagesViewer/OutgoingMessagesViewerModule.h index 4fccc266820f00568f7f791a4b3989c3b96799c5..d8c5816070475c4607248f36f46a9e4c312e53c4 100644 --- a/src/shared/Modules/OutgoingMessagesViewer/OutgoingMessagesViewerModule.h +++ b/src/shared/Modules/OutgoingMessagesViewer/OutgoingMessagesViewerModule.h @@ -21,52 +21,37 @@ #include <Core/Message/Message.h> #include <Modules/Module.h> +#include <QDateTime> +#include <QList> +#include <QPair> #include <QWidget> -class QTableWidgetItem; - -class MessageLog +class OutgoingMessagesViewerModule : public DefaultModule { + Q_OBJECT public: - explicit MessageLog(QTableWidgetItem* item, const Message& msg); + explicit OutgoingMessagesViewerModule(QWidget* parent = nullptr); - QTableWidgetItem* getItem() const; - void setItem(QTableWidgetItem* value); + QWidget* toWidget() override; - Message getMsg() const; - void setMsg(const Message& value); + XmlObject toXmlObject() override; + void fromXmlObject(const XmlObject& xmlObject) override; private: - QTableWidgetItem* item = nullptr; - Message msg; -}; + void setupUi(); -namespace Ui -{ -class OutgoingMessagesViewerModule; -} + void resizeEvent(QResizeEvent* event = nullptr) override; -class OutgoingMessagesViewerModule : public Module -{ - Q_OBJECT - -public: - OutgoingMessagesViewerModule(); - ~OutgoingMessagesViewerModule(); - - void addMsgSent(const Message& msg); + void handleMsg(const Message& msg); void handleAck(const Message& ack); void handleNack(const Message& nack); void handleWack(const Message& wack); -protected: - int updateVerticalHeaders(const Message& msg); - void registerMessage(QTableWidgetItem* item, const Message& msg); - QString computeMsgName(const Message& msg); + void addMessageToTable(const QPair<QDateTime, Message>& msg, int row = 0); -private: - Ui::OutgoingMessagesViewerModule* ui; - QList<MessageLog> messages; - int maxSize = 10; + QTableWidget* table; + + QList<QPair<QDateTime, Message>> messages; + size_t maxListSize = 20; }; diff --git a/src/shared/Modules/OutgoingMessagesViewer/OutgoingMessagesViewerModule.ui b/src/shared/Modules/OutgoingMessagesViewer/OutgoingMessagesViewerModule.ui deleted file mode 100644 index 9394dc3916b37a0e6f4372161060463c127fcf72..0000000000000000000000000000000000000000 --- a/src/shared/Modules/OutgoingMessagesViewer/OutgoingMessagesViewerModule.ui +++ /dev/null @@ -1,49 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>OutgoingMessagesViewerModule</class> - <widget class="QWidget" name="OutgoingMessagesViewerModule"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>414</width> - <height>400</height> - </rect> - </property> - <property name="minimumSize"> - <size> - <width>150</width> - <height>400</height> - </size> - </property> - <property name="windowTitle"> - <string>Form</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QTableWidget" name="tableWidget"> - <property name="rowCount"> - <number>10</number> - </property> - <row /> - <row /> - <row /> - <row /> - <row /> - <row /> - <row /> - <row /> - <row /> - <row /> - <column> - <property name="text"> - <string>Message</string> - </property> - </column> - </widget> - </item> - </layout> - </widget> - <resources /> - <connections /> -</ui> \ No newline at end of file