Files
qt5-legatus-legacy/TetraIF/LogView/LogViewTableWidget.cpp
T
2026-08-13 18:33:10 +02:00

312 lines
8.6 KiB
C++

// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// manual class headers
#include "LogViewTableWidget.hpp"
#include "LogViewField.hpp"
#include <QHeaderView>
#include <QJsonArray>
#include "LogViewXdrStandardType.hpp"
#include "LogViewTelegram.hpp"
#include "LogViewEnumEdit.hpp"
namespace N_LogView
{
// ---------------------------------------------------------------
LogViewTableWidget::LogViewTableWidget(LogViewField* a_field, QWidget* a_parent, const bool a_readonly)
: QTableWidget(0, 2, a_parent)
, LogViewWidget(a_field, this, a_parent, a_readonly)
, m_IsFloat(false)
, m_IsEnum(false)
{
switch (m_Field->xdrElement()->getKind())
{
case LogViewXdrElement::e_KindEnum:
m_IsEnum = true;
break;
default:
m_IsFloat = LogViewXdrStandardType::e_Float == static_cast<const LogViewXdrStandardType*>(m_Field->xdrElement())->getValueKind();
}
if (!m_IsFloat)
setColumnCount(3);
if (m_IsEnum)
setColumnCount(1);
setHorizontalHeaderItem(0, new QTableWidgetItem(m_IsEnum ? tr("Enum") : tr("Dez")));
if (!m_IsEnum)
{
setHorizontalHeaderItem(1, new QTableWidgetItem(tr("Hex")));
if (!m_IsFloat)
{
setHorizontalHeaderItem(2, new QTableWidgetItem(tr("Bin")));
}
}
setAlternatingRowColors(true);
// make pretty
// horizontalHeader()->setResizeMode(2, QHeaderView::Stretch);
updateToolTip();
// for debugging only
// INFO_LOG(m_logger) << "type=" << static_cast<const LogViewXdrStandardType*>(a_field->getXdrElement())->getValueKind();
// INFO_LOG(m_logger) << "name=" << static_cast<const LogViewXdrStandardType*>(a_field->getXdrElement())->getName().toStdString();
// a_field->getXdrElement()->dump();
// fill in the values
// fixme: implementiere den Fall isHasContent() false
int nbrOfRows = a_field->valueListSize();
setRowCount(nbrOfRows);
for (int i = 0; i < nbrOfRows; i++)
changeRow(i, a_field->value(i));
makePretty();
// connect signals
connect(this, &LogViewTableWidget::itemChanged,
this, &LogViewTableWidget::checkAndOvertakeContent);
}
// ---------------------------------------------------------------
void LogViewTableWidget::changeSize(const int a_newSize)
{
setRowCount(a_newSize);
disconnect(this, &LogViewTableWidget::itemChanged,
this, &LogViewTableWidget::checkAndOvertakeContent);
// check and set the new fields
for (int i = 0; i < a_newSize; i++)
changeRow(i, QLatin1String("0"));
connect(this, &LogViewTableWidget::itemChanged,
this, &LogViewTableWidget::checkAndOvertakeContent);
makePretty();
m_Valid = true;
}
// ---------------------------------------------------------------
void LogViewTableWidget::changeRow(const int a_rowIndex, const QString& a_value)
{
// INFO_LOG(m_logger) << "a_rowIndex=" << a_rowIndex << " a_value=" << a_value.toStdString();
if (m_IsEnum)
{
// enum
QWidget* enumItem = cellWidget(a_rowIndex, 0);
if (!enumItem)
setCellWidget(a_rowIndex, 0, new LogViewEnumEdit(m_Field, this, m_Readonly, a_rowIndex));
}
else
{
QFont font;
font.setStyleHint(QFont::TypeWriter);
font.setFamily(QString());
// decimal
QTableWidgetItem* decItem = item(a_rowIndex, 0);
if (!decItem)
{
decItem = new QTableWidgetItem();
//decItem->setData(Qt::DisplayRole, 0);
decItem->setText(a_value);
decItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
if (!m_Readonly)
{
decItem->setFlags(decItem->flags() | Qt::ItemIsEditable);
}
decItem->setFont(font);
decItem->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
setItem(a_rowIndex, 0, decItem);
}
// hexadecimal
QTableWidgetItem* hexItem = item(a_rowIndex, 1);
if (!hexItem)
{
hexItem = new QTableWidgetItem();
hexItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
hexItem->setFont(font);
hexItem->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
setItem(a_rowIndex, 1, hexItem);
}
// binary
if (!m_IsFloat)
{
QTableWidgetItem* binItem = item(a_rowIndex, 2);
if (!binItem)
{
binItem = new QTableWidgetItem();
binItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
binItem->setFont(font);
binItem->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
setItem(a_rowIndex, 2, binItem);
}
}
// set the values
checkAndOvertakeContent(decItem);
makePretty();
}
}
// ---------------------------------------------------------------
void LogViewTableWidget::checkAndOvertakeContent(QTableWidgetItem* a_changedItem)
{
if (a_changedItem->column() != 0) return;
int row = a_changedItem->row();
QString text = a_changedItem->text();
bool ok;
int64_t intValue = 0;
double floatValue = 0.0;
// get the calculated and checked value
if (m_IsFloat)
floatValue = getFloat(text, (uint64_t&)intValue, ok, true);
else
intValue = getInteger(text, ok);
// handle errors
if (!ok)
{
setFocus();
// selectAll();
setCurrentCell(row, 0); // todo: funktioniert nicht
return;
}
// set the decimal value
QTableWidgetItem* decField = item(row, 0);
if (decField) decField->setText(QString::number(m_IsFloat ? floatValue : intValue));
// set the hex value
QTableWidgetItem* hexField = item(row, 1);
if (hexField) hexField->setText(toHex(intValue));
// set the binary value
if (!m_IsFloat)
{
QTableWidgetItem* binField = item(row, 2);
if (binField) binField->setText(toBin(intValue));
}
}
// ---------------------------------------------------------------
void LogViewTableWidget::makePretty()
{
//horizontalHeader()->setResizeMode(2, QHeaderView::Stretch);
resizeColumnsToContents();
resizeRowsToContents();
// set the height of table-widget
//// QWidget* cellWdg = tableWidget->cellWidget(0, 0);
// int showRows = 7;
// if (m_Field->getValueListSize() < (showRows-1))
// {
// showRows = m_Field->getValueListSize()+1;
// setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
// }
// else
// {
// setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
// }
// setFixedHeight(showRows*tableWidget->rowHeight(0));
}
// ---------------------------------------------------------------
// Writes the content into telegram.
// Returns true if successful.
// ---------------------------------------------------------------
bool LogViewTableWidget::saveContent(LogViewTelegram* a_telegram)
{
if (!isValid())
return false;
if (a_telegram->isJsonTelegram())
{
if (m_Field->kind() == LogViewField::e_FieldKindPodArray)
{
QJsonArray arr;
for (int i = 0; i < rowCount(); ++i)
arr += item(i, 0)->text().toInt();
a_telegram->setJsonValue(m_Field->jsonPath(), arr);
}
else
{
QString value;
value.reserve(rowCount() * 2);
for (int i = 0; i < rowCount(); ++i)
{
int val = item(i, 0)->text().toInt();
value += QStringLiteral("%1").arg(val, 2, 16, QLatin1Char('0'));
}
a_telegram->setJsonValue(m_Field->jsonPath(), value);
}
return true;
}
uint16_t arraySize;
if (m_Field->isDynamicArray())
{
arraySize = rowCount();
a_telegram->setUIntX(LogViewTelegram::SIZE_CENTRAL_DYN_ARRAY_SIZE, arraySize);
// fixme: bei vielen Telegrammen muss Länge auf die Länge des Textes gesetzt werden. Dies kann nicht automatisch gemacht werden. Aber vielleicht kann man schauen, ob vor dem dyn. Array ein Feld Länge vorkommt, oder hartcodieren, oder konfigurierbaren
}
else
{
// todo: teste mit opaque[]
arraySize = m_Field->maxArraySize();
}
// copy the data
INFO_LOG(m_logger) << "arraySize=" << arraySize;
for (int i = 0; i < arraySize; i++)
{
if (m_IsEnum)
{
LogViewEnumEdit *enumEdit = dynamic_cast<LogViewEnumEdit*>(cellWidget(i,0));
enumEdit->saveContent(a_telegram);
}
else
{
uint16_t size = getSize();
QString text = item(i, 0)->text();
if (!m_IsFloat)
{
a_telegram->setUIntX(size, text.toULong());
}
else
{
const LogViewXdrStandardType *stdType = static_cast<const LogViewXdrStandardType*>(m_Field->xdrElement());
LogViewXdrStandardType::E_ByteOrder byteOrder = stdType->getByteOrder();
uint64_t hex;
getFloat(text, hex, m_Valid);
a_telegram->setUIntX(size, hex, byteOrder);
}
}
}
return true;
}
} // namespace N_LogView