Added fully qualified dbc, node, and msg searching

...to graphing window and signal viewer so complex systems with message
name duplication (eg "Status") works well.  DBCHandler class has a new
function to find a msg by fully qualified node name...Utility class defines
the qualified name seperator, right now it is :: and is used thusly
filenameNoExtension::nodeName for display in the node dropdown (because
nodes can be common between dbc files).  To get the message from the
system you use the findMessage function in dbchandler and pass the
msgName and the fully qualified node name.  This is about as unique as we
can get, second only to message ID.

Added node comboBox to graph signal editor for easier data filtering
(took the same implementation that was in signal viewer, and tuned up
both of them)
This commit is contained in:
Andy Huska
2023-05-17 17:23:27 -05:00
parent 0f9a17123d
commit ab476c746e
11 changed files with 272 additions and 71 deletions
+1
View File
@@ -71,6 +71,7 @@ class DBC_NODE
public:
QString name;
QString comment;
QString sourceFileName;
QList<DBC_ATTRIBUTE_VALUE> attributes;
DBC_ATTRIBUTE_VALUE *findAttrValByName(QString name);
+47
View File
@@ -392,6 +392,11 @@ QString DBCFile::getFilename()
return fileName;
}
QString DBCFile::getFilenameNoExt()
{
return fileName.split(".dbc")[0];
}
QString DBCFile::getPath()
{
return filePath;
@@ -873,6 +878,7 @@ bool DBCFile::loadFile(QString fileName)
DBC_ATTRIBUTE attr;
int numSigFaults = 0, numMsgFaults = 0;
int linesSinceYield = 0;
QString fileBaseName = QFileInfo(fileName).baseName();
bool inMultilineBU = false;
@@ -911,6 +917,7 @@ bool DBCFile::loadFile(QString fileName)
if (rawLine.startsWith("\t") || rawLine.startsWith(" "))
{
DBC_NODE node;
node.sourceFileName = fileBaseName;
node.name = line;
dbc_nodes.append(node);
}
@@ -950,6 +957,7 @@ bool DBCFile::loadFile(QString fileName)
if (nodeStrings[i].length() > 1)
{
DBC_NODE node;
node.sourceFileName = fileBaseName;
node.name = nodeStrings[i];
dbc_nodes.append(node);
}
@@ -2202,6 +2210,8 @@ DBC_MESSAGE* DBCHandler::findMessageForFilter(uint32_t id, MatchingCriteria_t *
/*
* As above, a real shortcut function that searches all files in order to try to find a message with the given name
* This has pitfalls because the same message name can easily exist in multiple dbc files AND nodes in a single file
* By DBC standards only the MSG ID is required to be unique
*/
DBC_MESSAGE* DBCHandler::findMessage(const QString msgName)
{
@@ -2215,6 +2225,43 @@ DBC_MESSAGE* DBCHandler::findMessage(const QString msgName)
return nullptr; //no match, tough luck, return null
}
DBC_MESSAGE* DBCHandler::findMessage(const QString msgName, const QString nodeName, const QString fileNameNoExt)
{
DBC_MESSAGE *msg = nullptr;
for(int i = 0; i < loadedFiles.count(); i++)
{
DBCFile * file = getFileByIdx(i);
if(file->getFilenameNoExt() == fileNameNoExt)
{
int msgCount = file->messageHandler->getCount();
for(int f = 0; f < msgCount; f++)
{
msg = file->messageHandler->findMsgByIdx(f);
if (msg && msg->name == msgName && msg->sender->name == nodeName)
return msg; //if it's not null and the node name matches return it
}
}
}
return nullptr; //no match, tough luck, return null
}
DBC_MESSAGE* DBCHandler::findMessage(const QString msgName, const QString fullyQualifiedNodeName)
{
QStringList nodeNameParts = fullyQualifiedNodeName.split(Utility::fullyQualifiedNameSeperator);
if(nodeNameParts.count() != 2)
{
qDebug() << "Error parsing fully qualified node name for message search";
return nullptr;
}
QString fileNameNoExt = nodeNameParts[0];
QString nodeName = nodeNameParts[1];
DBC_MESSAGE *msg = nullptr;
msg = findMessage(msgName, nodeName, fileNameNoExt);
return msg;
}
int DBCHandler::getFileCount()
{
return loadedFiles.count();
+3
View File
@@ -82,6 +82,7 @@ public:
bool loadFile(QString);
QString getFullFilename();
QString getFilename();
QString getFilenameNoExt();
QString getPath();
int getAssocBus();
void setAssocBus(int bus);
@@ -121,6 +122,8 @@ public:
void swapFiles(int pos1, int pos2);
DBC_MESSAGE* findMessage(const CANFrame &frame);
DBC_MESSAGE* findMessage(const QString msgName);
DBC_MESSAGE* findMessage(const QString msgName, const QString fullyQualifiedNodeName);
DBC_MESSAGE* findMessage(const QString msgName, const QString nodeName, const QString fileNameNoExt);
DBC_MESSAGE* findMessage(uint32_t id);
DBC_MESSAGE* findMessageForFilter(uint32_t id, MatchingCriteria_t * matchingCriteria);
int getFileCount();
+2 -2
View File
@@ -1031,7 +1031,7 @@ void GraphingWindow::loadDefinitions()
}
if (tokens.length() > 22)
{
DBC_MESSAGE *msg = dbcHandler->findMessage(QString(tokens[21]));
DBC_MESSAGE *msg = dbcHandler->findMessage(gp.ID);
if (msg)
{
gp.associatedSignal = msg->sigHandler->findSignalByName(tokens[22]);
@@ -1079,7 +1079,7 @@ void GraphingWindow::loadDefinitions()
}
if (tokens.length() > 21)
{
DBC_MESSAGE *msg = dbcHandler->findMessage(QString(tokens[20]));
DBC_MESSAGE *msg = dbcHandler->findMessage(gp.ID);
if (msg)
{
gp.associatedSignal = msg->sigHandler->findSignalByName(tokens[21]);
+144 -37
View File
@@ -43,6 +43,7 @@ NewGraphDialog::NewGraphDialog(DBCHandler *handler, QWidget *parent) :
ui->coPointStyle->addItem("Plus Inside Circle");
ui->coPointStyle->addItem("Peace Sign");
connect(ui->cbNodes, SIGNAL(currentIndexChanged(int)), this, SLOT(loadMessages(int)));
connect(ui->cbMessages, SIGNAL(currentIndexChanged(int)), this, SLOT(loadSignals(int)));
connect(ui->gridData, SIGNAL(gridClicked(int)), this, SLOT(bitfieldClicked(int)));
connect(ui->txtDataLen, SIGNAL(textChanged(QString)), this, SLOT(handleDataLenUpdate()));
@@ -54,7 +55,7 @@ NewGraphDialog::NewGraphDialog(DBCHandler *handler, QWidget *parent) :
dataLen = 1;
assocSignal = nullptr;
loadMessages();
loadNodes();
installEventFilter(this);
}
@@ -68,7 +69,8 @@ NewGraphDialog::~NewGraphDialog()
void NewGraphDialog::showEvent(QShowEvent* event)
{
QDialog::showEvent(event);
loadMessages();
if(shownFromPlotEdit == false)
loadNodes();
drawBitfield();
qDebug() << "S" << ui->gridData->geometry();
}
@@ -126,7 +128,9 @@ void NewGraphDialog::checkSignalAgreement()
if (dbcHandler == nullptr) return;
if (dbcHandler->getFileCount() == 0) return;
msg = dbcHandler->findMessage(ui->cbMessages->currentText());
QString fullyQualifiedNodeName = ui->cbNodes->itemText(ui->cbNodes->currentIndex());
QString msgName = ui->cbMessages->currentText();
msg = dbcHandler->findMessage(msgName, fullyQualifiedNodeName);
if (msg)
{
sig = msg->sigHandler->findSignalByName(ui->cbSignals->currentText());
@@ -149,13 +153,20 @@ void NewGraphDialog::checkSignalAgreement()
testingParams.startBit = startBit;
testingParams.numBits = dataLen;
if (testingParams.ID != msg->ID) bAgree = false;
if (fabs(testingParams.bias - sig->bias) > 0.01) bAgree = false;
if (testingParams.isSigned != sigSigned) bAgree = false;
if (testingParams.intelFormat != sig->intelByteOrder) bAgree = false;
if (fabs(testingParams.scale - sig->factor) > 0.01) bAgree = false;
if (testingParams.startBit != sig->startBit) bAgree = false;
if (testingParams.numBits != sig->signalSize) bAgree = false;
if (testingParams.ID != msg->ID)
bAgree = false;
if (fabs(testingParams.bias - sig->bias) > 0.01)
bAgree = false;
if (testingParams.isSigned != sigSigned)
bAgree = false;
if (testingParams.intelFormat != sig->intelByteOrder)
bAgree = false;
if (fabs(testingParams.scale - sig->factor) > 0.01)
bAgree = false;
if (testingParams.startBit != sig->startBit)
bAgree = false;
if (testingParams.numBits != sig->signalSize)
bAgree = false;
}
else
{
@@ -187,6 +198,8 @@ void NewGraphDialog::clearParams()
void NewGraphDialog::setParams(GraphParams &params)
{
shownFromPlotEdit = true;
ui->txtBias->setText(QString::number(params.bias));
ui->txtMask->setText(Utility::formatNumber(params.mask));
ui->txtScale->setText(QString::number(params.scale));
@@ -212,8 +225,59 @@ void NewGraphDialog::setParams(GraphParams &params)
assocSignal = params.associatedSignal;
loadMessages();
loadSignals(0);
loadNodes();
auto msg = assocSignal->parentMessage;
auto node = msg->sender;
bool nodeFound = false;
for(int i=0; i<ui->cbNodes->count(); i++)
{
if(ui->cbNodes->itemText(i) == node->sourceFileName + Utility::fullyQualifiedNameSeperator + node->name)
{
ui->cbNodes->setCurrentIndex(i);
nodeFound = true;
break;
}
}
qDebug() << "Matching plot params to Node: " << nodeFound;
if(nodeFound)
{
bool msgFound = false;
for(int i=0; i<ui->cbMessages->count(); i++)
{
if(ui->cbMessages->itemText(i) == msg->name)
{
ui->cbMessages->setCurrentIndex(i);
msgFound = true;
break;
}
}
qDebug() << "Matching plot params to Msg: " << msgFound;
if(msgFound)
{
bool sigFound = false;
for(int i=0; i<ui->cbSignals->count(); i++)
{
if(ui->cbSignals->itemText(i) == assocSignal->name)
{
ui->cbSignals->setCurrentIndex(i);
sigFound = true;
break;
}
}
qDebug() << "Matching plot params to Signal: " << sigFound;
}
}
//ui->cbNodes->model()->
//loadSignals(0);
drawBitfield();
checkSignalAgreement();
}
@@ -248,41 +312,85 @@ void NewGraphDialog::getParams(GraphParams &params)
if (params.stride < 1) params.stride = 1;
}
void NewGraphDialog::loadMessages()
void NewGraphDialog::loadNodes()
{
int numFiles;
ui->cbNodes->clear();
if (dbcHandler == nullptr) return;
if ((numFiles = dbcHandler->getFileCount()) == 0) return;
qDebug() << numFiles;
for (int f = 0; f < numFiles; f++)
{
DBCFile* thisFile = dbcHandler->getFileByIdx(f);
qDebug() << thisFile->messageHandler->getCount();
QList<QString> names;
for (int x = 0; x < thisFile->dbc_nodes.count(); x++)
{
bool messagesInNode = false;
for (int m = 0; m < thisFile->messageHandler->getCount(); m++)
{
if(thisFile->messageHandler->findMsgByIdx(m)->sender->name == thisFile->dbc_nodes[x].name)
{
messagesInNode = true;
break;
}
}
if(messagesInNode)
{
QString fullyQualifiedNodeName = thisFile->getFilenameNoExt() + Utility::fullyQualifiedNameSeperator + thisFile->dbc_nodes[x].name;
names.append(fullyQualifiedNodeName);
}
}
if(names.count() > 0)
{
names.sort();
ui->cbNodes->addItem("----" + thisFile->getFilename());
Utility::SetComboBoxItemEnabled(ui->cbNodes, ui->cbNodes->count() -1, false);
for(int i=0; i<names.count(); i++)
ui->cbNodes->addItem(names[i]);
}
}
}
void NewGraphDialog::loadMessages(int idx)
{
int numFiles = 0;
DBC_MESSAGE *msg;
ui->cbMessages->clear();
if (dbcHandler == nullptr) return;
if (dbcHandler->getFileCount() == 0) return;
for (int y = 0; y < dbcHandler->getFileCount(); y++)
if ((numFiles = dbcHandler->getFileCount()) == 0) return;
qDebug() << numFiles;
QString displayedNodeName = ui->cbNodes->itemText(idx);
for (int f = 0; f < numFiles; f++)
{
for (int x = 0; x < dbcHandler->getFileByIdx(y)->messageHandler->getCount(); x++)
qDebug() << dbcHandler->getFileByIdx(f)->messageHandler->getCount();
for (int x = 0; x < dbcHandler->getFileByIdx(f)->messageHandler->getCount(); x++)
{
msg = dbcHandler->getFileByIdx(y)->messageHandler->findMsgByIdx(x);
if (msg)
{
ui->cbMessages->addItem(msg->name);
if (assocSignal && msg->name == assocSignal->parentMessage->name)
{
ui->cbMessages->setCurrentIndex(ui->cbMessages->count() -1);
//qDebug() << "Found my parent";
}
}
QString fullyQualifiedNodeName = dbcHandler->getFileByIdx(f)->getFilenameNoExt() + Utility::fullyQualifiedNameSeperator + dbcHandler->getFileByIdx(f)->messageHandler->findMsgByIdx(x)->sender->name;
if(fullyQualifiedNodeName == displayedNodeName)
ui->cbMessages->addItem(dbcHandler->getFileByIdx(f)->messageHandler->findMsgByIdx(x)->name);
}
}
ui->cbMessages->model()->sort(0);
}
void NewGraphDialog::loadSignals(int idx)
{
Q_UNUSED(idx);
//search through all DBC files in order to try to find a message with the given name
DBC_MESSAGE *msg = dbcHandler->findMessage(ui->cbMessages->currentText());
DBC_SIGNAL *sig;
if (msg == nullptr) return;
ui->cbSignals->clear();
//search through all DBC files in order to try to find a message with the given name
QString fullyQualifiedNodeName = ui->cbNodes->itemText(ui->cbNodes->currentIndex());
DBC_MESSAGE *msg = dbcHandler->findMessage(ui->cbMessages->currentText(), fullyQualifiedNodeName);
if (msg == nullptr) return;
DBC_SIGNAL *sig;
for (int x = 0; x < msg->sigHandler->getCount(); x++)
{
sig = msg->sigHandler->findSignalByIdx(x);
@@ -366,11 +474,10 @@ void NewGraphDialog::copySignalToParamsUI()
assocSignal = nullptr;
DBC_MESSAGE *msg = nullptr;
for(int i = 0; i < dbcHandler->getFileCount(); i++)
{
msg = dbcHandler->getFileByIdx(i)->messageHandler->findMsgByName(ui->cbMessages->currentText());
if (msg) break;
}
QString fullyQualifiedNodeName = ui->cbNodes->itemText(ui->cbNodes->currentIndex());
QString msgName = ui->cbMessages->itemText(ui->cbMessages->currentIndex());
msg = dbcHandler->findMessage(msgName, fullyQualifiedNodeName);
if (!msg) return;
DBC_SIGNAL *sig = msg->sigHandler->findSignalByName(ui->cbSignals->currentText());
+3 -1
View File
@@ -25,7 +25,8 @@ private slots:
void addButtonClicked();
void colorSwatchClick();
void fillSwatchClick();
void loadMessages();
void loadNodes();
void loadMessages(int idx);
void loadSignals(int idx);
void bitfieldClicked(int);
void handleDataLenUpdate();
@@ -40,6 +41,7 @@ private:
DBCHandler *dbcHandler;
DBC_SIGNAL *assocSignal;
int startBit, dataLen;
bool shownFromPlotEdit;
};
#endif // NEWGRAPHDIALOG_H
+39 -30
View File
@@ -2,6 +2,7 @@
#include "ui_signalviewerwindow.h"
#include "helpwindow.h"
#include "mainwindow.h"
#include "utility.h"
#include <QDebug>
#define MSG_COL 1
@@ -40,6 +41,7 @@ SignalViewerWindow::SignalViewerWindow(const QVector<CANFrame> *frames, QWidget
verticalHeader->setFont(QFont());
dbcHandler = DBCHandler::getReference();
currentlySelectedMsg = nullptr;
connect(ui->cbNodes, SIGNAL(currentIndexChanged(int)), this, SLOT(loadMessages(int)));
connect(ui->cbMessages, SIGNAL(currentIndexChanged(int)), this, SLOT(loadSignals(int)));
@@ -118,18 +120,6 @@ void SignalViewerWindow::removeSelectedSignal()
ui->tableViewer->removeRow(selRow);
}
void SetComboBoxItemEnabled(QComboBox * comboBox, int index, bool enabled)
{
auto * model = qobject_cast<QStandardItemModel*>(comboBox->model());
assert(model);
if(!model) return;
auto * item = model->item(index);
assert(item);
if(!item) return;
item->setEnabled(enabled);
}
void SignalViewerWindow::loadNodes()
{
int numFiles;
@@ -139,22 +129,34 @@ void SignalViewerWindow::loadNodes()
qDebug() << numFiles;
for (int f = 0; f < numFiles; f++)
{
qDebug() << dbcHandler->getFileByIdx(f)->messageHandler->getCount();
DBCFile* thisFile = dbcHandler->getFileByIdx(f);
qDebug() << thisFile->messageHandler->getCount();
QList<QString> names;
for (int x = 0; x < dbcHandler->getFileByIdx(f)->dbc_nodes.count(); x++)
for (int x = 0; x < thisFile->dbc_nodes.count(); x++)
{
QString name = dbcHandler->getFileByIdx(f)->dbc_nodes[x].name;
if(name != "Vector__XXX")
names.append(name);
bool messagesInNode = false;
for (int m = 0; m < thisFile->messageHandler->getCount(); m++)
{
if(thisFile->messageHandler->findMsgByIdx(m)->sender->name == thisFile->dbc_nodes[x].name)
{
messagesInNode = true;
break;
}
}
if(messagesInNode)
{
QString fullyQualifiedNodeName = thisFile->getFilenameNoExt() + Utility::fullyQualifiedNameSeperator + thisFile->dbc_nodes[x].name;
names.append(fullyQualifiedNodeName);
}
}
if(names.count() > 0)
{
names.sort();
ui->cbNodes->addItem("----" + dbcHandler->getFileByIdx(f)->getFilename());
SetComboBoxItemEnabled(ui->cbNodes, ui->cbNodes->count() -1, false);
ui->cbNodes->addItem("----" + thisFile->getFilename());
Utility::SetComboBoxItemEnabled(ui->cbNodes, ui->cbNodes->count() -1, false);
for(int i=0; i<names.count(); i++)
ui->cbNodes->addItem(names[i]);
}
@@ -163,13 +165,13 @@ void SignalViewerWindow::loadNodes()
void SignalViewerWindow::loadMessages(int idx)
{
int numFiles;
int numFiles = 0;
ui->cbMessages->clear();
if (dbcHandler == nullptr) return;
if ((numFiles = dbcHandler->getFileCount()) == 0) return;
qDebug() << numFiles;
QString nodeName = ui->cbNodes->itemText(idx);
QString displayedNodeName = ui->cbNodes->itemText(idx);
for (int f = 0; f < numFiles; f++)
{
@@ -177,7 +179,8 @@ void SignalViewerWindow::loadMessages(int idx)
for (int x = 0; x < dbcHandler->getFileByIdx(f)->messageHandler->getCount(); x++)
{
if(dbcHandler->getFileByIdx(f)->messageHandler->findMsgByIdx(x)->sender->name == nodeName)
QString fullyQualifiedNodeName = dbcHandler->getFileByIdx(f)->getFilenameNoExt() + Utility::fullyQualifiedNameSeperator + dbcHandler->getFileByIdx(f)->messageHandler->findMsgByIdx(x)->sender->name;
if(fullyQualifiedNodeName == displayedNodeName)
ui->cbMessages->addItem(dbcHandler->getFileByIdx(f)->messageHandler->findMsgByIdx(x)->name);
}
}
@@ -186,14 +189,14 @@ void SignalViewerWindow::loadMessages(int idx)
void SignalViewerWindow::loadSignals(int idx)
{
Q_UNUSED(idx);
//messages were placed into the list in the same order as they exist
//in the data structure so it should have been possible to just
//look it up based on index but by name is probably safer and this operation
//is not time critical at all.
DBC_MESSAGE *msg = dbcHandler->findMessage(ui->cbMessages->currentText());
if (msg == nullptr) return;
ui->cbSignals->clear();
QString fullyQualifiedNodeName = ui->cbNodes->itemText(ui->cbNodes->currentIndex());
QString msgName = ui->cbMessages->itemText(ui->cbMessages->currentIndex());
DBC_MESSAGE *msg = dbcHandler->findMessage(msgName, fullyQualifiedNodeName);
if (msg == nullptr) return;
for (int x = 0; x < msg->sigHandler->getCount(); x++)
{
ui->cbSignals->addItem(msg->sigHandler->findSignalByIdx(x)->name);
@@ -202,7 +205,13 @@ void SignalViewerWindow::loadSignals(int idx)
void SignalViewerWindow::addSignal()
{
DBC_MESSAGE *msg = dbcHandler->findMessage(ui->cbMessages->currentText());
DBC_MESSAGE *msg = nullptr;
QString fullyQualifiedNodeName = ui->cbNodes->itemText(ui->cbNodes->currentIndex());
QString msgName = ui->cbMessages->itemText(ui->cbMessages->currentIndex());
msg = dbcHandler->findMessage(msgName, fullyQualifiedNodeName);
if (!msg) return;
DBC_SIGNAL *sig = msg->sigHandler->findSignalByName(ui->cbSignals->currentText());
if (!sig) return;
@@ -366,7 +375,7 @@ void SignalViewerWindow::loadDefinitions(bool append)
}
else
{
qDebug() << "Couldn't find the message by name! " << msgName << " " << sigName;
qDebug() << "Couldn't find the message by ID or name! " << msgName << " " << sigName;
}
}
}
+2
View File
@@ -36,6 +36,8 @@ private:
Ui::SignalViewerWindow *ui;
DBCHandler *dbcHandler;
DBC_MESSAGE *currentlySelectedMsg;
QList<DBC_SIGNAL *> signalList;
const QVector<CANFrame> *modelFrames;
+13
View File
@@ -277,6 +277,19 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_19">
<property name="text">
<string>Node:</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cbNodes"/>
</item>
<item>
<widget class="QLabel" name="label_9">
<property name="sizePolicy">
+1
View File
@@ -3,3 +3,4 @@
bool Utility::decimalMode = false;
QString Utility::timeFormat = "MMM-dd HH:mm:ss.zzz";
TimeStyle Utility::timeStyle = TS_MICROS;
QString Utility::fullyQualifiedNameSeperator = "::";
+16
View File
@@ -8,6 +8,8 @@
#include <QDebug>
#include <QApplication>
#include <QRect>
#include <QComboBox>
#include <QStandardItemModel>
//#include <QDesktopWidget>
enum TimeStyle
@@ -26,6 +28,20 @@ public:
static TimeStyle timeStyle;
static QString timeFormat;
static QString fullyQualifiedNameSeperator;
static void SetComboBoxItemEnabled(QComboBox * comboBox, int index, bool enabled)
{
auto * model = qobject_cast<QStandardItemModel*>(comboBox->model());
assert(model);
if(!model) return;
auto * item = model->item(index);
assert(item);
if(!item) return;
item->setEnabled(enabled);
}
//determines whether the window position is within any available screens. If it is not we default
//back to 0,0 which is going to be on screen. This fixes a problem where some operating systems would
//otherwise let you put windows on a second monitor, disconnect that monitor, and still put windows on it.