[DBC]Add support for multiple signal multiplexor values

This commit is contained in:
Miklos Marton
2024-01-18 16:42:38 +01:00
parent 101e42d0ec
commit 1dce603325
7 changed files with 205 additions and 128 deletions
+112 -22
View File
@@ -12,23 +12,12 @@ DBC_MESSAGE::DBC_MESSAGE()
sender = nullptr;
}
DBC_SIGNAL::DBC_SIGNAL()
void DBC_SIGNAL::addMultiplexRange(int min, int max)
{
bias = 0;
isMultiplexed = false;
isMultiplexor = false;
max = 1;
min = 0;
multiplexLowValue = 0;
multiplexHighValue = 0;
factor = 1.0;
intelByteOrder = false;
parentMessage = nullptr;
multiplexParent = nullptr;
receiver = nullptr;
signalSize = 1;
startBit = 1;
valType = DBC_SIG_VAL_TYPE::UNSIGNED_INT;
if (min != max)
hasExtendedMultiplexing = true;
isMultiplexed = true;
multiplexLowAndHighValues.append(QPair<int, int>(min, max));
}
bool DBC_SIGNAL::isSignalInMessage(const CANFrame &frame)
@@ -42,11 +31,7 @@ bool DBC_SIGNAL::isSignalInMessage(const CANFrame &frame)
{
int val;
if (!multiplexParent->processAsInt(frame, val)) return false;
if ((val >= multiplexLowValue) && (val <= multiplexHighValue))
{
return true;
}
else return false;
return isValueMatchingMultiplex(val);
}
else return false;
}
@@ -55,6 +40,111 @@ bool DBC_SIGNAL::isSignalInMessage(const CANFrame &frame)
else return true; //if signal isn't multiplexed then it's definitely in the message
}
bool DBC_SIGNAL::isValueMatchingMultiplex(int val) const
{
for (auto limitPair : multiplexLowAndHighValues) {
if ((limitPair.first <= val) && (val <= limitPair.second))
return true;
}
return false;
}
QString DBC_SIGNAL::multiplexDbcString(DbcMuxStringFormat fmt) const
{
QString ret;
for (auto limitPair : multiplexLowAndHighValues) {
if (fmt == MuxStringFormat_DbcFile) {
if (!ret.isEmpty())
ret.append(QStringLiteral(" "));
ret.append(QString("%1-%2").arg(limitPair.first).arg(limitPair.second));
} else {
if (!ret.isEmpty())
ret.append(QStringLiteral(";"));
ret.append(QString::number(limitPair.first));
if (limitPair.first != limitPair.second)
ret.append(QString("-%1").arg(limitPair.second));
}
}
return ret;
}
void DBC_SIGNAL::copyMultiplexValuesFromSignal(const DBC_SIGNAL &signal)
{
isMultiplexed = signal.isMultiplexed;
for (auto multiplexSignalPair : signal.multiplexLowAndHighValues) {
multiplexLowAndHighValues.append(multiplexSignalPair);
}
}
/**
* @brief DBC_SIGNAL::parseDbcMultiplexUiString
* Method for parsing the Vector CANDB++ like multiplex definitions:
*
* Single values has to be separated by semicolons
* and the value ranges by hypens
* (e.g.: 1;2;5-7)
* @param multiplexes in the format from the UI
* @param errorString output parameter to pass the failure text if parsing failed
* @return true if the multiplexes parameter could be parsed properly
*/
bool DBC_SIGNAL::parseDbcMultiplexUiString(const QString &multiplexes, QString &errorString)
{
QList<QPair<int, int>> multiplexLowAndHighValuesTemp;
const auto muxes = multiplexes.split(QChar(';'), Qt::SkipEmptyParts);
for (const auto &mux : muxes) {
bool ok = false;
if (mux.contains(QChar('-'))) {
const auto minMax = mux.split(QChar('-'));
if (minMax.count() != 2) {
errorString = QObject::tr("The %1 part contains more than one '-' sign").arg(mux);
return false;
}
int min = minMax.at(0).toInt(&ok);
if (!ok) {
errorString = QObject::tr("Unable to parse the %1 part to integer").arg(minMax.at(0));
return false;
}
int max = minMax.at(1).toInt(&ok);
if (!ok) {
errorString = QObject::tr("Unable to parse the %1 part to integer").arg(minMax.at(1));
return false;
}
multiplexLowAndHighValuesTemp.append(QPair<int, int>(min, max));
} else {
int value = mux.toInt(&ok);
if (!ok) {
errorString = QObject::tr("Unable to parse the %1 part to integer").arg(mux);
return false;
}
multiplexLowAndHighValuesTemp.append(QPair<int, int>(value, value));
}
}
multiplexLowAndHighValues.clear();
multiplexLowAndHighValues = multiplexLowAndHighValuesTemp;
return true;
}
bool DBC_SIGNAL::multiplexesIdenticalToSignal(DBC_SIGNAL *other) const
{
auto othersMuxes = other->multiplexLowAndHighValues;
for (auto myMux : multiplexLowAndHighValues) {
bool found = false;
for (auto otherMux : othersMuxes) {
if (myMux == otherMux) {
othersMuxes.removeAll(myMux);
found = true;
break;
}
}
if (!found)
return false;
}
return othersMuxes.isEmpty();
}
//Take all the children of this signal and see if they exist in the message. Can be called recursively to descend the dependency tree
QString DBC_SIGNAL::processSignalTree(const CANFrame &frame)
{
@@ -69,7 +159,7 @@ QString DBC_SIGNAL::processSignalTree(const CANFrame &frame)
foreach (DBC_SIGNAL *sig, multiplexedChildren)
{
if ( (val >= sig->multiplexLowValue) && (val <= sig->multiplexHighValue) )
if (sig->isValueMatchingMultiplex(val))
{
qDebug() << "Found match for multiplex value range - " << sig->name;
QString sigString;
+34 -17
View File
@@ -89,31 +89,44 @@ class DBC_SIGNAL;
class DBC_SIGNAL
{
public: //TODO: this is sloppy. It shouldn't all be public!
DBC_SIGNAL() = default;
enum DbcMuxStringFormat {
MuxStringFormat_DbcFile,
MuxStringFormat_UI
};
QString name;
int startBit;
int signalSize;
bool intelByteOrder; //true is obviously little endian. False is big endian
bool isMultiplexor;
bool isMultiplexed;
int multiplexHighValue;
int multiplexLowValue;
DBC_SIG_VAL_TYPE valType;
double factor;
double bias;
double min;
double max;
DBC_NODE *receiver; //it is fast to have a pointer but dangerous... Make sure to walk the whole tree and delete everything so nobody has stale references.
DBC_MESSAGE *parentMessage;
int startBit = 1;
int signalSize = 1;
bool intelByteOrder = false; //true is obviously little endian. False is big endian
bool isMultiplexor = false;
bool isMultiplexed = false;
void addMultiplexRange(int min, int max);
int multiplexHighValue = 0;
int multiplexLowValue = 0;
bool hasExtendedMultiplexing = false;
QList<DBC_SIGNAL *> multiplexedChildren;
DBC_SIGNAL *multiplexParent = nullptr;
QString multiplexDbcString(DbcMuxStringFormat fmt = MuxStringFormat_DbcFile) const;
void copyMultiplexValuesFromSignal(const DBC_SIGNAL &signal);
bool parseDbcMultiplexUiString(const QString &multiplexes, QString &errorString);
bool multiplexesIdenticalToSignal(DBC_SIGNAL *other) const;
DBC_SIG_VAL_TYPE valType = DBC_SIG_VAL_TYPE::UNSIGNED_INT;
double factor = 1.0;
double bias = 0;
double min = 0;
double max = 1;
DBC_NODE *receiver = nullptr; //it is fast to have a pointer but dangerous... Make sure to walk the whole tree and delete everything so nobody has stale references.
DBC_MESSAGE *parentMessage = nullptr;
QString unitName;
QString comment;
QVariant cachedValue;
QList<DBC_ATTRIBUTE_VALUE> attributes;
QList<DBC_VAL_ENUM_ENTRY> valList;
QList<DBC_SIGNAL *> multiplexedChildren;
DBC_SIGNAL *multiplexParent;
DBC_SIGNAL *self;
DBC_SIGNAL();
bool processAsText(const CANFrame &frame, QString &outString, bool outputName = true, bool outputUnit = true);
bool processAsInt(const CANFrame &frame, int32_t &outValue);
bool processAsDouble(const CANFrame &frame, double &outValue);
@@ -123,11 +136,15 @@ public: //TODO: this is sloppy. It shouldn't all be public!
DBC_ATTRIBUTE_VALUE *findAttrValByName(QString name);
DBC_ATTRIBUTE_VALUE *findAttrValByIdx(int idx);
bool isSignalInMessage(const CANFrame &frame);
bool isValueMatchingMultiplex(int val) const;
friend bool operator<(const DBC_SIGNAL& l, const DBC_SIGNAL& r)
{
return (l.name.toLower() < r.name.toLower());
}
private:
QList<QPair<int, int>> multiplexLowAndHighValues;
};
class DBCSignalHandler; //forward declaration to keep from having to include dbchandler.h in this file and thus create a loop
+20 -27
View File
@@ -507,11 +507,6 @@ DBC_SIGNAL* DBCFile::parseSignalLine(QString line, DBC_MESSAGE *msg)
//bool isMultiplexed = false;
DBC_SIGNAL sig;
sig.multiplexLowValue = 0;
sig.multiplexHighValue = 0;
sig.isMultiplexed = false;
sig.isMultiplexor = false;
qDebug() << "Found a SG line";
regex.setPattern("^SG\\_ *([-\\w]+) +M *: *(\\d+)\\|(\\d+)@(\\d+)([\\+|\\-]) \\(([0-9.+\\-eE]+),([0-9.+\\-eE]+)\\) \\[([0-9.+\\-eE]+)\\|([0-9.+\\-eE]+)\\] \\\"(.*)\\\" (.*)");
@@ -529,10 +524,7 @@ DBC_SIGNAL* DBCFile::parseSignalLine(QString line, DBC_MESSAGE *msg)
if (match.hasMatch())
{
qDebug() << "Multiplexed signal";
//isMultiplexed = true;
sig.isMultiplexed = true;
sig.multiplexLowValue = match.captured(2).toInt();
sig.multiplexHighValue = sig.multiplexLowValue;
sig.addMultiplexRange(match.captured(2).toInt(), match.captured(2).toInt());
offset = 1;
}
else
@@ -543,9 +535,7 @@ DBC_SIGNAL* DBCFile::parseSignalLine(QString line, DBC_MESSAGE *msg)
{
qDebug() << "Extended Multiplexor Signal";
sig.isMultiplexor = true; //we don't set the local isMessageMultiplexor variable because this isn't the top level multiplexor
sig.isMultiplexed = true; //but, it is both a multiplexor and multiplexed
sig.multiplexLowValue = match.captured(2).toInt();
sig.multiplexHighValue = sig.multiplexLowValue;
sig.addMultiplexRange(match.captured(2).toInt(), match.captured(2).toInt());
offset = 1;
}
else
@@ -643,7 +633,7 @@ bool DBCFile::parseSignalMultiplexValueLine(QString line)
QRegularExpressionMatch match;
qDebug() << "Found a multiplex definition line";
regex.setPattern("^SG\\_MUL\\_VAL\\_ (\\d+) ([-\\w]+) ([-\\w]+) (\\d+)\\-(\\d+);");
regex.setPattern("^SG\\_MUL\\_VAL\\_ (\\d+) ([-\\w]+) ([-\\w]+) ((?:\\d+\\-\\d+[\\s]*[\\,]?[\\s]*)*)");
match = regex.match(line);
//captured 1 is message ID
//Captured 2 is signal name
@@ -661,11 +651,21 @@ bool DBCFile::parseSignalMultiplexValueLine(QString line)
DBC_SIGNAL *parentSignal = msg->sigHandler->findSignalByName(match.captured(3));
if (parentSignal != nullptr)
{
//now need to add "thisSignal" to the children multiplexed signals of "parentSignal"
const QStringList ranges = match.captured(4).split(QChar(','), Qt::SkipEmptyParts);
for (const QString &range : ranges) {
//now need to add "thisSignal" to the children multiplexed signals of "parentSignal"
const QStringList rangeSides = range.trimmed().split(QChar('-'));
if (rangeSides.count() != 2) {
qDebug() << QString("Malformed range definition: '%2' found in the multiplexed signal: %1")
.arg(match.captured(1).arg(range.trimmed()));
return false;
}
int rangeMin = rangeSides.at(0).toInt();
int rangeMax = rangeSides.at(1).toInt();
thisSignal->multiplexParent = parentSignal;
thisSignal->addMultiplexRange(rangeMin, rangeMax);
}
parentSignal->multiplexedChildren.append(thisSignal);
thisSignal->multiplexParent = parentSignal;
thisSignal->multiplexLowValue = match.captured(4).toInt();
thisSignal->multiplexHighValue = match.captured(5).toInt();
return true;
}
}
@@ -1458,7 +1458,7 @@ bool DBCFile::saveFile(QString fileName)
}
//check for the two telltale signs that we've got extended multiplexing going on.
if (sig->isMultiplexed && sig->isMultiplexor) hasExtendedMultiplexing = true;
if (sig->multiplexLowValue != sig->multiplexHighValue) hasExtendedMultiplexing = true;
if (sig->hasExtendedMultiplexing) hasExtendedMultiplexing = true;
msgOutput.append(" : " + QString::number(sig->startBit) + "|" + QString::number(sig->signalSize) + "@");
@@ -1625,7 +1625,7 @@ bool DBCFile::saveFile(QString fileName)
{
msgOutput.append("SG_MUL_VAL_ " + QString::number(ID) + " ");
msgOutput.append(sig->name + " " + sig->multiplexParent->name + " ");
msgOutput.append(QString::number(sig->multiplexLowValue) + "-" + QString::number(sig->multiplexHighValue) + ";");
msgOutput.append(sig->multiplexDbcString() + ";");
msgOutput.append("\n");
extMultiplexOutput.append(msgOutput);
msgOutput.clear(); //got to reset it after writing
@@ -2042,14 +2042,7 @@ DBCFile* DBCHandler::loadJSONFile(QString filename)
if (!sigObj.find("mux_id")->isUndefined())
{
QJsonValue muxVal = sigObj.find("mux_id").value();
sig.multiplexLowValue = muxVal.toInt();
sig.multiplexHighValue = sig.multiplexLowValue;
sig.isMultiplexed = true;
}
else
{
sig.multiplexLowValue = 0;
sig.multiplexHighValue = 0;
sig.addMultiplexRange(muxVal.toInt(), muxVal.toInt());
}
QJsonValue muxerVal = sigObj.find("is_muxer").value();
if (!muxerVal.isNull())
+2 -5
View File
@@ -442,9 +442,7 @@ QString DBCMainEditor::createSignalText(DBC_SIGNAL *sig)
QString sigInfo;
if (sig->isMultiplexed)
{
sigInfo = "(" + QString::number(sig->multiplexLowValue);
if (sig->multiplexHighValue != sig->multiplexLowValue) sigInfo += "-" + QString::number(sig->multiplexHighValue);
sigInfo += ") ";
sigInfo = "(" + sig->multiplexDbcString() + ") ";
}
sigInfo.append(sig->name);
@@ -624,8 +622,7 @@ void DBCMainEditor::copyMessageToNode(DBC_NODE *parentNode, DBC_MESSAGE *source,
sig.isMultiplexor = false; //sigSource->isMultiplexor;
sig.max = sigSource->max;
sig.min = sigSource->min;
sig.multiplexLowValue = sigSource->multiplexLowValue;
sig.multiplexHighValue = sigSource->multiplexHighValue;
sig.copyMultiplexValuesFromSignal(*sigSource);
sig.factor = sigSource->factor;
sig.intelByteOrder = sigSource->intelByteOrder;
sig.parentMessage = &msg;
+19 -38
View File
@@ -5,6 +5,7 @@
#include <QMenu>
#include <QSettings>
#include <QRandomGenerator>
#include <QMessageBox>
#include <qevent.h>
#include "helpwindow.h"
@@ -281,33 +282,21 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
}
});
connect(ui->txtMultiplexLow, &QLineEdit::editingFinished,
connect(ui->txtMultiplexValues, &QLineEdit::editingFinished,
[=]()
{
if (currentSignal == nullptr) return;
int temp;
temp = Utility::ParseStringToNum(ui->txtMultiplexLow->text());
if (currentSignal->multiplexLowValue != temp)
if (currentSignal->multiplexDbcString(DBC_SIGNAL::MuxStringFormat_UI) != ui->txtMultiplexValues->text())
{
pushToUndoBuffer();
dbcFile->setDirtyFlag();
//TODO: could look up the multiplexor and ensure that the value is within a range that the multiplexor could return
currentSignal->multiplexLowValue = temp;
}
});
connect(ui->txtMultiplexHigh, &QLineEdit::editingFinished,
[=]()
{
if (!currentSignal) return;
int temp;
temp = Utility::ParseStringToNum(ui->txtMultiplexHigh->text());
if (currentSignal->multiplexHighValue != temp)
{
pushToUndoBuffer();
dbcFile->setDirtyFlag();
//TODO: could look up the multiplexor and ensure that the value is within a range that the multiplexor could return
currentSignal->multiplexHighValue = temp;
QString errorString;
if (!currentSignal->parseDbcMultiplexUiString(ui->txtMultiplexValues->text(), errorString)) {
QMessageBox::critical(this, tr("Error"), tr("The multiplex values field contains errors:\n%1").arg(errorString));
} else {
pushToUndoBuffer();
dbcFile->setDirtyFlag();
}
}
});
@@ -326,8 +315,7 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
currentSignal->isMultiplexor = true;
//an extended multi signal cannot be the root multiplexor for a message so make sure to remove it if it was.
if (dbcMessage->multiplexorSignal == currentSignal) dbcMessage->multiplexorSignal = nullptr;
ui->txtMultiplexLow->setEnabled(currentSignal->isMultiplexed);
ui->txtMultiplexHigh->setEnabled(currentSignal->isMultiplexed);
ui->txtMultiplexValues->setEnabled(currentSignal->isMultiplexed);
ui->cbMultiplexParent->setEnabled(currentSignal->isMultiplexed);
fillSignalForm(currentSignal);
}
@@ -348,8 +336,7 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
currentSignal->isMultiplexor = false;
//if the set multiplexor for the message was this signal then clear it
if (dbcMessage->multiplexorSignal == currentSignal) dbcMessage->multiplexorSignal = nullptr;
ui->txtMultiplexLow->setEnabled(currentSignal->isMultiplexed);
ui->txtMultiplexHigh->setEnabled(currentSignal->isMultiplexed);
ui->txtMultiplexValues->setEnabled(currentSignal->isMultiplexed);
ui->cbMultiplexParent->setEnabled(currentSignal->isMultiplexed);
fillSignalForm(currentSignal);
}
@@ -369,8 +356,7 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
currentSignal->isMultiplexor = true;
//we just set that this is the multiplexor so update the message to show that as well.
dbcMessage->multiplexorSignal = currentSignal;
ui->txtMultiplexLow->setEnabled(currentSignal->isMultiplexed);
ui->txtMultiplexHigh->setEnabled(currentSignal->isMultiplexed);
ui->txtMultiplexValues->setEnabled(currentSignal->isMultiplexed);
ui->cbMultiplexParent->setEnabled(currentSignal->isMultiplexed);
fillSignalForm(currentSignal);
}
@@ -389,8 +375,7 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
currentSignal->isMultiplexed = false;
currentSignal->isMultiplexor = false;
if (dbcMessage->multiplexorSignal == currentSignal) dbcMessage->multiplexorSignal = nullptr;
ui->txtMultiplexLow->setEnabled(currentSignal->isMultiplexed);
ui->txtMultiplexHigh->setEnabled(currentSignal->isMultiplexed);
ui->txtMultiplexValues->setEnabled(currentSignal->isMultiplexed);
ui->cbMultiplexParent->setEnabled(currentSignal->isMultiplexed);
fillSignalForm(currentSignal);
}
@@ -587,8 +572,7 @@ void DBCSignalEditor::fillSignalForm(DBC_SIGNAL *sig)
ui->txtMinVal->setText("");
ui->txtScale->setText("");
ui->txtUnitName->setText("");
ui->txtMultiplexLow->setText("");
ui->txtMultiplexHigh->setText("");
ui->txtMultiplexValues->setText("");
ui->rbMultiplexed->setChecked(false);
ui->rbMultiplexor->setChecked(false);
ui->rbNotMulti->setChecked(true);
@@ -604,8 +588,7 @@ void DBCSignalEditor::fillSignalForm(DBC_SIGNAL *sig)
ui->txtName->setText(sig->name);
ui->txtBias->setText(QString::number(sig->bias));
ui->txtBitLength->setText(QString::number(sig->signalSize));
ui->txtMultiplexLow->setText(QString::number(sig->multiplexLowValue));
ui->txtMultiplexHigh->setText(QString::number(sig->multiplexHighValue));
ui->txtMultiplexValues->setText(sig->multiplexDbcString(DBC_SIGNAL::MuxStringFormat_UI));
ui->txtComment->setText(sig->comment);
ui->txtMaxVal->setText(QString::number(sig->max));
ui->txtMinVal->setText(QString::number(sig->min));
@@ -641,8 +624,7 @@ void DBCSignalEditor::fillSignalForm(DBC_SIGNAL *sig)
}
}
ui->txtMultiplexLow->setEnabled(sig->isMultiplexed);
ui->txtMultiplexHigh->setEnabled(sig->isMultiplexed);
ui->txtMultiplexValues->setEnabled(sig->isMultiplexed);
ui->cbMultiplexParent->setEnabled(sig->isMultiplexed);
ui->cbIntelFormat->setChecked(sig->intelByteOrder);
@@ -693,7 +675,7 @@ void DBCSignalEditor::refreshBitGrid()
{
DBC_SIGNAL *sig = dbcMessage->sigHandler->findSignalByIdx(x);
//only set a signal name for signals which match multiplexparent with our currentsignal
if (!sig->multiplexParent || ((sig->multiplexParent == currentSignal->multiplexParent) && (sig->multiplexHighValue == currentSignal->multiplexHighValue)) )
if (!sig->multiplexParent || ((sig->multiplexParent == currentSignal->multiplexParent) && (sig->multiplexesIdenticalToSignal(currentSignal)) ))
{
ui->bitfield->setSignalNames(x, sig->name);
//qDebug() << sig->name << sig->multiplexParent;
@@ -845,8 +827,7 @@ void DBCSignalEditor::generateUsedBits()
if (sig->multiplexParent)
{
if (sig->multiplexParent != currentSignal->multiplexParent) continue; //go thee away!
if (sig->multiplexHighValue != currentSignal->multiplexHighValue) continue; //buzz off
if (sig->multiplexLowValue != currentSignal->multiplexLowValue) continue;
if (!sig->multiplexesIdenticalToSignal(currentSignal)) continue; //buzz off
}
startBit = sig->startBit;
+17 -19
View File
@@ -188,12 +188,22 @@
<item row="10" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Multiplex Low Value</string>
<string>Multiplex value</string>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QLineEdit" name="txtMultiplexLow"/>
<widget class="QLineEdit" name="txtMultiplexValues"/>
</item>
<item row="12" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Multiplex Parent</string>
</property>
</widget>
</item>
<item row="12" column="1">
<widget class="QComboBox" name="cbMultiplexParent"/>
</item>
<item row="13" column="0">
<widget class="QLabel" name="label_13">
@@ -205,23 +215,12 @@
<item row="13" column="1">
<widget class="QLineEdit" name="txtComment"/>
</item>
<item row="12" column="1">
<widget class="QComboBox" name="cbMultiplexParent"/>
</item>
<item row="12" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Multiplex Parent</string>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QLineEdit" name="txtMultiplexHigh"/>
</item>
<item row="11" column="0">
<widget class="QLabel" name="label_17">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Multiplex High Value</string>
<string>Single values has to be separated by semicolons
and the value ranges by hypens
(e.g.: 1;2;5-7)</string>
</property>
</widget>
</item>
@@ -263,8 +262,7 @@
<tabstop>rbMultiplexed</tabstop>
<tabstop>rbMultiplexor</tabstop>
<tabstop>rbExtended</tabstop>
<tabstop>txtMultiplexLow</tabstop>
<tabstop>txtMultiplexHigh</tabstop>
<tabstop>txtMultiplexValues</tabstop>
<tabstop>cbMultiplexParent</tabstop>
<tabstop>txtComment</tabstop>
<tabstop>valuesTable</tabstop>
+1
View File
@@ -190,6 +190,7 @@ public:
return (double)timestamp / 1000000.0;
break;
}
return QVariant();
}
//parses the input string to grab as much of it as possible while staying alpha numeric