312 lines
8.6 KiB
C++
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
|