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

231 lines
7.4 KiB
C++

// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// manual class headers
#include "LogViewWidget.hpp"
#include "LogViewField.hpp"
#include "LogViewTelegram.hpp"
#include "LogViewXdrStandardType.hpp"
#include "IntegerCalculator.hpp"
#include <QMessageBox>
namespace N_LogView
{
// ---------------------------------------------------------------
LogViewWidget::LogViewWidget(LogViewField* a_field, QWidget* a_widget, QWidget* a_parent, bool a_readonly)
: m_Readonly(a_readonly)
, m_Valid(true)
, m_Widget(a_widget)
, m_Field(a_field)
, m_Parent(a_parent)
, m_logger(getLogger("LogViewWidget"))
{
}
// ---------------------------------------------------------------
uint16_t LogViewWidget::getSize() const
{
// todo: check whether really a standardtype
const LogViewXdrStandardType* xdrStandardType = static_cast<const LogViewXdrStandardType*>(m_Field->xdrElement());
return xdrStandardType->getValueSize();
}
// ---------------------------------------------------------------
void LogViewWidget::showMessageBox(const QString &a_errorText) const
{
QMessageBox::warning(m_Parent, QObject::tr("Fehler"), a_errorText);
}
// ---------------------------------------------------------------
void LogViewWidget::updateToolTip(const QString &a_text)
{
bool isList = m_Field->valueListSize() > 1 || m_Field->isDynamicArray();
switch (m_Field->xdrElement()->getKind())
{
case LogViewXdrElement::e_KindStandardType:
switch (static_cast<const LogViewXdrStandardType*>(m_Field->xdrElement())->getValueKind())
{
case LogViewXdrStandardType::e_Character:
m_Widget->setToolTip(QObject::tr("%1 Zeichen").arg(a_text.length()));
if (!m_Readonly)
m_Widget->setToolTip(QObject::tr("%1<br><nobr>Maximal %2 Zeichen erlaubt</nobr>").arg(m_Widget->toolTip()).arg(m_Field->maxArraySize()));
break;
case LogViewXdrStandardType::e_Data:
if (m_Readonly)
m_Widget->setToolTip(QObject::tr("%1 Bytes").arg(m_Field->valueListSize()));
break;
case LogViewXdrStandardType::e_Unsigned:
case LogViewXdrStandardType::e_Signed:
if (m_Readonly && isList)
{
m_Widget->setToolTip(QObject::tr("%1 Elemente").arg(m_Field->valueListSize()));
}
else
{
// fixme: bei 3-byte werten werden fälschlicherweise 4 Bytes angezeigt
if (m_Field->isDateTimeField())
{
m_Widget->setToolTip(QObject::tr("Unixzeit: %1 ").arg(a_text));
}
else
{
m_Widget->setToolTip(QString());
}
// actual value in hex and binary
if (!isList)
{
int64_t value = a_text.toLong();
m_Widget->setToolTip(QStringLiteral("%1<b>%2</b> %3").arg(m_Widget->toolTip(), toHex(value), toBin(value)));
}
// range
if (!m_Field->isDateTimeField() && !m_Readonly)
{
const QString sep(isList ? QString() : QStringLiteral("<br>"));
m_Widget->setToolTip(QStringLiteral("%1%2<nobr>Wertebereich: %3..%4</nobr>").arg(m_Widget->toolTip(), sep).arg(m_Field->getLowestValue()).arg(m_Field->getHighestValue()));
}
}
break;
case LogViewXdrStandardType::e_Float:
if (4 == m_Field->size())
m_Widget->setToolTip(QStringLiteral("<nobr>Wertebereich: +/-3.4e+/-38</nobr>"));
else
m_Widget->setToolTip(QStringLiteral("<nobr>Wertebereich: +/-1.7e+/-308</nobr>"));
break;
case LogViewXdrStandardType::e_Boolean:
m_Widget->setToolTip(QStringLiteral("true/false"));
}
break;
case LogViewXdrElement::e_KindEnum:
{
uint64_t enumValue = a_text.toLong();
m_Widget->setToolTip(QStringLiteral("<b>%1 %2</b> %3").arg(enumValue).arg(toHex(enumValue), toBin(enumValue)));
break;
}
default:
ERROR_LOG(m_logger) << "Case not implemented";
}
}
// ---------------------------------------------------------------
double LogViewWidget::getFloat(const QString& a_text, uint64_t& a_FloatAsData, bool& a_ok, const bool a_reverse)
{
// INFO_LOG(m_logger) << "a_text=" << a_text.toStdString();
//LogViewXdrStandardType::E_ByteOrder byteOrder = ((LogViewXdrStandardType*)m_Field->xdrElement())->getByteOrder();
double value;
if (8 == getSize())
{
value = a_text.toDouble(&a_ok);
a_FloatAsData = LogViewTelegram::doubleToXdr(value);
} else {
value = a_text.toFloat(&a_ok);
a_FloatAsData = LogViewTelegram::floatToXdr(value);
}
// show error-message
// fixme zeige fehler genauer
if (!a_ok)
showMessageBox(QStringLiteral("Inalid real value: '%1'").arg(a_text));
m_Valid = a_ok;
// swap for display data on table
if (a_reverse)
{
int j = getSize() - 1;
uint64_t* ptr = &a_FloatAsData;
for (int i = 0; i < getSize() / 2; i++)
{
uint8_t data = ((uint8_t*)ptr)[j];
((uint8_t*)&a_FloatAsData)[j] = ((uint8_t*)&a_FloatAsData)[i];
((uint8_t*)&a_FloatAsData)[i] = data;
j--;
}
}
// set the upper 4 bytes to 0 for float
if (4 == getSize())
{
((uint8_t*)&a_FloatAsData)[4] = 0;
((uint8_t*)&a_FloatAsData)[5] = 0;
((uint8_t*)&a_FloatAsData)[6] = 0;
((uint8_t*)&a_FloatAsData)[7] = 0;
}
return value;
}
// ---------------------------------------------------------------
// Converts a_text into a signed integer and returns it. The
// parameter a_ok will be true if all was successful. The
// attribute m_Valid will be set to a_ok.
// The range will be checked, if the value is out of range, an
// error will be shown as messge-box and a_ok will be false.
// The input a_text can be a calculation.
// ---------------------------------------------------------------
int64_t LogViewWidget::getInteger(const QString& a_text, bool& a_ok)
{
// calculate the expression into a number
N_SST::IntegerCalculator calculator;
N_SST::IntegerCalculator::E_Error error;
int64_t value = calculator.calc(a_text.toStdString(), error);
m_Valid = false;
a_ok = true;
if (N_SST::IntegerCalculator::e_Ok != error)
{
// todo: show exact error-message
if (a_text != m_LastErrorValueText)
{
showMessageBox(QString::fromUtf8("Die Berechnung '%1' ist falsch").arg(a_text));
m_LastErrorValueText = a_text;
}
a_ok = false;
}
else
{
// check the range
int64_t highest = m_Field->getHighestValue();
if (value > highest)
{
a_ok = false;
// fixme: dieser Trick mit m_LastErrorValueText ist für den Benutzer etwas verwirrend, da
// plötzlich keine Reaktion mehr auf Tab, Ok oder wählen eines anderen Feldes passiert...
if (a_text != m_LastErrorValueText)
{
showMessageBox(QString::fromUtf8("Der Wert '%1' ist zu hoch. Maximalwert: %2").arg(a_text).arg(highest));
m_LastErrorValueText = a_text;
}
return value; // abort
}
int64_t lowest = m_Field->getLowestValue();
if (value < lowest)
{
a_ok = false;
if (a_text != m_LastErrorValueText)
{
showMessageBox(QString::fromUtf8("Der Wert '%1' ist zu tief. Minimalwert: %2").arg(a_text).arg(lowest));
m_LastErrorValueText = a_text;
}
return value; // abort
}
m_Valid = true;
}
return value;
}
} // namespace N_LogView