Select Git revision
OutgoingMessagesViewerModule.cpp
OutgoingMessagesViewerModule.cpp 6.53 KiB
/*
* This file is part of Skyward Hub.
*
* Skyward Hub is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* Skyward Hub is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* Skyward Hub. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "OutgoingMessagesViewerModule.h"
#include <Core/MessageBroker/MessageBroker.h>
#include <Modules/SkywardHubStrings.h>
#include <QDebug>
#include <QTableWidgetItem>
OutgoingMessagesViewerModule::OutgoingMessagesViewerModule(QWidget* parent)
: DefaultModule(parent)
{
setupUi();
defaultContextMenuSetup();
// Subscribe to commands, ACKs and NACKs
getCore()->getMessageBroker()->subscribe(
Filter::fromString(SkywardHubStrings::logCommandsTopic), this,
[this](const Message& message, const Filter& filter)
{ handleMsg(message); });
getCore()->getMessageBroker()->subscribe(
Filter::fromString(SkywardHubStrings::mavlink_received_msg_ACK_topic),
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)
{ handleNack(message); });
MessageBroker::getInstance().subscribe(
Filter::fromString(SkywardHubStrings::mavlink_received_msg_WACK_topic),
this, [this](const Message& message, const Filter& filter)
{ handleWack(message); });
}
QWidget* OutgoingMessagesViewerModule::toWidget() { return this; }
XmlObject OutgoingMessagesViewerModule::toXmlObject()
{
return XmlObject(getName(ModuleId::OUTCOMINGMESSAGEVIEWER));
}
void OutgoingMessagesViewerModule::fromXmlObject(const XmlObject& xmlObject)
{
Q_UNUSED(xmlObject);
}
void OutgoingMessagesViewerModule::setupUi()
{
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)
{
return;
}
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::handleMsg(const Message& msg)
{
// First register the message into the list
messages.prepend({QDateTime::currentDateTime(), msg});
// 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::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.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)));
}
}
}
}
void OutgoingMessagesViewerModule::handleNack(const Message& nack)
{
// Color the message the nack is for with red background
for (int i = 0; i < messages.count(); i++)
{
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)));
}
}
}
}
void OutgoingMessagesViewerModule::handleWack(const Message& nack)
{
// Color the message the wack is for with white background
for (int i = 0; i < messages.count(); i++)
{
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)));
}
}
}
}
void OutgoingMessagesViewerModule::addMessageToTable(
const QPair<QDateTime, Message>& msg, int row)
{
// 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);
}