Merge pull request #210 from mjuhanne/master
DBC configuration saving, GMLAN 29bit Arbitration ID Matching, Filter labeling
This commit is contained in:
+4
-2
@@ -68,7 +68,8 @@ SOURCES += main.cpp\
|
||||
blfhandler.cpp \
|
||||
re/sniffer/SnifferDelegate.cpp \
|
||||
connections/newconnectiondialog.cpp \
|
||||
re/temporalgraphwindow.cpp
|
||||
re/temporalgraphwindow.cpp \
|
||||
filterutility.cpp
|
||||
|
||||
HEADERS += mainwindow.h \
|
||||
can_structs.h \
|
||||
@@ -127,7 +128,8 @@ HEADERS += mainwindow.h \
|
||||
blfhandler.h \
|
||||
re/sniffer/SnifferDelegate.h \
|
||||
connections/newconnectiondialog.h \
|
||||
re/temporalgraphwindow.h
|
||||
re/temporalgraphwindow.h \
|
||||
filterutility.h
|
||||
|
||||
FORMS += ui/candatagrid.ui \
|
||||
ui/connectionwindow.ui \
|
||||
|
||||
+6
-1
@@ -102,7 +102,7 @@ void CANFrameModel::setSysTimeMode(bool mode)
|
||||
}
|
||||
}
|
||||
|
||||
void CANFrameModel::setInterpetMode(bool mode)
|
||||
void CANFrameModel::setInterpretMode(bool mode)
|
||||
{
|
||||
//if the state of interpretFrames changes then we need to reset the model
|
||||
//so that QT will refresh the view properly
|
||||
@@ -114,6 +114,11 @@ void CANFrameModel::setInterpetMode(bool mode)
|
||||
}
|
||||
}
|
||||
|
||||
bool CANFrameModel::getInterpretMode()
|
||||
{
|
||||
return interpretFrames;
|
||||
}
|
||||
|
||||
void CANFrameModel::setTimeFormat(QString format)
|
||||
{
|
||||
Utility::timeFormat = format;
|
||||
|
||||
+2
-1
@@ -42,7 +42,8 @@ public:
|
||||
void sendRefresh(int);
|
||||
int sendBulkRefresh();
|
||||
void clearFrames();
|
||||
void setInterpetMode(bool);
|
||||
void setInterpretMode(bool);
|
||||
bool getInterpretMode();
|
||||
void setOverwriteMode(bool);
|
||||
void setHexMode(bool);
|
||||
void setSysTimeMode(bool);
|
||||
|
||||
+124
-19
@@ -87,7 +87,7 @@ DBC_MESSAGE* DBCMessageHandler::findMsgByID(uint32_t id)
|
||||
if (messages.count() == 0) return nullptr;
|
||||
for (int i = 0; i < messages.count(); i++)
|
||||
{
|
||||
if (isJ1939Handler)
|
||||
if (matchingCriteria == J1939)
|
||||
{
|
||||
// include data page and extended data page in the pgn
|
||||
uint32_t pgn = (id & 0x3FFFF00) >> 8;
|
||||
@@ -109,6 +109,13 @@ DBC_MESSAGE* DBCMessageHandler::findMsgByID(uint32_t id)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (matchingCriteria == GMLAN)
|
||||
{
|
||||
// Match the bits 14-26 (Arbitration Id) of GMLAN 29bit header
|
||||
uint32_t arbId = id &0x3FFE000;
|
||||
if ( (arbId != 0) && (messages[i].ID & 0x3FFE000) == arbId )
|
||||
return &messages[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( messages[i].ID == id )
|
||||
@@ -203,20 +210,31 @@ int DBCMessageHandler::getCount()
|
||||
return messages.count();
|
||||
}
|
||||
|
||||
bool DBCMessageHandler::isJ1939()
|
||||
bool DBCMessageHandler::filterLabeling()
|
||||
{
|
||||
return isJ1939Handler;
|
||||
return filterLabelingEnabled;
|
||||
}
|
||||
|
||||
void DBCMessageHandler::setJ1939(bool j1939)
|
||||
void DBCMessageHandler::setFilterLabeling(bool filterLabeling)
|
||||
{
|
||||
isJ1939Handler = j1939;
|
||||
filterLabelingEnabled = filterLabeling;
|
||||
}
|
||||
|
||||
MatchingCriteria_t DBCMessageHandler::getMatchingCriteria()
|
||||
{
|
||||
return matchingCriteria;
|
||||
}
|
||||
|
||||
void DBCMessageHandler::setMatchingCriteria(MatchingCriteria_t _matchingCriteria)
|
||||
{
|
||||
matchingCriteria = _matchingCriteria;
|
||||
}
|
||||
|
||||
DBCFile::DBCFile()
|
||||
{
|
||||
messageHandler = new DBCMessageHandler;
|
||||
messageHandler->setJ1939(false);
|
||||
messageHandler->setMatchingCriteria(EXACT);
|
||||
messageHandler->setFilterLabeling(false);
|
||||
}
|
||||
|
||||
DBCFile::DBCFile(const DBCFile& cpy) : QObject()
|
||||
@@ -225,7 +243,8 @@ DBCFile::DBCFile(const DBCFile& cpy) : QObject()
|
||||
for (int i = 0 ; i < cpy.messageHandler->getCount() ; i++)
|
||||
messageHandler->addMessage(*cpy.messageHandler->findMsgByIdx(i));
|
||||
|
||||
messageHandler->setJ1939(cpy.messageHandler->isJ1939());
|
||||
messageHandler->setMatchingCriteria(cpy.messageHandler->getMatchingCriteria());
|
||||
messageHandler->setFilterLabeling(cpy.messageHandler->filterLabeling());
|
||||
fileName = cpy.fileName;
|
||||
filePath = cpy.filePath;
|
||||
assocBuses = cpy.assocBuses;
|
||||
@@ -293,9 +312,10 @@ int DBCFile::getAssocBus()
|
||||
|
||||
void DBCFile::setAssocBus(int bus)
|
||||
{
|
||||
int numBuses = CANConManager::getInstance()->getNumBuses();
|
||||
if (bus < -1) return;
|
||||
if (bus >= numBuses) return;
|
||||
// To allow setting bus numbers even before connection is configured, do not enforce "valid" bus numbers
|
||||
//int numBuses = CANConManager::getInstance()->getNumBuses();
|
||||
//if (bus >= numBuses) return;
|
||||
assocBuses = bus;
|
||||
}
|
||||
|
||||
@@ -690,7 +710,8 @@ void DBCFile::loadFile(QString fileName)
|
||||
qDebug() << "Starting DBC load";
|
||||
dbc_nodes.clear();
|
||||
messageHandler->removeAllMessages();
|
||||
messageHandler->setJ1939(false);
|
||||
messageHandler->setMatchingCriteria(EXACT);
|
||||
messageHandler->setFilterLabeling(false);
|
||||
|
||||
DBC_NODE falseNode;
|
||||
falseNode.name = "Vector__XXX";
|
||||
@@ -884,14 +905,24 @@ void DBCFile::loadFile(QString fileName)
|
||||
fgAttr = findAttributeByName("GenMsgForegroundColor");
|
||||
}
|
||||
|
||||
DBC_ATTRIBUTE *j1939attr = findAttributeByName("isj1939dbc");
|
||||
if (j1939attr)
|
||||
DBC_ATTRIBUTE *mc_attr = findAttributeByName("matchingcriteria");
|
||||
if (mc_attr)
|
||||
{
|
||||
messageHandler->setJ1939(j1939attr->defaultValue > 0);
|
||||
messageHandler->setMatchingCriteria((MatchingCriteria_t)mc_attr->defaultValue.toInt());
|
||||
}
|
||||
else
|
||||
{
|
||||
messageHandler->setJ1939(false);
|
||||
messageHandler->setMatchingCriteria(EXACT);
|
||||
}
|
||||
|
||||
DBC_ATTRIBUTE *fl_attr = findAttributeByName("filterlabeling");
|
||||
if (fl_attr)
|
||||
{
|
||||
messageHandler->setFilterLabeling(fl_attr->defaultValue.toInt());
|
||||
}
|
||||
else
|
||||
{
|
||||
messageHandler->setFilterLabeling(false);
|
||||
}
|
||||
|
||||
QColor DefaultBG = QColor(bgAttr->defaultValue.toString());
|
||||
@@ -1397,7 +1428,16 @@ int DBCHandler::createBlankFile()
|
||||
attr.enumVals.clear();
|
||||
attr.lower = 0;
|
||||
attr.upper = 0;
|
||||
attr.name = "isj1939dbc";
|
||||
attr.name = "matchingcriteria";
|
||||
attr.valType = QINT;
|
||||
newFile.dbc_attributes.append(attr);
|
||||
|
||||
attr.attrType = MESSAGE;
|
||||
attr.defaultValue = 0;
|
||||
attr.enumVals.clear();
|
||||
attr.lower = 0;
|
||||
attr.upper = 0;
|
||||
attr.name = "filterlabeling";
|
||||
attr.valType = QINT;
|
||||
newFile.dbc_attributes.append(attr);
|
||||
|
||||
@@ -1405,6 +1445,14 @@ int DBCHandler::createBlankFile()
|
||||
return loadedFiles.count();
|
||||
}
|
||||
|
||||
DBCFile* DBCHandler::loadDBCFile(QString filename)
|
||||
{
|
||||
DBCFile newFile;
|
||||
newFile.loadFile(filename);
|
||||
loadedFiles.append(newFile);
|
||||
return &loadedFiles.last();
|
||||
}
|
||||
|
||||
//the only reason to even bother sending the index is to see if
|
||||
//the user wants to replace an already loaded DBC.
|
||||
//Otherwise add a new one. Well, always add a new one.
|
||||
@@ -1430,11 +1478,8 @@ DBCFile* DBCHandler::loadDBCFile(int idx)
|
||||
{
|
||||
filename = dialog.selectedFiles()[0];
|
||||
//right now there is only one file type that can be loaded here so just do it.
|
||||
DBCFile newFile;
|
||||
newFile.loadFile(filename);
|
||||
loadedFiles.append(newFile);
|
||||
settings.setValue("DBC/LoadSaveDirectory", dialog.directory().path());
|
||||
return &loadedFiles.last();
|
||||
return loadDBCFile(filename);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
@@ -1483,6 +1528,29 @@ DBC_MESSAGE* DBCHandler::findMessage(const CANFrame &frame)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
// This function won't care which bus the DBC file is associated, but will return any message as long as ID matches and the file
|
||||
// has filter labeling enabled.
|
||||
// Returns the found message as well as the matching criteria (exact/J1939/GMLAN)
|
||||
// Used for quickly populating the Frame Filtering section with interpreted values
|
||||
DBC_MESSAGE* DBCHandler::findMessageForFilter(uint32_t id, MatchingCriteria_t * matchingCriteria)
|
||||
{
|
||||
for(int i = 0; i < loadedFiles.count(); i++)
|
||||
{
|
||||
if (loadedFiles[i].messageHandler->filterLabeling())
|
||||
{
|
||||
DBC_MESSAGE* msg = loadedFiles[i].messageHandler->findMsgByID(id);
|
||||
if (msg != nullptr)
|
||||
{
|
||||
*matchingCriteria = loadedFiles[i].messageHandler->getMatchingCriteria();
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* As above, a real shortcut function that searches all files in order to try to find a message with the given name
|
||||
*/
|
||||
@@ -1526,7 +1594,44 @@ DBCFile* DBCHandler::getFileByName(QString name)
|
||||
|
||||
DBCHandler::DBCHandler()
|
||||
{
|
||||
// Load previously saved DBC file settings
|
||||
QSettings settings;
|
||||
int filecount = settings.value("DBC/FileCount", 0).toInt();
|
||||
for (int i=0; i<filecount; i++)
|
||||
{
|
||||
QString filename = settings.value("DBC/Filename_" + QString(i),"").toString();
|
||||
DBCFile * file = loadDBCFile(filename);
|
||||
int bus = settings.value("DBC/AssocBus_" + QString(i),0).toInt();
|
||||
file->setAssocBus(bus);
|
||||
|
||||
MatchingCriteria_t matchingCriteria = (MatchingCriteria_t)settings.value("DBC/MatchingCriteria_" + QString(i),0).toInt();
|
||||
|
||||
DBC_ATTRIBUTE attr;
|
||||
|
||||
attr.attrType = MESSAGE;
|
||||
attr.defaultValue = matchingCriteria;
|
||||
attr.enumVals.clear();
|
||||
attr.lower = 0;
|
||||
attr.upper = 0;
|
||||
attr.name = "matchingcriteria";
|
||||
attr.valType = QINT;
|
||||
file->dbc_attributes.append(attr);
|
||||
file->messageHandler->setMatchingCriteria(matchingCriteria);
|
||||
|
||||
bool filterLabeling = settings.value("DBC/FilterLabeling_" + QString(i),0).toBool();
|
||||
attr.attrType = MESSAGE;
|
||||
attr.defaultValue = filterLabeling;
|
||||
attr.enumVals.clear();
|
||||
attr.lower = 0;
|
||||
attr.upper = 0;
|
||||
attr.name = "filterlabeling";
|
||||
attr.valType = QINT;
|
||||
file->dbc_attributes.append(attr);
|
||||
file->messageHandler->setFilterLabeling(filterLabeling);
|
||||
|
||||
qInfo() << "Loaded DBC file" << filename << " (bus:" << bus
|
||||
<< ", Matching Criteria:" << (int)matchingCriteria << "Filter labeling: " << (filterLabeling?"enabled":"disabled") << ")";
|
||||
}
|
||||
}
|
||||
|
||||
DBCHandler* DBCHandler::getReference()
|
||||
|
||||
+15
-3
@@ -5,6 +5,13 @@
|
||||
#include "dbc_classes.h"
|
||||
#include "can_structs.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EXACT,
|
||||
J1939,
|
||||
GMLAN
|
||||
} MatchingCriteria_t;
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* Finish coding up the decoupled design
|
||||
@@ -40,11 +47,14 @@ public:
|
||||
bool removeMessage(QString name);
|
||||
void removeAllMessages();
|
||||
int getCount();
|
||||
bool isJ1939();
|
||||
void setJ1939(bool j1939);
|
||||
MatchingCriteria_t getMatchingCriteria();
|
||||
void setMatchingCriteria(MatchingCriteria_t mc);
|
||||
void setFilterLabeling( bool labelFiltering );
|
||||
bool filterLabeling();
|
||||
private:
|
||||
QList<DBC_MESSAGE> messages;
|
||||
bool isJ1939Handler;
|
||||
MatchingCriteria_t matchingCriteria;
|
||||
bool filterLabelingEnabled;
|
||||
};
|
||||
|
||||
//technically there should be a node handler too but I'm sort of treating nodes as second class
|
||||
@@ -90,6 +100,7 @@ class DBCHandler: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DBCFile* loadDBCFile(QString filename);
|
||||
DBCFile* loadDBCFile(int);
|
||||
void saveDBCFile(int);
|
||||
void removeDBCFile(int);
|
||||
@@ -97,6 +108,7 @@ public:
|
||||
void swapFiles(int pos1, int pos2);
|
||||
DBC_MESSAGE* findMessage(const CANFrame &frame);
|
||||
DBC_MESSAGE* findMessage(const QString msgName);
|
||||
DBC_MESSAGE* findMessageForFilter(uint32_t id, MatchingCriteria_t * matchingCriteria);
|
||||
int getFileCount();
|
||||
DBCFile* getFileByIdx(int idx);
|
||||
DBCFile* getFileByName(QString name);
|
||||
|
||||
+140
-20
@@ -1,6 +1,6 @@
|
||||
#include "dbcloadsavewindow.h"
|
||||
#include "ui_dbcloadsavewindow.h"
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include "helpwindow.h"
|
||||
#include "connections/canconmanager.h"
|
||||
|
||||
@@ -18,14 +18,44 @@ DBCLoadSaveWindow::DBCLoadSaveWindow(const QVector<CANFrame> *frames, QWidget *p
|
||||
inhibitCellProcessing = false;
|
||||
|
||||
QStringList header;
|
||||
header << "Filename" << "Associated Bus" << "J1939";
|
||||
ui->tableFiles->setColumnCount(3);
|
||||
header << "Filename" << "Associated Bus" << "Matching criteria" << "Label filters";
|
||||
ui->tableFiles->setColumnCount(4);
|
||||
ui->tableFiles->setHorizontalHeaderLabels(header);
|
||||
ui->tableFiles->setColumnWidth(0, 265);
|
||||
ui->tableFiles->setColumnWidth(1, 125);
|
||||
ui->tableFiles->setColumnWidth(2, 80);
|
||||
ui->tableFiles->setColumnWidth(2, 120);
|
||||
ui->tableFiles->setColumnWidth(3, 90);
|
||||
ui->tableFiles->horizontalHeader()->setStretchLastSection(true);
|
||||
|
||||
// Populate table
|
||||
for (int idx=0; idx<dbcHandler->getFileCount(); idx++)
|
||||
{
|
||||
DBCFile * file = dbcHandler->getFileByIdx(idx);
|
||||
ui->tableFiles->insertRow(ui->tableFiles->rowCount());
|
||||
ui->tableFiles->setItem(idx, 0, new QTableWidgetItem(file->getFullFilename()));
|
||||
QString bus = QString::number(file->getAssocBus() );
|
||||
ui->tableFiles->setItem(idx, 1, new QTableWidgetItem(bus));
|
||||
|
||||
QComboBox * mc_item = addMatchingCriteriaCombobox(idx);
|
||||
int mc = (int)file->messageHandler->getMatchingCriteria();
|
||||
mc_item->setCurrentIndex(mc);
|
||||
|
||||
QTableWidgetItem *item = new QTableWidgetItem("");
|
||||
ui->tableFiles->setItem(idx, 3, item);
|
||||
bool filterLabeling = file->messageHandler->filterLabeling();
|
||||
if (filterLabeling)
|
||||
{
|
||||
item->setCheckState(Qt::Checked);
|
||||
}
|
||||
else
|
||||
{
|
||||
item->setCheckState(Qt::Unchecked);
|
||||
}
|
||||
|
||||
qDebug() << "Populate DBC table:" << file->getFullFilename() << " (bus:" << bus << " - Matching Criteria:" << mc
|
||||
<< "Filter labeling: " << (filterLabeling?"enabled":"disabled") << ")";
|
||||
}
|
||||
|
||||
connect(ui->btnEdit, &QAbstractButton::clicked, this, &DBCLoadSaveWindow::editFile);
|
||||
connect(ui->btnLoad, &QAbstractButton::clicked, this, &DBCLoadSaveWindow::loadFile);
|
||||
connect(ui->btnMoveDown, &QAbstractButton::clicked, this, &DBCLoadSaveWindow::moveDown);
|
||||
@@ -42,12 +72,42 @@ DBCLoadSaveWindow::DBCLoadSaveWindow(const QVector<CANFrame> *frames, QWidget *p
|
||||
installEventFilter(this);
|
||||
}
|
||||
|
||||
QComboBox * DBCLoadSaveWindow::addMatchingCriteriaCombobox(int row)
|
||||
{
|
||||
QComboBox *item = new QComboBox();
|
||||
item->addItem("Exact");
|
||||
item->addItem("J1939");
|
||||
item->addItem("GMLAN");
|
||||
ui->tableFiles->setCellWidget(row, 2, item);
|
||||
connect(item, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||
[this](int box_idx) { matchingCriteriaChanged(box_idx); } );
|
||||
return item;
|
||||
}
|
||||
|
||||
DBCLoadSaveWindow::~DBCLoadSaveWindow()
|
||||
{
|
||||
removeEventFilter(this);
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void DBCLoadSaveWindow::updateSettings()
|
||||
{
|
||||
QSettings settings;
|
||||
int filecount = ui->tableFiles->rowCount();
|
||||
settings.setValue("DBC/FileCount", filecount);
|
||||
for (int i=0; i<filecount; i++)
|
||||
{
|
||||
DBCFile * file = dbcHandler->getFileByIdx(i);
|
||||
if (file)
|
||||
{
|
||||
settings.setValue("DBC/Filename_" + QString(i), file->getFullFilename());
|
||||
settings.setValue("DBC/AssocBus_" + QString(i), file->getAssocBus());
|
||||
settings.setValue("DBC/MatchingCriteria_" + QString(i), file->messageHandler->getMatchingCriteria());
|
||||
settings.setValue("DBC/FilterLabeling_" + QString(i), file->messageHandler->filterLabeling());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool DBCLoadSaveWindow::eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::KeyRelease) {
|
||||
@@ -74,9 +134,12 @@ void DBCLoadSaveWindow::newFile()
|
||||
ui->tableFiles->setItem(idx, 0, new QTableWidgetItem("UNNAMEDFILE"));
|
||||
ui->tableFiles->setItem(idx, 1, new QTableWidgetItem("-1"));
|
||||
|
||||
QComboBox * mc_item = addMatchingCriteriaCombobox(idx);
|
||||
mc_item->setCurrentIndex(EXACT);
|
||||
|
||||
QTableWidgetItem *item = new QTableWidgetItem("");
|
||||
item->setCheckState(Qt::Unchecked);
|
||||
ui->tableFiles->setItem(idx, 2, item);
|
||||
item->setCheckState(Qt::Checked);
|
||||
ui->tableFiles->setItem(idx, 3, item);
|
||||
}
|
||||
|
||||
void DBCLoadSaveWindow::loadFile()
|
||||
@@ -87,9 +150,17 @@ void DBCLoadSaveWindow::loadFile()
|
||||
ui->tableFiles->insertRow(ui->tableFiles->rowCount());
|
||||
ui->tableFiles->setItem(idx, 0, new QTableWidgetItem(file->getFullFilename()));
|
||||
ui->tableFiles->setItem(idx, 1, new QTableWidgetItem("-1"));
|
||||
DBC_ATTRIBUTE *attr = file->findAttributeByName("isj1939dbc");
|
||||
|
||||
DBC_ATTRIBUTE *attr = file->findAttributeByName("matchingcriteria");
|
||||
QComboBox * mc_item = addMatchingCriteriaCombobox(idx);
|
||||
if (attr && attr->defaultValue > 0)
|
||||
{
|
||||
mc_item->setCurrentIndex(attr->defaultValue.toInt());
|
||||
}
|
||||
|
||||
attr = file->findAttributeByName("filterlabeling");
|
||||
QTableWidgetItem *item = new QTableWidgetItem("");
|
||||
ui->tableFiles->setItem(idx, 2, item);
|
||||
ui->tableFiles->setItem(idx, 3, item);
|
||||
if (attr && attr->defaultValue > 0)
|
||||
{
|
||||
item->setCheckState(Qt::Checked);
|
||||
@@ -98,6 +169,8 @@ void DBCLoadSaveWindow::loadFile()
|
||||
{
|
||||
item->setCheckState(Qt::Unchecked);
|
||||
}
|
||||
|
||||
updateSettings();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,6 +204,7 @@ void DBCLoadSaveWindow::removeFile()
|
||||
dbcHandler->removeDBCFile(idx);
|
||||
ui->tableFiles->removeRow(idx);
|
||||
}
|
||||
updateSettings();
|
||||
}
|
||||
|
||||
void DBCLoadSaveWindow::moveUp()
|
||||
@@ -139,6 +213,7 @@ void DBCLoadSaveWindow::moveUp()
|
||||
if (idx < 1) return;
|
||||
dbcHandler->swapFiles(idx - 1, idx);
|
||||
swapTableRows(true);
|
||||
updateSettings();
|
||||
}
|
||||
|
||||
void DBCLoadSaveWindow::moveDown()
|
||||
@@ -148,6 +223,7 @@ void DBCLoadSaveWindow::moveDown()
|
||||
if (idx > (dbcHandler->getFileCount() - 2)) return;
|
||||
dbcHandler->swapFiles(idx, idx + 1);
|
||||
swapTableRows(false);
|
||||
updateSettings();
|
||||
}
|
||||
|
||||
void DBCLoadSaveWindow::editFile()
|
||||
@@ -159,6 +235,42 @@ void DBCLoadSaveWindow::editFile()
|
||||
editorWindow->show();
|
||||
}
|
||||
|
||||
void DBCLoadSaveWindow::matchingCriteriaChanged(int index)
|
||||
{
|
||||
// We don't know which combobox changed, so we just update all of them
|
||||
for (int row=0; row<ui->tableFiles->rowCount(); row++)
|
||||
{
|
||||
DBCFile *file = dbcHandler->getFileByIdx(row);
|
||||
if (file)
|
||||
{
|
||||
QComboBox *item = (QComboBox*)ui->tableFiles->cellWidget(row, 2);
|
||||
MatchingCriteria_t matchingCriteria = (MatchingCriteria_t) item->currentIndex();
|
||||
DBC_ATTRIBUTE *attr = file->findAttributeByName("matchingcriteria");
|
||||
if (attr)
|
||||
{
|
||||
attr->defaultValue = matchingCriteria;
|
||||
file->messageHandler->setMatchingCriteria(matchingCriteria);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBC_ATTRIBUTE attr;
|
||||
|
||||
attr.attrType = MESSAGE;
|
||||
attr.defaultValue = matchingCriteria;
|
||||
attr.enumVals.clear();
|
||||
attr.lower = 0;
|
||||
attr.upper = 0;
|
||||
attr.name = "matchingcriteria";
|
||||
attr.valType = QINT;
|
||||
file->dbc_attributes.append(attr);
|
||||
file->messageHandler->setMatchingCriteria(matchingCriteria);
|
||||
}
|
||||
}
|
||||
}
|
||||
updateSettings();
|
||||
}
|
||||
|
||||
|
||||
void DBCLoadSaveWindow::cellChanged(int row, int col)
|
||||
{
|
||||
if (inhibitCellProcessing) return;
|
||||
@@ -167,39 +279,40 @@ void DBCLoadSaveWindow::cellChanged(int row, int col)
|
||||
DBCFile *file = dbcHandler->getFileByIdx(row);
|
||||
int bus = ui->tableFiles->item(row, col)->text().toInt();
|
||||
int numBuses = CANConManager::getInstance()->getNumBuses();
|
||||
if (bus > -2 && bus < numBuses)
|
||||
if (bus > -2)
|
||||
{
|
||||
file->setAssocBus(bus);
|
||||
}
|
||||
}
|
||||
else if (col == 2)
|
||||
updateSettings();
|
||||
}
|
||||
else if (col == 3) // labelfilters
|
||||
{
|
||||
DBCFile *file = dbcHandler->getFileByIdx(row);
|
||||
if (file)
|
||||
{
|
||||
//int isj1939dbc = ui->tableFiles->item(row, col)->text().toInt();
|
||||
bool isj1939dbc = ui->tableFiles->item(row, col)->checkState() == Qt::Checked;
|
||||
DBC_ATTRIBUTE *attr = file->findAttributeByName("isj1939dbc");
|
||||
bool labelFilters = ui->tableFiles->item(row, col)->checkState() == Qt::Checked;
|
||||
DBC_ATTRIBUTE *attr = file->findAttributeByName("filterlabeling");
|
||||
if (attr)
|
||||
{
|
||||
attr->defaultValue = isj1939dbc ? 1 : 0;
|
||||
file->messageHandler->setJ1939(isj1939dbc);
|
||||
attr->defaultValue = labelFilters ? 1 : 0;
|
||||
file->messageHandler->setFilterLabeling(labelFilters);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBC_ATTRIBUTE attr;
|
||||
|
||||
attr.attrType = MESSAGE;
|
||||
attr.defaultValue = isj1939dbc ? 1 : 0;
|
||||
attr.defaultValue = labelFilters ? 1 : 0;
|
||||
attr.enumVals.clear();
|
||||
attr.lower = 0;
|
||||
attr.upper = 0;
|
||||
attr.name = "isj1939dbc";
|
||||
attr.name = "labelfilters";
|
||||
attr.valType = QINT;
|
||||
file->dbc_attributes.append(attr);
|
||||
file->messageHandler->setJ1939(isj1939dbc);
|
||||
file->messageHandler->setFilterLabeling(labelFilters);
|
||||
}
|
||||
}
|
||||
updateSettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,10 +335,17 @@ void DBCLoadSaveWindow::swapTableRows(bool up)
|
||||
QList<QTableWidgetItem*> sourceItems = takeRow(idx);
|
||||
QList<QTableWidgetItem*> destItems = takeRow(destIdx);
|
||||
|
||||
// QCombobox needs separate handling
|
||||
int sourceMC = ((QComboBox*)ui->tableFiles->cellWidget(idx,2))->currentIndex();
|
||||
int destMC = ((QComboBox*)ui->tableFiles->cellWidget(destIdx,2))->currentIndex();
|
||||
|
||||
// set back in reverse order
|
||||
setRow(idx, destItems);
|
||||
setRow(destIdx, sourceItems);
|
||||
|
||||
((QComboBox*)ui->tableFiles->cellWidget(idx,2))->setCurrentIndex(destMC);
|
||||
((QComboBox*)ui->tableFiles->cellWidget(destIdx,2))->setCurrentIndex(sourceMC);
|
||||
|
||||
inhibitCellProcessing = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <QDialog>
|
||||
#include <QTableWidget>
|
||||
#include <QComboBox>
|
||||
#include "dbchandler.h"
|
||||
#include "dbcmaineditor.h"
|
||||
|
||||
@@ -27,6 +28,7 @@ private slots:
|
||||
void editFile();
|
||||
void cellChanged(int row, int col);
|
||||
void cellDoubleClicked(int row, int col);
|
||||
void matchingCriteriaChanged(int index);
|
||||
void newFile();
|
||||
|
||||
private:
|
||||
@@ -41,6 +43,8 @@ private:
|
||||
QList<QTableWidgetItem*> takeRow(int row);
|
||||
void setRow(int row, const QList<QTableWidgetItem*>& rowItems);
|
||||
bool eventFilter(QObject *obj, QEvent *event);
|
||||
void updateSettings();
|
||||
QComboBox * addMatchingCriteriaCombobox(int row);
|
||||
};
|
||||
|
||||
#endif // DBCLOADSAVEWINDOW_H
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
#include "utility.h"
|
||||
#include "filterutility.h"
|
||||
#include "dbc/dbchandler.h"
|
||||
#include <QSettings>
|
||||
|
||||
uint32_t FilterUtility::getIdAsInt( QListWidgetItem * item )
|
||||
{
|
||||
return Utility::ParseStringToNum(getId(item));
|
||||
}
|
||||
|
||||
QString FilterUtility::getId( QString itemText )
|
||||
{
|
||||
if (itemText.contains(" "))
|
||||
// Strip away the filter label
|
||||
return itemText.left(itemText.indexOf(" "));
|
||||
else
|
||||
return itemText;
|
||||
}
|
||||
|
||||
QString FilterUtility::getId( QListWidgetItem * item )
|
||||
{
|
||||
return getId(item->text());
|
||||
}
|
||||
|
||||
uint32_t FilterUtility::getGMLanArbitrationId(uint32_t id)
|
||||
{
|
||||
return (id >> 13) & 0x1FFF;
|
||||
}
|
||||
|
||||
uint32_t FilterUtility::getGMLanPriorityBits(uint32_t id)
|
||||
{
|
||||
return (id >> 26) & 0x7;
|
||||
}
|
||||
|
||||
uint32_t FilterUtility::getGMLanSenderId(uint32_t id)
|
||||
{
|
||||
return id & 0x1FFF;
|
||||
}
|
||||
|
||||
QListWidgetItem * FilterUtility::createCheckableFilterItem(uint32_t id, bool checked, QListWidget* parent)
|
||||
{
|
||||
QListWidgetItem * thisItem = createFilterItem(id,parent);
|
||||
thisItem->setFlags(thisItem->flags() | Qt::ItemIsUserCheckable);
|
||||
if (checked)
|
||||
thisItem->setCheckState(Qt::Checked);
|
||||
else
|
||||
thisItem->setCheckState(Qt::Unchecked);
|
||||
return thisItem;
|
||||
}
|
||||
|
||||
QListWidgetItem * FilterUtility::createFilterItem(uint32_t id, QListWidget* parent)
|
||||
{
|
||||
QSettings settings;
|
||||
DBCHandler * dbcHandler = DBCHandler::getReference();
|
||||
QListWidgetItem *thisItem = new QListWidgetItem(parent);
|
||||
QString filterItemName = Utility::formatCANID(id);
|
||||
|
||||
if (settings.value("Main/FilterLabeling", false).toBool())
|
||||
{
|
||||
// Filter labeling (show interpreted frame names next to the CAN addr ID)
|
||||
MatchingCriteria_t matchingCriteria;
|
||||
DBC_MESSAGE *msg = dbcHandler->findMessageForFilter(id,&matchingCriteria);
|
||||
if (msg != NULL)
|
||||
{
|
||||
filterItemName.append(" ");
|
||||
filterItemName.append(msg->name);
|
||||
|
||||
// Create tooltip to show the whole name just in case it's too long to fit in the filter window.
|
||||
// Also if the matching criteria is set to GMLAN, show the Arbitration ID as well
|
||||
QString tooltip;
|
||||
if (matchingCriteria == GMLAN)
|
||||
tooltip.append("0x" + QString::number(FilterUtility::getGMLanArbitrationId(id), 16).toUpper().rightJustified(4,'0') + ": ");
|
||||
tooltip.append(msg->name);
|
||||
thisItem->setToolTip(tooltip);
|
||||
}
|
||||
}
|
||||
|
||||
thisItem->setText(filterItemName);
|
||||
return thisItem;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef FILTERUTILITY_H
|
||||
#define FILTERUTILITY_H
|
||||
|
||||
#include <QListWidget>
|
||||
|
||||
|
||||
class FilterUtility
|
||||
{
|
||||
|
||||
public:
|
||||
static QListWidgetItem * createFilterItem(uint32_t id, QListWidget* parent=NULL); // if parent is given, add item automatically to listwidget
|
||||
static QListWidgetItem * createCheckableFilterItem(uint32_t id, bool checked, QListWidget* parent=NULL);
|
||||
|
||||
static uint32_t getIdAsInt( QListWidgetItem * item );
|
||||
static QString getId( QListWidgetItem * item );
|
||||
static QString getId( QString itemText );
|
||||
|
||||
static uint32_t getGMLanArbitrationId(uint32_t id);
|
||||
static uint32_t getGMLanSenderId(uint32_t id);
|
||||
static uint32_t getGMLanPriorityBits(uint32_t id);
|
||||
};
|
||||
|
||||
#endif // DBCLOADSAVEWINDOW_H
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <QSettings>
|
||||
#include "connections/canconmanager.h"
|
||||
#include "helpwindow.h"
|
||||
#include "filterutility.h"
|
||||
|
||||
/*
|
||||
* Notes about new functionality:
|
||||
@@ -78,6 +79,9 @@ FramePlaybackWindow::FramePlaybackWindow(const QVector<CANFrame> *frames, QWidge
|
||||
|
||||
playbackObject.setPlaybackInterval(ui->spinPlaySpeed->value());
|
||||
|
||||
// Prevent annoying accidental horizontal scrolling when filter list is populated with long interpreted message names
|
||||
ui->listID->horizontalScrollBar()->setEnabled(false);
|
||||
|
||||
QStringList headers;
|
||||
headers << "Source" << "Loops";
|
||||
ui->tblSequence->setColumnCount(2);
|
||||
@@ -197,7 +201,7 @@ void FramePlaybackWindow::saveFilters()
|
||||
|
||||
for (int c = 0; c < ui->listID->count(); c++)
|
||||
{
|
||||
outFile->write(QString::number(ui->listID->item(c)->text().toInt(nullptr, 16), 16).toUtf8());
|
||||
outFile->write(QString::number(FilterUtility::getId(ui->listID->item(c)).toInt(nullptr, 16), 16).toUtf8());
|
||||
outFile->putChar(',');
|
||||
if (ui->listID->item(c)->checkState() == Qt::Checked) outFile->putChar('T');
|
||||
else outFile->putChar('F');
|
||||
@@ -260,7 +264,7 @@ void FramePlaybackWindow::loadFilters()
|
||||
for (int c = 0; c < ui->listID->count(); c++)
|
||||
{
|
||||
QListWidgetItem *item = ui->listID->item(c);
|
||||
if (item->text().toInt(nullptr, 16) == ID)
|
||||
if (FilterUtility::getId(item).toInt(nullptr, 16) == ID)
|
||||
{
|
||||
item->setCheckState(Qt::Checked);
|
||||
}
|
||||
@@ -291,10 +295,7 @@ void FramePlaybackWindow::refreshIDList()
|
||||
QHash<int, bool>::Iterator filterIter;
|
||||
for (filterIter = currentSeqItem->idFilters.begin(); filterIter != currentSeqItem->idFilters.end(); ++filterIter)
|
||||
{
|
||||
QListWidgetItem* listItem = new QListWidgetItem(Utility::formatCANID(filterIter.key()), ui->listID);
|
||||
listItem->setFlags(listItem->flags() | Qt::ItemIsUserCheckable); // set checkable flag
|
||||
if (filterIter.value()) listItem->setCheckState(Qt::Checked);
|
||||
else listItem->setCheckState(Qt::Unchecked);
|
||||
QListWidgetItem* listItem = FilterUtility::createCheckableFilterItem(filterIter.key(), filterIter.value(), ui->listID);
|
||||
}
|
||||
//default is to sort in ascending order
|
||||
ui->listID->sortItems();
|
||||
@@ -611,7 +612,7 @@ void FramePlaybackWindow::changeSendingBus(int newIdx)
|
||||
void FramePlaybackWindow::changeIDFiltering(QListWidgetItem *item)
|
||||
{
|
||||
qDebug() << "Changed ID filter " << item->text() << " : " << item->checkState();
|
||||
int ID = Utility::ParseStringToNum(item->text());
|
||||
int ID = FilterUtility::getIdAsInt(item);
|
||||
currentSeqItem->idFilters[ID] = (item->checkState() == Qt::Checked) ? true : false;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@ MainSettingsDialog::MainSettingsDialog(QWidget *parent) :
|
||||
ui->comboSendingBus->setCurrentIndex(settings.value("Playback/SendingBus", 4).toInt());
|
||||
ui->cbUseFiltered->setChecked(settings.value("Main/UseFiltered", false).toBool());
|
||||
ui->cbUseOpenGL->setChecked(settings.value("Main/UseOpenGL", false).toBool());
|
||||
ui->cbFilterLabeling->setChecked(settings.value("Main/FilterLabeling", false).toBool());
|
||||
|
||||
//just for simplicity they all call the same function and that function updates all settings at once
|
||||
connect(ui->cbDisplayHex, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
|
||||
@@ -83,6 +84,7 @@ MainSettingsDialog::MainSettingsDialog(QWidget *parent) :
|
||||
connect(ui->lineRemoteHost, SIGNAL(editingFinished()), this, SLOT(updateSettings()));
|
||||
connect(ui->lineRemotePort, SIGNAL(editingFinished()), this, SLOT(updateSettings()));
|
||||
connect(ui->cbLoadConnections, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
|
||||
connect(ui->cbFilterLabeling, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
|
||||
installEventFilter(this);
|
||||
}
|
||||
|
||||
@@ -141,6 +143,7 @@ void MainSettingsDialog::updateSettings()
|
||||
settings.setValue("Remote/Host", ui->lineRemoteHost->text());
|
||||
settings.setValue("Remote/Port", ui->lineRemotePort->text());
|
||||
settings.setValue("Remote/AutoStart", ui->cbAutoStartRemote->isChecked());
|
||||
settings.setValue("Main/FilterLabeling", ui->cbFilterLabeling->isChecked());
|
||||
|
||||
settings.sync();
|
||||
emit updatedSettings();
|
||||
|
||||
+19
-10
@@ -8,6 +8,7 @@
|
||||
#include "connections/connectionwindow.h"
|
||||
#include "helpwindow.h"
|
||||
#include "utility.h"
|
||||
#include "filterutility.h"
|
||||
|
||||
/*
|
||||
Some notes on things I'd like to put into the program but haven't put on github (yet)
|
||||
@@ -143,6 +144,9 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
ui->lbFPS->setText("0");
|
||||
ui->lbNumFrames->setText("0");
|
||||
|
||||
// Prevent annoying accidental horizontal scrolling when filter list is populated with long interpreted message names
|
||||
ui->listFilters->horizontalScrollBar()->setEnabled(false);
|
||||
|
||||
connect(&updateTimer, &QTimer::timeout, this, &MainWindow::tickGUIUpdate);
|
||||
updateTimer.setInterval(250);
|
||||
updateTimer.start();
|
||||
@@ -324,7 +328,13 @@ void MainWindow::readUpdateableSettings()
|
||||
useFiltered = settings.value("Main/UseFiltered", false).toBool();
|
||||
model->setTimeFormat(settings.value("Main/TimeFormat", "MMM-dd HH:mm:ss.zzz").toString());
|
||||
|
||||
}
|
||||
if (settings.value("Main/FilterLabeling", false).toBool())
|
||||
ui->listFilters->setMaximumWidth(250);
|
||||
else
|
||||
ui->listFilters->setMaximumWidth(175);
|
||||
updateFilterList();
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::writeSettings()
|
||||
{
|
||||
@@ -391,7 +401,7 @@ void MainWindow::gridDoubleClicked(QModelIndex idx)
|
||||
|
||||
void MainWindow::interpretToggled(bool state)
|
||||
{
|
||||
model->setInterpetMode(state);
|
||||
model->setInterpretMode(state);
|
||||
//ui->canFramesView->resizeRowsToContents(); //a VERY costly operation!
|
||||
}
|
||||
|
||||
@@ -422,6 +432,8 @@ void MainWindow::updateFilterList()
|
||||
|
||||
qDebug() << "updateFilterList called on MainWindow";
|
||||
|
||||
inhibitFilterUpdate = true;
|
||||
|
||||
ui->listFilters->clear();
|
||||
|
||||
if (filters->isEmpty()) return;
|
||||
@@ -429,22 +441,19 @@ void MainWindow::updateFilterList()
|
||||
QMap<int, bool>::const_iterator filterIter;
|
||||
for (filterIter = filters->begin(); filterIter != filters->end(); ++filterIter)
|
||||
{
|
||||
QListWidgetItem *thisItem = new QListWidgetItem();
|
||||
thisItem->setText(Utility::formatCANID(filterIter.key()));
|
||||
thisItem->setFlags(thisItem->flags() | Qt::ItemIsUserCheckable);
|
||||
if (filterIter.value()) thisItem->setCheckState(Qt::Checked);
|
||||
else thisItem->setCheckState(Qt::Unchecked);
|
||||
ui->listFilters->addItem(thisItem);
|
||||
QListWidgetItem *thisItem = FilterUtility::createCheckableFilterItem(filterIter.key(), filterIter.value(), ui->listFilters);
|
||||
}
|
||||
inhibitFilterUpdate = false;
|
||||
}
|
||||
|
||||
void MainWindow::filterListItemChanged(QListWidgetItem *item)
|
||||
{
|
||||
if (inhibitFilterUpdate) return;
|
||||
//qDebug() << item->text();
|
||||
int ID;
|
||||
|
||||
// strip away possible filter label
|
||||
int ID = FilterUtility::getIdAsInt(item);
|
||||
bool isSet = false;
|
||||
ID = Utility::ParseStringToNum(item->text());
|
||||
if (item->checkState() == Qt::Checked) isSet = true;
|
||||
|
||||
model->setFilterState(ID, isSet);
|
||||
|
||||
+20
-5
@@ -2,6 +2,7 @@
|
||||
#include "ui_flowviewwindow.h"
|
||||
#include "mainwindow.h"
|
||||
#include "helpwindow.h"
|
||||
#include "filterutility.h"
|
||||
|
||||
const QColor FlowViewWindow::graphColors[8] = {Qt::blue, Qt::green, Qt::black, Qt::red, //0 1 2 3
|
||||
Qt::gray, Qt::yellow, Qt::cyan, Qt::darkMagenta}; //4 5 6 7
|
||||
@@ -85,7 +86,6 @@ FlowViewWindow::FlowViewWindow(const QVector<CANFrame> *frames, QWidget *parent)
|
||||
connect(ui->btnForwardOne, SIGNAL(clicked(bool)), this, SLOT(btnFwdOneClick()));
|
||||
connect(ui->spinPlayback, SIGNAL(valueChanged(int)), this, SLOT(changePlaybackSpeed(int)));
|
||||
connect(ui->cbLoopPlayback, SIGNAL(clicked(bool)), this, SLOT(changeLooping(bool)));
|
||||
connect(ui->listFrameID, SIGNAL(currentTextChanged(QString)), this, SLOT(changeID(QString)));
|
||||
connect(playbackTimer, SIGNAL(timeout()), this, SLOT(timerTriggered()));
|
||||
connect(ui->graphView, SIGNAL(plottableDoubleClick(QCPAbstractPlottable*,QMouseEvent*)), this, SLOT(plottableDoubleClick(QCPAbstractPlottable*,QMouseEvent*)));
|
||||
connect(ui->txtTrigger0, SIGNAL(textEdited(QString)), this, SLOT(updateTriggerValues()));
|
||||
@@ -97,6 +97,13 @@ FlowViewWindow::FlowViewWindow(const QVector<CANFrame> *frames, QWidget *parent)
|
||||
connect(ui->txtTrigger6, SIGNAL(textEdited(QString)), this, SLOT(updateTriggerValues()));
|
||||
connect(ui->txtTrigger7, SIGNAL(textEdited(QString)), this, SLOT(updateTriggerValues()));
|
||||
|
||||
// Using lambda expression to strip away the possible filter label before passing the ID to updateDetailsWindow
|
||||
connect(ui->listFrameID, &QListWidget::currentTextChanged,
|
||||
[this](QString itemText)
|
||||
{
|
||||
changeID(FilterUtility::getId(itemText));
|
||||
} );
|
||||
|
||||
connect(MainWindow::getReference(), SIGNAL(framesUpdated(int)), this, SLOT(updatedFrames(int)));
|
||||
|
||||
ui->graphView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
@@ -105,6 +112,9 @@ FlowViewWindow::FlowViewWindow(const QVector<CANFrame> *frames, QWidget *parent)
|
||||
connect(ui->flowView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequestFlow(QPoint)));
|
||||
connect(ui->flowView, SIGNAL(gridClicked(int,int)), this, SLOT(gotCellClick(int, int)));
|
||||
|
||||
// Prevent annoying accidental horizontal scrolling when filter list is populated with long interpreted message names
|
||||
ui->listFrameID->horizontalScrollBar()->setEnabled(false);
|
||||
|
||||
playbackTimer->setInterval(ui->spinPlayback->value()); //set the timer to the default value of the control
|
||||
}
|
||||
|
||||
@@ -119,7 +129,7 @@ void FlowViewWindow::showEvent(QShowEvent* event)
|
||||
refreshIDList();
|
||||
if (ui->listFrameID->count() > 0)
|
||||
{
|
||||
changeID(ui->listFrameID->item(0)->text());
|
||||
changeID(FilterUtility::getId(ui->listFrameID->item(0)));
|
||||
ui->listFrameID->setCurrentRow(0);
|
||||
}
|
||||
updateFrameLabel();
|
||||
@@ -161,6 +171,11 @@ void FlowViewWindow::readSettings()
|
||||
ui->cbTimeGraph->setChecked(true);
|
||||
}
|
||||
|
||||
if (settings.value("Main/FilterLabeling", false).toBool())
|
||||
ui->listFrameID->setMaximumWidth(250);
|
||||
else
|
||||
ui->listFrameID->setMaximumWidth(120);
|
||||
|
||||
secondsMode = settings.value("Main/TimeSeconds", false).toBool();
|
||||
openGLMode = settings.value("Main/UseOpenGL", false).toBool();
|
||||
}
|
||||
@@ -252,7 +267,7 @@ void FlowViewWindow::gotCenterTimeID(int32_t ID, double timestamp)
|
||||
|
||||
for (int j = 0; j < ui->listFrameID->count(); j++)
|
||||
{
|
||||
int thisNum = Utility::ParseStringToNum(ui->listFrameID->item(j)->text());
|
||||
int thisNum = FilterUtility::getIdAsInt(ui->listFrameID->item(j));
|
||||
if (thisNum == ID)
|
||||
{
|
||||
ui->listFrameID->setCurrentRow(j);
|
||||
@@ -423,7 +438,7 @@ void FlowViewWindow::updatedFrames(int numFrames)
|
||||
if (!foundID.contains(thisFrame.ID))
|
||||
{
|
||||
foundID.append(thisFrame.ID);
|
||||
/*QListWidgetItem* item =*/ new QListWidgetItem(Utility::formatCANID(thisFrame.ID, thisFrame.extended), ui->listFrameID);
|
||||
FilterUtility::createFilterItem(thisFrame.ID, ui->listFrameID);
|
||||
}
|
||||
|
||||
if (thisFrame.ID == refID)
|
||||
@@ -540,7 +555,7 @@ void FlowViewWindow::refreshIDList()
|
||||
if (!foundID.contains(id))
|
||||
{
|
||||
foundID.append(id);
|
||||
/*QListWidgetItem* item = */ new QListWidgetItem(Utility::formatCANID(id, thisFrame.extended), ui->listFrameID);
|
||||
FilterUtility::createFilterItem(id, ui->listFrameID);
|
||||
}
|
||||
}
|
||||
//default is to sort in ascending order
|
||||
|
||||
+55
-13
@@ -4,6 +4,7 @@
|
||||
#include "helpwindow.h"
|
||||
#include <QtDebug>
|
||||
#include <vector>
|
||||
#include "filterutility.h"
|
||||
|
||||
const QColor FrameInfoWindow::byteGraphColors[8] = {Qt::blue, Qt::green, Qt::black, Qt::red, //0 1 2 3
|
||||
Qt::gray, Qt::yellow, Qt::cyan, Qt::darkMagenta}; //4 5 6 7
|
||||
@@ -22,7 +23,13 @@ FrameInfoWindow::FrameInfoWindow(const QVector<CANFrame> *frames, QWidget *paren
|
||||
|
||||
modelFrames = frames;
|
||||
|
||||
connect(ui->listFrameID, &QListWidget::currentTextChanged, this, &FrameInfoWindow::updateDetailsWindow);
|
||||
// Using lambda expression to strip away the possible filter label before passing the ID to updateDetailsWindow
|
||||
connect(ui->listFrameID, &QListWidget::currentTextChanged,
|
||||
[this](QString itemText)
|
||||
{
|
||||
FrameInfoWindow::updateDetailsWindow(FilterUtility::getId(itemText));
|
||||
} );
|
||||
|
||||
connect(MainWindow::getReference(), &MainWindow::framesUpdated, this, &FrameInfoWindow::updatedFrames);
|
||||
connect(ui->btnSave, &QAbstractButton::clicked, this, &FrameInfoWindow::saveDetails);
|
||||
|
||||
@@ -82,6 +89,9 @@ FrameInfoWindow::FrameInfoWindow(const QVector<CANFrame> *frames, QWidget *paren
|
||||
ui->timeHistogram->setAntialiasedElements(QCP::aeNone);
|
||||
}
|
||||
|
||||
// Prevent annoying accidental horizontal scrolling when filter list is populated with long interpreted message names
|
||||
ui->listFrameID->horizontalScrollBar()->setEnabled(false);
|
||||
|
||||
installEventFilter(this);
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
@@ -98,7 +108,7 @@ void FrameInfoWindow::showEvent(QShowEvent* event)
|
||||
refreshIDList();
|
||||
if (ui->listFrameID->count() > 0)
|
||||
{
|
||||
updateDetailsWindow(ui->listFrameID->item(0)->text());
|
||||
updateDetailsWindow(FilterUtility::getId(ui->listFrameID->item(0)));
|
||||
ui->listFrameID->setCurrentRow(0);
|
||||
}
|
||||
}
|
||||
@@ -135,12 +145,23 @@ void FrameInfoWindow::closeEvent(QCloseEvent *event)
|
||||
void FrameInfoWindow::readSettings()
|
||||
{
|
||||
QSettings settings;
|
||||
|
||||
if (settings.value("Main/FilterLabeling", false).toBool())
|
||||
{
|
||||
ui->listFrameID->setMinimumWidth(250);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->listFrameID->setMinimumWidth(120);
|
||||
}
|
||||
|
||||
if (settings.value("Main/SaveRestorePositions", false).toBool())
|
||||
{
|
||||
resize(settings.value("FrameInfo/WindowSize", QSize(794, 694)).toSize());
|
||||
move(settings.value("FrameInfo/WindowPos", QPoint(50, 50)).toPoint());
|
||||
}
|
||||
useOpenGL = settings.value("Main/UseOpenGL", false).toBool();
|
||||
|
||||
}
|
||||
|
||||
void FrameInfoWindow::writeSettings()
|
||||
@@ -174,7 +195,7 @@ void FrameInfoWindow::updatedFrames(int numFrames)
|
||||
refreshIDList();
|
||||
if (ui->listFrameID->count() > 0)
|
||||
{
|
||||
updateDetailsWindow(ui->listFrameID->item(0)->text());
|
||||
updateDetailsWindow(FilterUtility::getId(ui->listFrameID->item(0)));
|
||||
ui->listFrameID->setCurrentRow(0);
|
||||
}
|
||||
}
|
||||
@@ -185,7 +206,7 @@ void FrameInfoWindow::updatedFrames(int numFrames)
|
||||
|
||||
unsigned int currID = 0;
|
||||
if (ui->listFrameID->currentItem())
|
||||
currID = static_cast<unsigned int>(ui->listFrameID->currentItem()->text().toInt(nullptr, 16));
|
||||
currID = static_cast<unsigned int>(FilterUtility::getIdAsInt(ui->listFrameID->currentItem()));
|
||||
bool thisID = false;
|
||||
for (int x = modelFrames->count() - numFrames; x < modelFrames->count(); x++)
|
||||
{
|
||||
@@ -194,7 +215,7 @@ void FrameInfoWindow::updatedFrames(int numFrames)
|
||||
if (!foundID.contains(id))
|
||||
{
|
||||
foundID.append(id);
|
||||
ui->listFrameID->addItem(Utility::formatCANID(id, thisFrame.extended));
|
||||
FilterUtility::createFilterItem(id, ui->listFrameID);
|
||||
}
|
||||
|
||||
if (currID == modelFrames->at(x).ID)
|
||||
@@ -266,6 +287,7 @@ void FrameInfoWindow::updateDetailsWindow(QString newID)
|
||||
|
||||
if (frameCache[0].extended) //if these frames seem to be extended then try for J1939 decoding
|
||||
{
|
||||
// ------- J1939 decoding ----------
|
||||
J1939ID jid;
|
||||
jid.src = targettedID & 0xFF;
|
||||
jid.priority = targettedID >> 26;
|
||||
@@ -273,36 +295,56 @@ void FrameInfoWindow::updateDetailsWindow(QString newID)
|
||||
jid.pf = (targettedID >> 16) & 0xFF;
|
||||
jid.ps = (targettedID >> 8) & 0xFF;
|
||||
|
||||
tempItem = new QTreeWidgetItem();
|
||||
tempItem->setText(0, tr("J1939 decoding"));
|
||||
baseNode->addChild(tempItem);
|
||||
|
||||
if (jid.pf > 0xEF)
|
||||
{
|
||||
jid.isBroadcast = true;
|
||||
jid.dest = 0xFFFF;
|
||||
tempItem = new QTreeWidgetItem();
|
||||
tempItem->setText(0, tr("Broadcast Frame"));
|
||||
tempItem->setText(0, tr(" Broadcast Frame"));
|
||||
baseNode->addChild(tempItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
jid.dest = jid.ps;
|
||||
tempItem = new QTreeWidgetItem();
|
||||
tempItem->setText(0, tr("Destination ID: ") + Utility::formatNumber(static_cast<uint64_t>(jid.dest)));
|
||||
tempItem->setText(0, tr(" Destination ID: ") + Utility::formatNumber(static_cast<uint64_t>(jid.dest)));
|
||||
baseNode->addChild(tempItem);
|
||||
}
|
||||
tempItem = new QTreeWidgetItem();
|
||||
tempItem->setText(0, tr("SRC: ") + Utility::formatNumber(static_cast<uint64_t>(jid.src)));
|
||||
tempItem->setText(0, tr(" SRC: ") + Utility::formatNumber(static_cast<uint64_t>(jid.src)));
|
||||
baseNode->addChild(tempItem);
|
||||
|
||||
tempItem = new QTreeWidgetItem();
|
||||
tempItem->setText(0, tr("PGN: ") + Utility::formatNumber(static_cast<uint64_t>(jid.pgn)) + "(" + QString::number(jid.pgn) + ")");
|
||||
tempItem->setText(0, tr(" PGN: ") + Utility::formatNumber(static_cast<uint64_t>(jid.pgn)) + "(" + QString::number(jid.pgn) + ")");
|
||||
baseNode->addChild(tempItem);
|
||||
|
||||
tempItem = new QTreeWidgetItem();
|
||||
tempItem->setText(0, tr("PF: ") + Utility::formatNumber(static_cast<uint64_t>(jid.pf)));
|
||||
tempItem->setText(0, tr(" PF: ") + Utility::formatNumber(static_cast<uint64_t>(jid.pf)));
|
||||
baseNode->addChild(tempItem);
|
||||
|
||||
tempItem = new QTreeWidgetItem();
|
||||
tempItem->setText(0, tr("PS: ") + Utility::formatNumber(static_cast<uint64_t>(jid.ps)));
|
||||
tempItem->setText(0, tr(" PS: ") + Utility::formatNumber(static_cast<uint64_t>(jid.ps)));
|
||||
baseNode->addChild(tempItem);
|
||||
|
||||
// ------- GMLAN 29bit decoding ----------
|
||||
tempItem = new QTreeWidgetItem();
|
||||
tempItem->setText(0, tr("GMLAN 29bit decoding"));
|
||||
baseNode->addChild(tempItem);
|
||||
|
||||
tempItem = new QTreeWidgetItem();
|
||||
tempItem->setText(0, tr(" Priority bits: ") + Utility::formatNumber( FilterUtility::getGMLanPriorityBits(targettedID)));
|
||||
baseNode->addChild(tempItem);
|
||||
tempItem = new QTreeWidgetItem();
|
||||
tempItem->setText(0, tr(" Arbitration Id: ") + Utility::formatNumber( FilterUtility::getGMLanArbitrationId(targettedID)));
|
||||
baseNode->addChild(tempItem);
|
||||
tempItem = new QTreeWidgetItem();
|
||||
tempItem->setText(0, tr(" Sender Id: ") + Utility::formatNumber( FilterUtility::getGMLanSenderId(targettedID)));
|
||||
baseNode->addChild(tempItem);
|
||||
|
||||
}
|
||||
|
||||
tempItem = new QTreeWidgetItem();
|
||||
@@ -562,7 +604,7 @@ void FrameInfoWindow::refreshIDList()
|
||||
if (!foundID.contains(id))
|
||||
{
|
||||
foundID.append(id);
|
||||
ui->listFrameID->addItem(Utility::formatCANID(id, thisFrame.extended));
|
||||
FilterUtility::createFilterItem(id, ui->listFrameID);
|
||||
}
|
||||
}
|
||||
//default is to sort in ascending order
|
||||
@@ -603,7 +645,7 @@ void FrameInfoWindow::saveDetails()
|
||||
//go through all IDs, recalculate the data, and then save it to file
|
||||
for (int i = 0; i < ui->listFrameID->count(); i++)
|
||||
{
|
||||
updateDetailsWindow(ui->listFrameID->item(i)->text());
|
||||
updateDetailsWindow(FilterUtility::getId(ui->listFrameID->item(i)));
|
||||
dumpNode(ui->treeDetails->invisibleRootItem(), outFile, 0);
|
||||
outFile->write("\n\n");
|
||||
}
|
||||
|
||||
+7
-11
@@ -5,6 +5,7 @@
|
||||
#include "mainwindow.h"
|
||||
#include "helpwindow.h"
|
||||
#include "connections/canconmanager.h"
|
||||
#include "filterutility.h"
|
||||
|
||||
FuzzingWindow::FuzzingWindow(const QVector<CANFrame> *frames, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
@@ -43,6 +44,9 @@ FuzzingWindow::FuzzingWindow(const QVector<CANFrame> *frames, QWidget *parent) :
|
||||
for (int n = 0; n < numBuses; n++) ui->cbBuses->addItem(QString::number(n));
|
||||
ui->cbBuses->addItem(tr("All"));
|
||||
|
||||
// Prevent annoying accidental horizontal scrolling when filter list is populated with long interpreted message names
|
||||
ui->listID->horizontalScrollBar()->setEnabled(false);
|
||||
|
||||
installEventFilter(this);
|
||||
}
|
||||
|
||||
@@ -95,11 +99,7 @@ void FuzzingWindow::updatedFrames(int numFrames)
|
||||
{
|
||||
foundIDs.append(id);
|
||||
selectedIDs.append(id);
|
||||
QListWidgetItem *thisItem = new QListWidgetItem();
|
||||
thisItem->setText(Utility::formatCANID(id, modelFrames->at(i).extended));
|
||||
thisItem->setFlags(thisItem->flags() | Qt::ItemIsUserCheckable);
|
||||
thisItem->setCheckState(Qt::Checked);
|
||||
ui->listID->addItem(thisItem);
|
||||
FilterUtility::createCheckableFilterItem(id, true, ui->listID);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -376,11 +376,7 @@ void FuzzingWindow::refreshIDList()
|
||||
{
|
||||
foundIDs.append(id);
|
||||
selectedIDs.append(id);
|
||||
QListWidgetItem *thisItem = new QListWidgetItem();
|
||||
thisItem->setText(Utility::formatCANID(id, thisFrame.extended));
|
||||
thisItem->setFlags(thisItem->flags() | Qt::ItemIsUserCheckable);
|
||||
thisItem->setCheckState(Qt::Checked);
|
||||
ui->listID->addItem(thisItem);
|
||||
FilterUtility::createCheckableFilterItem(id, true, ui->listID);
|
||||
}
|
||||
}
|
||||
//default is to sort in ascending order
|
||||
@@ -389,7 +385,7 @@ void FuzzingWindow::refreshIDList()
|
||||
|
||||
void FuzzingWindow::idListChanged(QListWidgetItem *item)
|
||||
{
|
||||
int id = Utility::ParseStringToNum(item->text());
|
||||
int id = FilterUtility::getIdAsInt(item);
|
||||
if (item->checkState() == Qt::Checked)
|
||||
{
|
||||
if (!selectedIDs.contains(id))
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>506</width>
|
||||
<width>680</width>
|
||||
<height>665</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
||||
@@ -73,6 +73,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbFilterLabeling">
|
||||
<property name="text">
|
||||
<string>Label filters using messages from DBC files</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbUseOpenGL">
|
||||
<property name="text">
|
||||
|
||||
Reference in New Issue
Block a user