First pass implementing support for extended multiplexing.
This causes significant changes to the DBC interface. Things are probably a bit broken right now. Committing to get it on record before further large changes are done.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
#ifndef CONFIG
|
||||
#define CONFIG
|
||||
|
||||
#define VERSION 202
|
||||
#define VERSION 203
|
||||
|
||||
//try to keep this in sync.
|
||||
//SavvyCAN will complain if you connect a GVRET board with a revision
|
||||
|
||||
@@ -23,12 +23,19 @@ DBC_SIGNAL::DBC_SIGNAL()
|
||||
factor = 1.0;
|
||||
intelByteOrder = false;
|
||||
parentMessage = nullptr;
|
||||
multiplexParent = nullptr;
|
||||
receiver = nullptr;
|
||||
signalSize = 1;
|
||||
startBit = 1;
|
||||
valType = DBC_SIG_VAL_TYPE::UNSIGNED_INT;
|
||||
}
|
||||
|
||||
DBC_MULTIPLEX::DBC_MULTIPLEX()
|
||||
{
|
||||
lowerBound = 0;
|
||||
upperBound = 0;
|
||||
sig = nullptr;
|
||||
}
|
||||
|
||||
/*
|
||||
The way that the DBC file format works is kind of weird... For intel format signals you count up
|
||||
|
||||
+21
-8
@@ -26,18 +26,19 @@ enum DBC_SIG_VAL_TYPE
|
||||
|
||||
enum DBC_ATTRIBUTE_VAL_TYPE
|
||||
{
|
||||
QINT,
|
||||
QFLOAT,
|
||||
QSTRING,
|
||||
ENUM
|
||||
ATTR_INT,
|
||||
ATTR_FLOAT,
|
||||
ATTR_STRING,
|
||||
ATTR_ENUM,
|
||||
};
|
||||
|
||||
enum DBC_ATTRIBUTE_TYPE
|
||||
{
|
||||
GENERAL,
|
||||
NODE,
|
||||
MESSAGE,
|
||||
SIG
|
||||
ATTR_TYPE_GENERAL,
|
||||
ATTR_TYPE_NODE,
|
||||
ATTR_TYPE_MESSAGE,
|
||||
ATTR_TYPE_SIG,
|
||||
ATTR_TYPE_ANY
|
||||
};
|
||||
|
||||
class DBC_ATTRIBUTE
|
||||
@@ -82,6 +83,16 @@ public:
|
||||
};
|
||||
|
||||
class DBC_MESSAGE; //forward reference so that DBC_SIGNAL can compile before we get to real definition of DBC_MESSAGE
|
||||
class DBC_SIGNAL;
|
||||
|
||||
class DBC_MULTIPLEX
|
||||
{
|
||||
public:
|
||||
int lowerBound, upperBound;
|
||||
DBC_SIGNAL *sig;
|
||||
|
||||
DBC_MULTIPLEX();
|
||||
};
|
||||
|
||||
class DBC_SIGNAL
|
||||
{
|
||||
@@ -105,6 +116,8 @@ public: //TODO: this is sloppy. It shouldn't all be public!
|
||||
QVariant cachedValue;
|
||||
QList<DBC_ATTRIBUTE_VALUE> attributes;
|
||||
QList<DBC_VAL_ENUM_ENTRY> valList;
|
||||
QList<DBC_MULTIPLEX> multiplexedChildren;
|
||||
DBC_SIGNAL *multiplexParent;
|
||||
|
||||
DBC_SIGNAL();
|
||||
bool processAsText(const CANFrame &frame, QString &outString, bool outputName = true);
|
||||
|
||||
+145
-57
@@ -373,12 +373,12 @@ void DBCFile::setAssocBus(int bus)
|
||||
assocBuses = bus;
|
||||
}
|
||||
|
||||
DBC_ATTRIBUTE *DBCFile::findAttributeByName(QString name)
|
||||
DBC_ATTRIBUTE *DBCFile::findAttributeByName(QString name, DBC_ATTRIBUTE_TYPE type)
|
||||
{
|
||||
if (dbc_attributes.length() == 0) return nullptr;
|
||||
for (int i = 0; i < dbc_attributes.length(); i++)
|
||||
{
|
||||
if (dbc_attributes[i].name.compare(name, Qt::CaseInsensitive) == 0)
|
||||
if (dbc_attributes[i].name.compare(name, Qt::CaseInsensitive) == 0 && ((type == dbc_attributes[i].attrType) || (type == ATTR_TYPE_ANY) ) )
|
||||
{
|
||||
return &dbc_attributes[i];
|
||||
}
|
||||
@@ -481,11 +481,24 @@ DBC_SIGNAL* DBCFile::parseSignalLine(QString line, DBC_MESSAGE *msg)
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "standard signal";
|
||||
regex.setPattern("^SG\\_ *(\\w+) *: *(\\d+)\\|(\\d+)@(\\d+)([\\+|\\-]) \\(([0-9.+\\-eE]+),([0-9.+\\-eE]+)\\) \\[([0-9.+\\-eE]+)\\|([0-9.+\\-eE]+)\\] \\\"(.*)\\\" (.*)");
|
||||
regex.setPattern("^SG\\_ *(\\w+) +m(\\d+)M *: *(\\d+)\\|(\\d+)@(\\d+)([\\+|\\-]) \\(([0-9.+\\-eE]+),([0-9.+\\-eE]+)\\) \\[([0-9.+\\-eE]+)\\|([0-9.+\\-eE]+)\\] \\\"(.*)\\\" (.*)");
|
||||
match = regex.match(line);
|
||||
sig.isMultiplexed = false;
|
||||
sig.isMultiplexor = false;
|
||||
if (match.hasMatch())
|
||||
{
|
||||
qDebug() << "Extended Multiplexor Signal";
|
||||
sig.isMultiplexor = true; //we don't set the local isMultiplexor variable because this isn't the top level multiplexor
|
||||
sig.isMultiplexed = true; //but, it is both a multiplexor and multiplexed
|
||||
sig.multiplexValue = match.captured(2).toInt();
|
||||
offset = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "standard signal";
|
||||
regex.setPattern("^SG\\_ *(\\w+) *: *(\\d+)\\|(\\d+)@(\\d+)([\\+|\\-]) \\(([0-9.+\\-eE]+),([0-9.+\\-eE]+)\\) \\[([0-9.+\\-eE]+)\\|([0-9.+\\-eE]+)\\] \\\"(.*)\\\" (.*)");
|
||||
match = regex.match(line);
|
||||
sig.isMultiplexed = false;
|
||||
sig.isMultiplexor = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -566,6 +579,46 @@ DBC_SIGNAL* DBCFile::parseSignalLine(QString line, DBC_MESSAGE *msg)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//SG_MUL_VAL_ 2024 S1_PID_0D_VehicleSpeed S1 13-13;
|
||||
bool DBCFile::parseSignalMultiplexValueLine(QString line)
|
||||
{
|
||||
QRegularExpression regex;
|
||||
QRegularExpressionMatch match;
|
||||
|
||||
qDebug() << "Found a multiplex definition line";
|
||||
regex.setPattern("^SG\\_MUL\\_VAL\\_ (\\d+) (\\w+) (\\w+) (\\d+)\\-(\\d+);");
|
||||
match = regex.match(line);
|
||||
//captured 1 is message ID
|
||||
//Captured 2 is signal name
|
||||
//Captured 3 is parent multiplexor
|
||||
//captured 4 is the lower bound
|
||||
//captured 5 is the upper bound
|
||||
if (match.hasMatch())
|
||||
{
|
||||
DBC_MESSAGE *msg = messageHandler->findMsgByID(match.captured(1).toUInt());
|
||||
if (msg != nullptr)
|
||||
{
|
||||
DBC_SIGNAL *thisSignal = msg->sigHandler->findSignalByName(match.captured(2));
|
||||
if (thisSignal != nullptr)
|
||||
{
|
||||
DBC_SIGNAL *parentSignal = msg->sigHandler->findSignalByName(match.captured(3));
|
||||
if (parentSignal != nullptr)
|
||||
{
|
||||
//now need to add "thisSignal" to the children multiplexed signals of "parentSignal"
|
||||
DBC_MULTIPLEX mx;
|
||||
mx.lowerBound = match.captured(4).toInt();
|
||||
mx.upperBound = match.captured(5).toInt();
|
||||
mx.sig = thisSignal;
|
||||
parentSignal->multiplexedChildren.append(mx);
|
||||
thisSignal->multiplexParent = parentSignal;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DBCFile::parseValueLine(QString line)
|
||||
{
|
||||
QRegularExpression regex;
|
||||
@@ -732,16 +785,16 @@ bool DBCFile::parseDefaultAttrLine(QString line)
|
||||
{
|
||||
switch (found->valType)
|
||||
{
|
||||
case QSTRING:
|
||||
case ATTR_STRING:
|
||||
found->defaultValue = match.captured(2);
|
||||
break;
|
||||
case QFLOAT:
|
||||
case ATTR_FLOAT:
|
||||
found->defaultValue = match.captured(2).toFloat();
|
||||
break;
|
||||
case QINT:
|
||||
case ATTR_INT:
|
||||
found->defaultValue = match.captured(2).toInt();
|
||||
break;
|
||||
case ENUM:
|
||||
case ATTR_ENUM:
|
||||
QString temp = match.captured(2);
|
||||
found->defaultValue = 0;
|
||||
for (int x = 0; x < found->enumVals.count(); x++)
|
||||
@@ -825,6 +878,12 @@ bool DBCFile::loadFile(QString fileName)
|
||||
{
|
||||
if (!parseSignalLine(line, currentMessage)) numSigFaults++;
|
||||
}
|
||||
|
||||
if (line.startsWith("SG_MUL_VAL_ ")) //defines a signal multiplexing value definition
|
||||
{
|
||||
if (!parseSignalMultiplexValueLine(line)) numSigFaults++;
|
||||
}
|
||||
|
||||
if (line.startsWith("BU_:")) //line specifies the nodes on this canbus
|
||||
{
|
||||
qDebug() << "Found a BU line";
|
||||
@@ -917,33 +976,46 @@ bool DBCFile::loadFile(QString fileName)
|
||||
if (parseAttribute(line.right(line.length() - 12), attr))
|
||||
{
|
||||
//qDebug() << "Success";
|
||||
attr.attrType = SIG;
|
||||
attr.attrType = ATTR_TYPE_SIG;
|
||||
dbc_attributes.append(attr);
|
||||
}
|
||||
}
|
||||
if (line.startsWith("BA_DEF_ BO_ ")) //definition of a message attribute
|
||||
else if (line.startsWith("BA_DEF_ BO_ ")) //definition of a message attribute
|
||||
{
|
||||
qDebug() << "Found a BO attribute line";
|
||||
|
||||
if (parseAttribute(line.right(line.length() - 12), attr))
|
||||
{
|
||||
qDebug() << "Success";
|
||||
attr.attrType = MESSAGE;
|
||||
attr.attrType = ATTR_TYPE_MESSAGE;
|
||||
dbc_attributes.append(attr);
|
||||
}
|
||||
}
|
||||
if (line.startsWith("BA_DEF_ BU_ ")) //definition of a node attribute
|
||||
else if (line.startsWith("BA_DEF_ BU_ ")) //definition of a node attribute
|
||||
{
|
||||
qDebug() << "Found a BU attribute line";
|
||||
|
||||
if (parseAttribute(line.right(line.length() - 12), attr))
|
||||
{
|
||||
//qDebug() << "Success";
|
||||
attr.attrType = NODE;
|
||||
attr.attrType = ATTR_TYPE_NODE;
|
||||
dbc_attributes.append(attr);
|
||||
}
|
||||
}
|
||||
|
||||
else if (line.startsWith("BA_DEF_ ")) //definition of a root attribute
|
||||
{
|
||||
qDebug() << "Found a BU attribute line";
|
||||
|
||||
if (parseAttribute(line.right(line.length() - 9), attr))
|
||||
{
|
||||
//qDebug() << "Success";
|
||||
attr.attrType = ATTR_TYPE_GENERAL;
|
||||
dbc_attributes.append(attr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (line.startsWith("BA_DEF_DEF_ ")) //definition of default value for an attribute
|
||||
{
|
||||
parseDefaultAttrLine(line);
|
||||
@@ -961,13 +1033,13 @@ bool DBCFile::loadFile(QString fileName)
|
||||
DBC_ATTRIBUTE *bgAttr = findAttributeByName("GenMsgBackgroundColor");
|
||||
if (!bgAttr)
|
||||
{
|
||||
attr.attrType = MESSAGE;
|
||||
attr.attrType = ATTR_TYPE_MESSAGE;
|
||||
attr.defaultValue = QApplication::palette().color(QPalette::Base).name();
|
||||
attr.enumVals.clear();
|
||||
attr.lower = 0;
|
||||
attr.upper = 0;
|
||||
attr.name = "GenMsgBackgroundColor";
|
||||
attr.valType = QSTRING;
|
||||
attr.valType = ATTR_STRING;
|
||||
dbc_attributes.append(attr);
|
||||
bgAttr = findAttributeByName("GenMsgBackgroundColor");
|
||||
}
|
||||
@@ -975,13 +1047,13 @@ bool DBCFile::loadFile(QString fileName)
|
||||
DBC_ATTRIBUTE *fgAttr = findAttributeByName("GenMsgForegroundColor");
|
||||
if (!fgAttr)
|
||||
{
|
||||
attr.attrType = MESSAGE;
|
||||
attr.attrType = ATTR_TYPE_MESSAGE;
|
||||
attr.defaultValue = QApplication::palette().color(QPalette::WindowText).name();
|
||||
attr.enumVals.clear();
|
||||
attr.lower = 0;
|
||||
attr.upper = 0;
|
||||
attr.name = "GenMsgForegroundColor";
|
||||
attr.valType = QSTRING;
|
||||
attr.valType = ATTR_STRING;
|
||||
dbc_attributes.append(attr);
|
||||
fgAttr = findAttributeByName("GenMsgForegroundColor");
|
||||
}
|
||||
@@ -1021,6 +1093,22 @@ bool DBCFile::loadFile(QString fileName)
|
||||
thisFG = msg->findAttrValByName("GenMsgForegroundColor");
|
||||
if (thisBG) msg->bgColor = QColor(thisBG->value.toString());
|
||||
if (thisFG) msg->fgColor = QColor(thisFG->value.toString());
|
||||
for (int y = 0; y < msg->sigHandler->getCount(); y++)
|
||||
{
|
||||
DBC_SIGNAL *sig = msg->sigHandler->findSignalByIdx(y);
|
||||
//if this doesn't have a multiplex parent set but is multiplexed then it must have used
|
||||
//simple multiplexing instead of any extended specification. So, fill in the multiplexor signal here
|
||||
//and also write the extended entry for it too.
|
||||
if (sig->isMultiplexed && (sig->multiplexParent == nullptr) )
|
||||
{
|
||||
sig->multiplexParent = msg->multiplexorSignal;
|
||||
DBC_MULTIPLEX mlt;
|
||||
mlt.sig = sig;
|
||||
mlt.lowerBound = sig->multiplexValue;
|
||||
mlt.upperBound = mlt.lowerBound;
|
||||
msg->multiplexorSignal->multiplexedChildren.append(mlt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (numSigFaults > 0 || numMsgFaults > 0)
|
||||
@@ -1049,14 +1137,14 @@ QVariant DBCFile::processAttributeVal(QString input, DBC_ATTRIBUTE_VAL_TYPE typ)
|
||||
QVariant out;
|
||||
switch (typ)
|
||||
{
|
||||
case QSTRING:
|
||||
case ATTR_STRING:
|
||||
out = input;
|
||||
break;
|
||||
case QFLOAT:
|
||||
case ATTR_FLOAT:
|
||||
out = input.toFloat();
|
||||
break;
|
||||
case QINT:
|
||||
case ENUM:
|
||||
case ATTR_INT:
|
||||
case ATTR_ENUM:
|
||||
out = input.toInt();
|
||||
break;
|
||||
}
|
||||
@@ -1080,14 +1168,14 @@ bool DBCFile::parseAttribute(QString inpString, DBC_ATTRIBUTE &attr)
|
||||
qDebug() << "Parsing an attribute with low/high values";
|
||||
attr.name = match.captured(1);
|
||||
QString typ = match.captured(2);
|
||||
attr.attrType = SIG;
|
||||
attr.attrType = ATTR_TYPE_SIG;
|
||||
attr.lower = 0;
|
||||
attr.upper = 0;
|
||||
attr.valType = QSTRING;
|
||||
attr.valType = ATTR_STRING;
|
||||
if (!typ.compare("INT", Qt::CaseInsensitive))
|
||||
{
|
||||
qDebug() << "INT attribute named " << attr.name;
|
||||
attr.valType = QINT;
|
||||
attr.valType = ATTR_INT;
|
||||
attr.lower = match.captured(3).toInt();
|
||||
attr.upper = match.captured(4).toInt();
|
||||
goodAttr = true;
|
||||
@@ -1095,7 +1183,7 @@ bool DBCFile::parseAttribute(QString inpString, DBC_ATTRIBUTE &attr)
|
||||
if (!typ.compare("FLOAT", Qt::CaseInsensitive))
|
||||
{
|
||||
qDebug() << "FLOAT attribute named " << attr.name;
|
||||
attr.valType = QFLOAT;
|
||||
attr.valType = ATTR_FLOAT;
|
||||
attr.lower = match.captured(3).toDouble();
|
||||
attr.upper = match.captured(4).toDouble();
|
||||
goodAttr = true;
|
||||
@@ -1103,7 +1191,7 @@ bool DBCFile::parseAttribute(QString inpString, DBC_ATTRIBUTE &attr)
|
||||
if (!typ.compare("STRING", Qt::CaseInsensitive))
|
||||
{
|
||||
qDebug() << "STRING attribute named " << attr.name;
|
||||
attr.valType = QSTRING;
|
||||
attr.valType = ATTR_STRING;
|
||||
goodAttr = true;
|
||||
}
|
||||
}
|
||||
@@ -1119,26 +1207,26 @@ bool DBCFile::parseAttribute(QString inpString, DBC_ATTRIBUTE &attr)
|
||||
QString typ = match.captured(2);
|
||||
attr.lower = 0;
|
||||
attr.upper = 0;
|
||||
attr.attrType = SIG;
|
||||
attr.attrType = ATTR_TYPE_SIG;
|
||||
|
||||
if (!typ.compare("INT", Qt::CaseInsensitive))
|
||||
{
|
||||
qDebug() << "INT attribute named " << attr.name;
|
||||
attr.valType = QINT;
|
||||
attr.valType = ATTR_INT;
|
||||
goodAttr = true;
|
||||
}
|
||||
|
||||
if (!typ.compare("FLOAT", Qt::CaseInsensitive))
|
||||
{
|
||||
qDebug() << "FLOAT attribute named " << attr.name;
|
||||
attr.valType = QFLOAT;
|
||||
attr.valType = ATTR_FLOAT;
|
||||
goodAttr = true;
|
||||
}
|
||||
|
||||
if (!typ.compare("STRING", Qt::CaseInsensitive))
|
||||
{
|
||||
qDebug() << "STRING attribute named " << attr.name;
|
||||
attr.valType = QSTRING;
|
||||
attr.valType = ATTR_STRING;
|
||||
goodAttr = true;
|
||||
}
|
||||
|
||||
@@ -1151,7 +1239,7 @@ bool DBCFile::parseAttribute(QString inpString, DBC_ATTRIBUTE &attr)
|
||||
attr.enumVals.append(Utility::unQuote(enumStr));
|
||||
qDebug() << "Enum value: " << enumStr;
|
||||
}
|
||||
attr.valType = ENUM;
|
||||
attr.valType = ATTR_ENUM;
|
||||
goodAttr = true;
|
||||
}
|
||||
}
|
||||
@@ -1378,15 +1466,15 @@ bool DBCFile::saveFile(QString fileName)
|
||||
msgOutput.append("BA_DEF_ ");
|
||||
switch (dbc_attributes[x].attrType)
|
||||
{
|
||||
case GENERAL:
|
||||
case ATTR_TYPE_GENERAL:
|
||||
break;
|
||||
case NODE:
|
||||
case ATTR_TYPE_NODE:
|
||||
msgOutput.append("BU_ ");
|
||||
break;
|
||||
case MESSAGE:
|
||||
case ATTR_TYPE_MESSAGE:
|
||||
msgOutput.append("BO_ ");
|
||||
break;
|
||||
case SIG:
|
||||
case ATTR_TYPE_SIG:
|
||||
msgOutput.append("SG_ ");
|
||||
break;
|
||||
}
|
||||
@@ -1395,16 +1483,16 @@ bool DBCFile::saveFile(QString fileName)
|
||||
|
||||
switch (dbc_attributes[x].valType)
|
||||
{
|
||||
case QINT:
|
||||
case ATTR_INT:
|
||||
msgOutput.append("INT " + QString::number(dbc_attributes[x].lower) + " " + QString::number(dbc_attributes[x].upper));
|
||||
break;
|
||||
case QFLOAT:
|
||||
case ATTR_FLOAT:
|
||||
msgOutput.append("FLOAT " + QString::number(dbc_attributes[x].lower) + " " + QString::number(dbc_attributes[x].upper));
|
||||
break;
|
||||
case QSTRING:
|
||||
case ATTR_STRING:
|
||||
msgOutput.append("STRING ");
|
||||
break;
|
||||
case ENUM:
|
||||
case ATTR_ENUM:
|
||||
msgOutput.append("ENUM ");
|
||||
foreach (QString str, dbc_attributes[x].enumVals)
|
||||
{
|
||||
@@ -1424,14 +1512,14 @@ bool DBCFile::saveFile(QString fileName)
|
||||
defaultsOutput.append("BA_DEF_DEF_ \"" + dbc_attributes[x].name + "\" ");
|
||||
switch (dbc_attributes[x].valType)
|
||||
{
|
||||
case QSTRING:
|
||||
case ATTR_STRING:
|
||||
defaultsOutput.append("\"" + dbc_attributes[x].defaultValue.toString() + "\";\n");
|
||||
break;
|
||||
case ENUM:
|
||||
case ATTR_ENUM:
|
||||
defaultsOutput.append("\"" + dbc_attributes[x].enumVals[dbc_attributes[x].defaultValue.toInt()] + "\";\n");
|
||||
break;
|
||||
case QINT:
|
||||
case QFLOAT:
|
||||
case ATTR_INT:
|
||||
case ATTR_FLOAT:
|
||||
defaultsOutput.append(dbc_attributes[x].defaultValue.toString() + ";\n");
|
||||
break;
|
||||
}
|
||||
@@ -1496,42 +1584,42 @@ int DBCHandler::createBlankFile()
|
||||
DBC_ATTRIBUTE attr;
|
||||
|
||||
//add our custom attributes to the new file so that we know they're already there.
|
||||
attr.attrType = MESSAGE;
|
||||
attr.attrType = ATTR_TYPE_MESSAGE;
|
||||
attr.defaultValue = QApplication::palette().color(QPalette::Base).name();
|
||||
qDebug() << attr.defaultValue;
|
||||
attr.enumVals.clear();
|
||||
attr.lower = 0;
|
||||
attr.upper = 0;
|
||||
attr.name = "GenMsgBackgroundColor";
|
||||
attr.valType = QSTRING;
|
||||
attr.valType = ATTR_STRING;
|
||||
newFile.dbc_attributes.append(attr);
|
||||
|
||||
attr.attrType = MESSAGE;
|
||||
attr.attrType = ATTR_TYPE_MESSAGE;
|
||||
attr.defaultValue = QApplication::palette().color(QPalette::WindowText).name();
|
||||
qDebug() << attr.defaultValue;
|
||||
attr.enumVals.clear();
|
||||
attr.lower = 0;
|
||||
attr.upper = 0;
|
||||
attr.name = "GenMsgForegroundColor";
|
||||
attr.valType = QSTRING;
|
||||
attr.valType = ATTR_STRING;
|
||||
newFile.dbc_attributes.append(attr);
|
||||
|
||||
attr.attrType = MESSAGE;
|
||||
attr.attrType = ATTR_TYPE_MESSAGE;
|
||||
attr.defaultValue = 0;
|
||||
attr.enumVals.clear();
|
||||
attr.lower = 0;
|
||||
attr.upper = 0;
|
||||
attr.name = "matchingcriteria";
|
||||
attr.valType = QINT;
|
||||
attr.valType = ATTR_INT;
|
||||
newFile.dbc_attributes.append(attr);
|
||||
|
||||
attr.attrType = MESSAGE;
|
||||
attr.attrType = ATTR_TYPE_MESSAGE;
|
||||
attr.defaultValue = 0;
|
||||
attr.enumVals.clear();
|
||||
attr.lower = 0;
|
||||
attr.upper = 0;
|
||||
attr.name = "filterlabeling";
|
||||
attr.valType = QINT;
|
||||
attr.valType = ATTR_INT;
|
||||
newFile.dbc_attributes.append(attr);
|
||||
|
||||
DBC_NODE falseNode;
|
||||
@@ -1870,24 +1958,24 @@ DBCHandler::DBCHandler()
|
||||
|
||||
DBC_ATTRIBUTE attr;
|
||||
|
||||
attr.attrType = MESSAGE;
|
||||
attr.attrType = ATTR_TYPE_MESSAGE;
|
||||
attr.defaultValue = matchingCriteria;
|
||||
attr.enumVals.clear();
|
||||
attr.lower = 0;
|
||||
attr.upper = 0;
|
||||
attr.name = "matchingcriteria";
|
||||
attr.valType = QINT;
|
||||
attr.valType = ATTR_INT;
|
||||
file->dbc_attributes.append(attr);
|
||||
file->messageHandler->setMatchingCriteria(matchingCriteria);
|
||||
|
||||
bool filterLabeling = settings.value("DBC/FilterLabeling_" + QString(i),0).toBool();
|
||||
attr.attrType = MESSAGE;
|
||||
attr.attrType = ATTR_TYPE_MESSAGE;
|
||||
attr.defaultValue = filterLabeling;
|
||||
attr.enumVals.clear();
|
||||
attr.lower = 0;
|
||||
attr.upper = 0;
|
||||
attr.name = "filterlabeling";
|
||||
attr.valType = QINT;
|
||||
attr.valType = ATTR_INT;
|
||||
file->dbc_attributes.append(attr);
|
||||
file->messageHandler->setFilterLabeling(filterLabeling);
|
||||
|
||||
|
||||
+2
-1
@@ -73,7 +73,7 @@ public:
|
||||
DBCFile& operator=(const DBCFile& cpy);
|
||||
DBC_NODE *findNodeByName(QString name);
|
||||
DBC_NODE *findNodeByIdx(int idx);
|
||||
DBC_ATTRIBUTE *findAttributeByName(QString name);
|
||||
DBC_ATTRIBUTE *findAttributeByName(QString name, DBC_ATTRIBUTE_TYPE type = ATTR_TYPE_ANY);
|
||||
DBC_ATTRIBUTE *findAttributeByIdx(int idx);
|
||||
void findAttributesByType(DBC_ATTRIBUTE_TYPE typ, QList<DBC_ATTRIBUTE> *list);
|
||||
bool saveFile(QString);
|
||||
@@ -99,6 +99,7 @@ private:
|
||||
bool parseAttribute(QString inpString, DBC_ATTRIBUTE &attr);
|
||||
QVariant processAttributeVal(QString input, DBC_ATTRIBUTE_VAL_TYPE typ);
|
||||
DBC_SIGNAL* parseSignalLine(QString line, DBC_MESSAGE *msg);
|
||||
bool parseSignalMultiplexValueLine(QString line);
|
||||
DBC_MESSAGE* parseMessageLine(QString line);
|
||||
bool parseValueLine(QString line);
|
||||
bool parseAttributeLine(QString line);
|
||||
|
||||
@@ -35,7 +35,7 @@ DBCLoadSaveWindow::DBCLoadSaveWindow(const QVector<CANFrame> *frames, QWidget *p
|
||||
{
|
||||
DBCFile * file = dbcHandler->getFileByIdx(idx);
|
||||
ui->tableFiles->insertRow(ui->tableFiles->rowCount());
|
||||
ui->tableFiles->setItem(idx, 0, new QTableWidgetItem(file->getFullFilename()));
|
||||
ui->tableFiles->setItem(idx, 0, new QTableWidgetItem(file->getFilename()));
|
||||
QString bus = QString::number(file->getAssocBus() );
|
||||
ui->tableFiles->setItem(idx, 1, new QTableWidgetItem(bus));
|
||||
|
||||
@@ -189,7 +189,7 @@ void DBCLoadSaveWindow::loadFile()
|
||||
inhibitCellProcessing=true;
|
||||
int idx = ui->tableFiles->rowCount();
|
||||
ui->tableFiles->insertRow(ui->tableFiles->rowCount());
|
||||
ui->tableFiles->setItem(idx, 0, new QTableWidgetItem(file->getFullFilename()));
|
||||
ui->tableFiles->setItem(idx, 0, new QTableWidgetItem(file->getFilename()));
|
||||
ui->tableFiles->setItem(idx, 1, new QTableWidgetItem("-1"));
|
||||
|
||||
DBC_ATTRIBUTE *attr = file->findAttributeByName("matchingcriteria");
|
||||
@@ -227,7 +227,7 @@ void DBCLoadSaveWindow::saveFile()
|
||||
if (idx < 0) return;
|
||||
dbcHandler->saveDBCFile(idx);
|
||||
//then update the list to show the new file name (if it changed)
|
||||
ui->tableFiles->setItem(idx, 0, new QTableWidgetItem(dbcHandler->getFileByIdx(idx)->getFullFilename()));
|
||||
ui->tableFiles->setItem(idx, 0, new QTableWidgetItem(dbcHandler->getFileByIdx(idx)->getFilename()));
|
||||
}
|
||||
|
||||
void DBCLoadSaveWindow::removeFile()
|
||||
@@ -305,13 +305,13 @@ void DBCLoadSaveWindow::matchingCriteriaChanged(int index)
|
||||
{
|
||||
DBC_ATTRIBUTE attr;
|
||||
|
||||
attr.attrType = MESSAGE;
|
||||
attr.attrType = ATTR_TYPE_MESSAGE;
|
||||
attr.defaultValue = matchingCriteria;
|
||||
attr.enumVals.clear();
|
||||
attr.lower = 0;
|
||||
attr.upper = 0;
|
||||
attr.name = "matchingcriteria";
|
||||
attr.valType = QINT;
|
||||
attr.valType = ATTR_INT;
|
||||
file->dbc_attributes.append(attr);
|
||||
file->messageHandler->setMatchingCriteria(matchingCriteria);
|
||||
}
|
||||
@@ -351,13 +351,13 @@ void DBCLoadSaveWindow::cellChanged(int row, int col)
|
||||
{
|
||||
DBC_ATTRIBUTE attr;
|
||||
|
||||
attr.attrType = MESSAGE;
|
||||
attr.attrType = ATTR_TYPE_MESSAGE;
|
||||
attr.defaultValue = labelFilters ? 1 : 0;
|
||||
attr.enumVals.clear();
|
||||
attr.lower = 0;
|
||||
attr.upper = 0;
|
||||
attr.name = "labelfilters";
|
||||
attr.valType = QINT;
|
||||
attr.valType = ATTR_INT;
|
||||
file->dbc_attributes.append(attr);
|
||||
file->messageHandler->setFilterLabeling(labelFilters);
|
||||
}
|
||||
|
||||
+63
-21
@@ -230,6 +230,19 @@ void DBCMainEditor::currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t DBCMainEditor::getParentMessageID(QTreeWidgetItem *cell)
|
||||
{
|
||||
if (cell->data(0, Qt::UserRole) == 2)
|
||||
{
|
||||
return static_cast<uint32_t>(Utility::ParseStringToNum(cell->text(0).split(" ")[0]));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cell->parent()) return getParentMessageID(cell->parent());
|
||||
else return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//Double clicking is interpreted as a desire to edit the given item.
|
||||
void DBCMainEditor::onTreeDoubleClicked(const QModelIndex &index)
|
||||
{
|
||||
@@ -266,16 +279,21 @@ void DBCMainEditor::onTreeDoubleClicked(const QModelIndex &index)
|
||||
msgEditor->show(); //show allows the rest of the forms to keep going
|
||||
break;
|
||||
case 3: //a signal
|
||||
idString = firstCol->parent()->text(0).split(" ")[0];
|
||||
msgID = static_cast<uint32_t>(Utility::ParseStringToNum(idString));
|
||||
msgID = getParentMessageID(firstCol);
|
||||
msg = dbcFile->messageHandler->findMsgByID(msgID);
|
||||
sig = msg->sigHandler->findSignalByName(firstCol->text(0).split(" ")[0]);
|
||||
sigEditor->setSignalRef(sig);
|
||||
sigEditor->setMessageRef(msg);
|
||||
sigEditor->setFileIdx(fileIdx);
|
||||
//sigEditor->setWindowModality(Qt::WindowModal);
|
||||
sigEditor->refreshView();
|
||||
sigEditor->show();
|
||||
QString nameString = firstCol->text(0);
|
||||
if (nameString.contains("(")) nameString = nameString.split(" ")[1];
|
||||
else nameString = nameString.split(" ")[0];
|
||||
sig = msg->sigHandler->findSignalByName(nameString);
|
||||
if (sig)
|
||||
{
|
||||
sigEditor->setSignalRef(sig);
|
||||
sigEditor->setMessageRef(msg);
|
||||
sigEditor->setFileIdx(fileIdx);
|
||||
//sigEditor->setWindowModality(Qt::WindowModal);
|
||||
sigEditor->refreshView();
|
||||
sigEditor->show();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -330,16 +348,8 @@ void DBCMainEditor::refreshTree()
|
||||
for (int i = 0; i < msg->sigHandler->getCount(); i++)
|
||||
{
|
||||
DBC_SIGNAL *sig = msg->sigHandler->findSignalByIdx(i);
|
||||
QTreeWidgetItem *sigItem = new QTreeWidgetItem(msgItem);
|
||||
QString sigInfo = sig->name;
|
||||
if (sig->comment.count() > 0) sigInfo.append(" - ").append(sig->comment);
|
||||
sigItem->setText(0, sigInfo);
|
||||
if (sig->isMultiplexed) sigItem->setIcon(0, multiplexedSignalIcon);
|
||||
else if (sig->isMultiplexor) sigItem->setIcon(0, multiplexorSignalIcon);
|
||||
else sigItem->setIcon(0, signalIcon);
|
||||
sigItem->setData(0, Qt::UserRole, 3);
|
||||
signalToItem.insert(sig, sigItem);
|
||||
itemToSignal.insert(sigItem, sig);
|
||||
//only process signals here which are "top" level
|
||||
if (sig->multiplexParent == nullptr) processSignalToTree(msgItem, sig);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -348,6 +358,39 @@ void DBCMainEditor::refreshTree()
|
||||
ui->treeDBC->sortItems(0, Qt::SortOrder::AscendingOrder); //sort the display list for ease in viewing by mere mortals, helps me a lot.
|
||||
}
|
||||
|
||||
QString DBCMainEditor::createSignalText(DBC_SIGNAL *sig)
|
||||
{
|
||||
QString sigInfo;
|
||||
if (sig->isMultiplexed)
|
||||
{
|
||||
sigInfo = "(" + QString::number(sig->multiplexValue) + ") ";
|
||||
}
|
||||
sigInfo.append(sig->name);
|
||||
if (sig->comment.count() > 0) sigInfo.append(" - ").append(sig->comment);
|
||||
return sigInfo;
|
||||
}
|
||||
|
||||
//Signals can have a hierarchial relationship with other signals so this function is separate and calls itself recursively to build the tree
|
||||
void DBCMainEditor::processSignalToTree(QTreeWidgetItem *parent, DBC_SIGNAL *sig)
|
||||
{
|
||||
QTreeWidgetItem *sigItem = new QTreeWidgetItem(parent);
|
||||
QString sigInfo = createSignalText(sig);
|
||||
sigItem->setText(0, sigInfo);
|
||||
if (sig->isMultiplexor) sigItem->setIcon(0, multiplexorSignalIcon);
|
||||
else if (sig->isMultiplexed) sigItem->setIcon(0, multiplexedSignalIcon);
|
||||
else sigItem->setIcon(0, signalIcon);
|
||||
sigItem->setData(0, Qt::UserRole, 3);
|
||||
signalToItem.insert(sig, sigItem);
|
||||
itemToSignal.insert(sigItem, sig);
|
||||
if (sig->multiplexedChildren.count() > 0)
|
||||
{
|
||||
for (int i = 0; i < sig->multiplexedChildren.count(); i++)
|
||||
{
|
||||
processSignalToTree(sigItem, sig->multiplexedChildren[i].sig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DBCMainEditor::updatedNode(DBC_NODE *node)
|
||||
{
|
||||
if (nodeToItem.contains(node))
|
||||
@@ -403,8 +446,7 @@ void DBCMainEditor::updatedSignal(DBC_SIGNAL *sig)
|
||||
if (signalToItem.contains(sig))
|
||||
{
|
||||
QTreeWidgetItem *item = signalToItem.value(sig);
|
||||
QString sigInfo = sig->name;
|
||||
if (sig->comment.count() > 0) sigInfo.append(" - ").append(sig->comment);
|
||||
QString sigInfo = createSignalText(sig);
|
||||
item->setText(0, sigInfo);
|
||||
}
|
||||
else qDebug() << "That signal doesn't exist. That's a bug dude.";
|
||||
|
||||
@@ -76,6 +76,9 @@ private:
|
||||
void readSettings();
|
||||
void writeSettings();
|
||||
void refreshTree();
|
||||
void processSignalToTree(QTreeWidgetItem *parent, DBC_SIGNAL *sig);
|
||||
uint32_t getParentMessageID(QTreeWidgetItem *cell);
|
||||
QString createSignalText(DBC_SIGNAL *sig);
|
||||
};
|
||||
|
||||
#endif // DBCMAINEDITOR_H
|
||||
|
||||
+82
-3
@@ -190,6 +190,22 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
|
||||
//TODO: could look up the multiplexor and ensure that the value is within a range that the multiplexor could return
|
||||
currentSignal->multiplexValue = temp;
|
||||
});
|
||||
|
||||
connect(ui->rbExtended, &QRadioButton::toggled,
|
||||
[=](bool state)
|
||||
{
|
||||
if (state && currentSignal) //signal is now set as an extended multiplex/multiplexor
|
||||
{
|
||||
currentSignal->isMultiplexed = true;
|
||||
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->txtMultiplexValue->setEnabled(currentSignal->isMultiplexed);
|
||||
ui->cbMultiplexParent->setEnabled(currentSignal->isMultiplexed);
|
||||
dbcFile->setDirtyFlag();
|
||||
});
|
||||
|
||||
connect(ui->rbMultiplexed, &QRadioButton::toggled,
|
||||
[=](bool state)
|
||||
{
|
||||
@@ -200,6 +216,8 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
|
||||
//if the set multiplexor for the message was this signal then clear it
|
||||
if (dbcMessage->multiplexorSignal == currentSignal) dbcMessage->multiplexorSignal = nullptr;
|
||||
}
|
||||
ui->txtMultiplexValue->setEnabled(currentSignal->isMultiplexed);
|
||||
ui->cbMultiplexParent->setEnabled(currentSignal->isMultiplexed);
|
||||
dbcFile->setDirtyFlag();
|
||||
});
|
||||
|
||||
@@ -215,6 +233,8 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
|
||||
//we just set that this is the multiplexor so update the message to show that as well.
|
||||
dbcMessage->multiplexorSignal = currentSignal;
|
||||
}
|
||||
ui->txtMultiplexValue->setEnabled(currentSignal->isMultiplexed);
|
||||
ui->cbMultiplexParent->setEnabled(currentSignal->isMultiplexed);
|
||||
dbcFile->setDirtyFlag();
|
||||
});
|
||||
|
||||
@@ -227,9 +247,42 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
|
||||
currentSignal->isMultiplexor = false;
|
||||
if (dbcMessage->multiplexorSignal == currentSignal) dbcMessage->multiplexorSignal = nullptr;
|
||||
}
|
||||
ui->txtMultiplexValue->setEnabled(currentSignal->isMultiplexed);
|
||||
ui->cbMultiplexParent->setEnabled(currentSignal->isMultiplexed);
|
||||
dbcFile->setDirtyFlag();
|
||||
});
|
||||
|
||||
connect(ui->cbMultiplexParent, &QComboBox::currentTextChanged,
|
||||
[=]()
|
||||
{
|
||||
//try to look up the signal that we're set to now, remove this signal from existing children list
|
||||
//add it to this one, update this signal's parent multiplexor
|
||||
DBC_SIGNAL *newSig = dbcMessage->sigHandler->findSignalByName(ui->cbMultiplexParent->currentText());
|
||||
DBC_SIGNAL *oldParent = currentSignal->multiplexParent;
|
||||
int low = currentSignal->multiplexValue;
|
||||
int high = low;
|
||||
if (newSig)
|
||||
{
|
||||
for (int i = 0; i < oldParent->multiplexedChildren.count(); i++)
|
||||
{
|
||||
if (oldParent->multiplexedChildren[i].sig == currentSignal)
|
||||
{
|
||||
low = oldParent->multiplexedChildren[i].lowerBound;
|
||||
high = oldParent->multiplexedChildren[i].upperBound;
|
||||
oldParent->multiplexedChildren.removeAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
currentSignal->multiplexParent = newSig;
|
||||
DBC_MULTIPLEX mlt;
|
||||
mlt.lowerBound = low;
|
||||
mlt.upperBound = high;
|
||||
mlt.sig = currentSignal;
|
||||
newSig->multiplexedChildren.append(mlt);
|
||||
dbcFile->setDirtyFlag();
|
||||
}
|
||||
});
|
||||
|
||||
installEventFilter(this);
|
||||
}
|
||||
|
||||
@@ -413,11 +466,37 @@ void DBCSignalEditor::fillSignalForm(DBC_SIGNAL *sig)
|
||||
ui->txtMinVal->setText(QString::number(sig->min));
|
||||
ui->txtScale->setText(QString::number(sig->factor));
|
||||
ui->txtUnitName->setText(sig->unitName);
|
||||
ui->rbMultiplexed->setChecked(sig->isMultiplexed);
|
||||
ui->rbMultiplexor->setChecked(sig->isMultiplexor);
|
||||
ui->rbNotMulti->setChecked( !(sig->isMultiplexor | sig->isMultiplexed) );
|
||||
if (sig->isMultiplexed && sig->isMultiplexor)
|
||||
{
|
||||
ui->rbMultiplexed->setChecked(false);
|
||||
ui->rbMultiplexor->setChecked(false);
|
||||
ui->rbNotMulti->setChecked(false);
|
||||
ui->rbExtended->setChecked(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->rbMultiplexed->setChecked(sig->isMultiplexed);
|
||||
ui->rbMultiplexor->setChecked(sig->isMultiplexor);
|
||||
ui->rbNotMulti->setChecked( !(sig->isMultiplexor | sig->isMultiplexed) );
|
||||
}
|
||||
qDebug() << sig->isMultiplexor << "*" << sig->isMultiplexed;
|
||||
|
||||
ui->cbMultiplexParent->clear();
|
||||
|
||||
int numSigs = dbcMessage->sigHandler->getCount();
|
||||
for (int i = 0; i < numSigs; i++)
|
||||
{
|
||||
DBC_SIGNAL *sig_iter = dbcMessage->sigHandler->findSignalByIdx(i);
|
||||
if (sig_iter->isMultiplexor && (sig_iter != sig))
|
||||
{
|
||||
ui->cbMultiplexParent->addItem(sig_iter->name);
|
||||
if (sig->multiplexParent == sig_iter) ui->cbMultiplexParent->setCurrentIndex(ui->cbMultiplexParent->count() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
ui->txtMultiplexValue->setEnabled(sig->isMultiplexed);
|
||||
ui->cbMultiplexParent->setEnabled(sig->isMultiplexed);
|
||||
|
||||
memset(bitpattern, 0, 8); //clear it out first.
|
||||
|
||||
int startBit, endBit;
|
||||
|
||||
+20
-3
@@ -160,7 +160,7 @@
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbNotMulti">
|
||||
<property name="text">
|
||||
<string>Not multiplexed</string>
|
||||
<string>None</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -178,6 +178,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbExtended">
|
||||
<property name="text">
|
||||
<string>Extended</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
@@ -190,16 +197,26 @@
|
||||
<item row="10" column="1">
|
||||
<widget class="QLineEdit" name="txtMultiplexValue"/>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<item row="12" column="0">
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="text">
|
||||
<string>Comment:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<item row="12" column="1">
|
||||
<widget class="QLineEdit" name="txtComment"/>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<widget class="QComboBox" name="cbMultiplexParent"/>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="text">
|
||||
<string>Multiplex Parent</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
|
||||
Reference in New Issue
Block a user