Merge branch 'master' of github.com:collin80/SavvyCAN

This commit is contained in:
Collin Kidder
2022-10-04 19:59:46 -04:00
30 changed files with 676 additions and 138 deletions
+45 -8
View File
@@ -4,6 +4,7 @@
#include <QApplication> #include <QApplication>
#include <QPalette> #include <QPalette>
#include <QDateTime> #include <QDateTime>
#include <QSettings>
#include "utility.h" #include "utility.h"
CANFrameModel::~CANFrameModel() CANFrameModel::~CANFrameModel()
@@ -45,24 +46,29 @@ int CANFrameModel::columnCount(const QModelIndex &index) const
CANFrameModel::CANFrameModel(QObject *parent) CANFrameModel::CANFrameModel(QObject *parent)
: QAbstractTableModel(parent) : QAbstractTableModel(parent)
{ {
int maxFramesDefault;
if (QSysInfo::WordSize > 32) if (QSysInfo::WordSize > 32)
{ {
qDebug() << "64 bit OS detected. Requesting a large preallocation"; qDebug() << "64 bit OS detected. Requesting a large preallocation";
preallocSize = 10000000; maxFramesDefault = 10000000;
} }
else //if compiling for 32 bit you can't ask for gigabytes of preallocation so tone it down. else //if compiling for 32 bit you can't ask for gigabytes of preallocation so tone it down.
{ {
qDebug() << "32 bit OS detected. Requesting a much restricted prealloc"; qDebug() << "32 bit OS detected. Requesting a much restricted prealloc";
preallocSize = 2000000; maxFramesDefault = 2000000;
} }
QSettings settings;
preallocSize = settings.value("Main/MaximumFrames", maxFramesDefault).toInt();
//the goal is to prevent a reallocation from ever happening
frames.reserve(preallocSize); frames.reserve(preallocSize);
filteredFrames.reserve(preallocSize); //the goal is to prevent a reallocation from ever happening filteredFrames.reserve(preallocSize);
dbcHandler = DBCHandler::getReference(); dbcHandler = DBCHandler::getReference();
interpretFrames = false; interpretFrames = false;
overwriteDups = false; overwriteDups = false;
filtersPersistDuringClear = false;
useHexMode = true; useHexMode = true;
timeSeconds = false; timeSeconds = false;
timeOffset = 0; timeOffset = 0;
@@ -196,6 +202,11 @@ void CANFrameModel::setOverwriteMode(bool mode)
endResetModel(); endResetModel();
} }
void CANFrameModel::setClearMode(bool mode)
{
filtersPersistDuringClear = mode;
}
void CANFrameModel::setFilterState(unsigned int ID, bool state) void CANFrameModel::setFilterState(unsigned int ID, bool state)
{ {
if (!filters.contains(ID)) return; if (!filters.contains(ID)) return;
@@ -370,6 +381,7 @@ void CANFrameModel::recalcOverwrite()
//Then replace the old list of frames with just the unique list //Then replace the old list of frames with just the unique list
frames.clear(); frames.clear();
frames.append(overWriteFrames.values().toVector()); frames.append(overWriteFrames.values().toVector());
frames.reserve(preallocSize);
filteredFrames.clear(); filteredFrames.clear();
filteredFrames.reserve(preallocSize); filteredFrames.reserve(preallocSize);
@@ -404,7 +416,7 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const
const unsigned char *data = reinterpret_cast<const unsigned char *>(thisFrame.payload().constData()); const unsigned char *data = reinterpret_cast<const unsigned char *>(thisFrame.payload().constData());
int dataLen = thisFrame.payload().count(); int dataLen = thisFrame.payload().count();
if (role == Qt::BackgroundColorRole) if (role == Qt::BackgroundRole)
{ {
if (dbcHandler != nullptr && interpretFrames && !ignoreDBCColors) if (dbcHandler != nullptr && interpretFrames && !ignoreDBCColors)
{ {
@@ -437,7 +449,7 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const
} }
} }
if (role == Qt::TextColorRole) if (role == Qt::ForegroundRole)
{ {
if (dbcHandler != nullptr && interpretFrames && !ignoreDBCColors) if (dbcHandler != nullptr && interpretFrames && !ignoreDBCColors)
{ {
@@ -672,8 +684,11 @@ void CANFrameModel::addFrame(const CANFrame& frame, bool autoRefresh = false)
} }
if (!overwriteDups) if (!overwriteDups)
{
try
{ {
frames.append(tempFrame); frames.append(tempFrame);
if (filters[tempFrame.frameId()] && busFilters[tempFrame.bus]) if (filters[tempFrame.frameId()] && busFilters[tempFrame.bus])
{ {
if (autoRefresh) beginInsertRows(QModelIndex(), filteredFrames.count(), filteredFrames.count()); if (autoRefresh) beginInsertRows(QModelIndex(), filteredFrames.count(), filteredFrames.count());
@@ -682,6 +697,11 @@ void CANFrameModel::addFrame(const CANFrame& frame, bool autoRefresh = false)
if (autoRefresh) endInsertRows(); if (autoRefresh) endInsertRows();
} }
} }
catch (const std::exception& ex)
{
qDebug() << "addFrame failed to append. App is probably going to crash. frames.length(): " << frames.length() << " Exception: " << ex.what();
}
}
else //yes, overwrite dups else //yes, overwrite dups
{ {
bool found = false; bool found = false;
@@ -728,6 +748,20 @@ void CANFrameModel::addFrame(const CANFrame& frame, bool autoRefresh = false)
void CANFrameModel::addFrames(const CANConnection*, const QVector<CANFrame>& pFrames) void CANFrameModel::addFrames(const CANConnection*, const QVector<CANFrame>& pFrames)
{ {
if(frames.length() > frames.capacity() * 0.99)
{
qDebug() << "Frames count: " << frames.length() << " of " << frames.capacity() << " capacity, removing first " << (int)(frames.capacity() * 0.05) << " frames";
frames.remove(0, (int)(frames.capacity() * 0.05));
qDebug() << "Frames removed, new count: " << frames.length();
}
if(filteredFrames.length() > filteredFrames.capacity() * 0.99)
{
qDebug() << "filteredFrames count: " << filteredFrames.length() << " of " << filteredFrames.capacity() << " capacity, removing first " << (int)(filteredFrames.capacity() * 0.05) << " frames";
filteredFrames.remove(0, (int)(filteredFrames.capacity() * 0.05));
qDebug() << "filteredFrames removed, new count: " << filteredFrames.length();
}
foreach(const CANFrame& frame, pFrames) foreach(const CANFrame& frame, pFrames)
{ {
addFrame(frame); addFrame(frame);
@@ -754,8 +788,8 @@ void CANFrameModel::sendRefresh()
mutex.lock(); mutex.lock();
beginResetModel(); beginResetModel();
filteredFrames.clear(); filteredFrames.clear();
filteredFrames.reserve(preallocSize);
filteredFrames.append(tempContainer); filteredFrames.append(tempContainer);
filteredFrames.reserve(preallocSize);
lastUpdateNumFrames = 0; lastUpdateNumFrames = 0;
endResetModel(); endResetModel();
@@ -779,7 +813,7 @@ int CANFrameModel::sendBulkRefresh()
if (lastUpdateNumFrames == 0 && !overwriteDups) return 0; if (lastUpdateNumFrames == 0 && !overwriteDups) return 0;
if (filteredFrames.count() == 0) return 0; if (filteredFrames.count() == 0) return 0;
qDebug() << "Bulk refresh of " << lastUpdateNumFrames; //qDebug() << "Bulk refresh of " << lastUpdateNumFrames;
beginResetModel(); beginResetModel();
endResetModel(); endResetModel();
@@ -796,8 +830,11 @@ void CANFrameModel::clearFrames()
this->beginResetModel(); this->beginResetModel();
frames.clear(); frames.clear();
filteredFrames.clear(); filteredFrames.clear();
if(filtersPersistDuringClear == false)
{
filters.clear(); filters.clear();
busFilters.clear(); busFilters.clear();
}
frames.reserve(preallocSize); frames.reserve(preallocSize);
filteredFrames.reserve(preallocSize); filteredFrames.reserve(preallocSize);
this->endResetModel(); this->endResetModel();
+2
View File
@@ -46,6 +46,7 @@ public:
bool getInterpretMode(); bool getInterpretMode();
void setOverwriteMode(bool); void setOverwriteMode(bool);
void setHexMode(bool); void setHexMode(bool);
void setClearMode(bool mode);
void setSysTimeMode(bool); void setSysTimeMode(bool);
void setMillisMode(bool mode); void setMillisMode(bool mode);
void setIgnoreDBCColors(bool mode); void setIgnoreDBCColors(bool mode);
@@ -89,6 +90,7 @@ private:
QMutex mutex; QMutex mutex;
bool interpretFrames; //should we use the dbcHandler? bool interpretFrames; //should we use the dbcHandler?
bool overwriteDups; //should we display all frames or only the newest for each ID? bool overwriteDups; //should we display all frames or only the newest for each ID?
bool filtersPersistDuringClear;
QString timeFormat; QString timeFormat;
bool useHexMode; bool useHexMode;
bool timeSeconds; bool timeSeconds;
+3
View File
@@ -14,6 +14,9 @@ CANConnection* CanConFactory::create(type pType, QString pPortName, QString pDri
case SERIALBUS: case SERIALBUS:
return new SerialBusConnection(pPortName, pDriverName); return new SerialBusConnection(pPortName, pDriverName);
case GVRET_SERIAL: case GVRET_SERIAL:
if(pPortName.contains("."))
return new GVRetSerial(pPortName, true);
else
return new GVRetSerial(pPortName, false); return new GVRetSerial(pPortName, false);
case REMOTE: case REMOTE:
return new GVRetSerial(pPortName, true); //it's a special case of GVRET connected over TCP/IP so it uses the same class return new GVRetSerial(pPortName, true); //it's a special case of GVRET connected over TCP/IP so it uses the same class
+2 -2
View File
@@ -250,11 +250,11 @@ CANCon::type CANConnection::getType() {
CANCon::status CANConnection::getStatus() { CANCon::status CANConnection::getStatus() {
return (CANCon::status) mStatus.load(); return (CANCon::status) mStatus.loadRelaxed();
} }
void CANConnection::setStatus(CANCon::status pStatus) { void CANConnection::setStatus(CANCon::status pStatus) {
mStatus.store(pStatus); mStatus.storeRelaxed(pStatus);
} }
bool CANConnection::isCapSuspended() { bool CANConnection::isCapSuspended() {
+2
View File
@@ -508,8 +508,10 @@ CANConnection* ConnectionWindow::create(CANCon::type pTye, QString pPortName, QS
void ConnectionWindow::loadConnections() void ConnectionWindow::loadConnections()
{ {
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
qRegisterMetaTypeStreamOperators<CANBus>(); qRegisterMetaTypeStreamOperators<CANBus>();
qRegisterMetaTypeStreamOperators<QList<CANBus>>(); qRegisterMetaTypeStreamOperators<QList<CANBus>>();
#endif
QSettings settings; QSettings settings;
+2
View File
@@ -485,6 +485,7 @@ void GVRetSerial::serialError(QSerialPort::SerialPortError err)
killConnection = true; killConnection = true;
piStop(); piStop();
break; break;
#if QT_VERSION <= QT_VERSION_CHECK( 6, 0, 0 )
case QSerialPort::ParityError: case QSerialPort::ParityError:
errMessage = "Parity error on serial port"; errMessage = "Parity error on serial port";
break; break;
@@ -494,6 +495,7 @@ void GVRetSerial::serialError(QSerialPort::SerialPortError err)
case QSerialPort::BreakConditionError: case QSerialPort::BreakConditionError:
errMessage = "Break error on serial port"; errMessage = "Break error on serial port";
break; break;
#endif
case QSerialPort::WriteError: case QSerialPort::WriteError:
errMessage = "Write error on serial port"; errMessage = "Write error on serial port";
piStop(); piStop();
+59 -9
View File
@@ -32,6 +32,7 @@ SocketCANd::SocketCANd(QString portName) :
for (int i = 0; i < mNumBuses; i++) for (int i = 0; i < mNumBuses; i++)
{ {
rx_state.append(IDLE); rx_state.append(IDLE);
unprocessedData.append("");
} }
} }
@@ -249,20 +250,35 @@ void SocketCANd::switchToRawMode(int busNum)
QCoreApplication::processEvents(); QCoreApplication::processEvents();
} }
void SocketCANd::decodeFrames(QString data, int busNum) QString SocketCANd::decodeFrames(QString data, int busNum)
{ {
if (data.indexOf("< frame ") == -1) if (data.indexOf("<") == -1)
return "";
else if(data.length() >= 8 && data.indexOf("< frame ") == -1)
return "";
int firstIndex = data.indexOf("< frame ");
if(firstIndex > 0)
{ {
qDebug() << "Received datagramm doesn't contain any frame: " << data; QString framePartial = data.left(firstIndex);
return; qDebug() << "Received datagramm that starts with fragment (missing '< frame'), this should only occur on startup, removing...: " << framePartial;
} }
else QString framePart = data.mid(firstIndex); //remove starting beginning of payload if not < frame >
{
QString framePart = data.mid(data.indexOf("< frame "), data.length()); //remove starting beginning of payload if not < frame >
const QString frameStrConst = framePart.left(framePart.indexOf(">")+1); const QString frameStrConst = framePart.left(framePart.indexOf(">")+1);
QString frameStr = frameStrConst; QString frameStr = frameStrConst;
QStringList frameParsed = (frameStr.remove(QRegExp("^<")).remove(QRegExp(">$"))).simplified().split(' '); QStringList frameParsed = (frameStr.remove(QRegExp("^<")).remove(QRegExp(">$"))).simplified().split(' ');
if(frameParsed.length() < 3)
{
//qDebug() << "Received datagramm is an incomplete frame: " << data;
//ok great, need to leave it in the buffer in case it can be combined with what comes next
//but if there was a fragment that did not have a starting token then we don't want it so only return
//known good data...again this should only happen on startup, but just in case we need to remove it
//so the data buffer doesn't grow uncontrolled.
return framePart;
}
buildFrame.setFrameId(frameParsed[1].toUInt(nullptr, 16)); buildFrame.setFrameId(frameParsed[1].toUInt(nullptr, 16));
buildFrame.bus = busNum; buildFrame.bus = busNum;
@@ -271,6 +287,13 @@ void SocketCANd::decodeFrames(QString data, int busNum)
buildFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, frameParsed[2].toDouble() * 1000000l)); buildFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, frameParsed[2].toDouble() * 1000000l));
//buildFrame.len = frameParsed[3].length() * 0.5; //buildFrame.len = frameParsed[3].length() * 0.5;
if(frameParsed.length() < 4)
{
qDebug() << "Received frame doesn't contain any data: " << data;
return data;
}
int framelength = frameParsed[3].length() * 0.5; int framelength = frameParsed[3].length() * 0.5;
buildData.resize(framelength); buildData.resize(framelength);
@@ -302,9 +325,14 @@ void SocketCANd::decodeFrames(QString data, int busNum)
else else
qDebug() << "can't get a frame, capture suspended"; qDebug() << "can't get a frame, capture suspended";
//take out the data that we just processed and anything that is in front of it
//this should keep broken frames from accumulating at in the data buffer
if (framePart.length() > frameStrConst.length()) if (framePart.length() > frameStrConst.length())
decodeFrames(framePart.right(framePart.length() - frameStrConst.length()), busNum); {
return decodeFrames(framePart.right(framePart.length() - frameStrConst.length()), busNum);
} }
return "";
} }
void SocketCANd::disconnectDevice() { void SocketCANd::disconnectDevice() {
@@ -374,6 +402,7 @@ void SocketCANd::procRXData(QString data, int busNum)
{ {
switchToRawMode(busNum); switchToRawMode(busNum);
rx_state[busNum] = SWITCHING2RAW; rx_state[busNum] = SWITCHING2RAW;
unprocessedData[busNum].clear();
} }
else qInfo() << hostCanIDs[busNum] << ": Could not open bus. Host did not respond with ""< ok >"": " << data; else qInfo() << hostCanIDs[busNum] << ": Could not open bus. Host did not respond with ""< ok >"": " << data;
break; break;
@@ -383,9 +412,30 @@ void SocketCANd::procRXData(QString data, int busNum)
{ {
rx_state[busNum] = RAWMODE; rx_state[busNum] = RAWMODE;
} }
else if(data.indexOf("< ok >", 0, Qt::CaseSensitivity::CaseInsensitive) == 0)
{
qDebug() << "Ok found at start of compound message, switching to RAW and decoding immediately";
rx_state[busNum] = RAWMODE;
unprocessedData[busNum] = decodeFrames(data, busNum);
}
else if(data.indexOf("< ok >", 0, Qt::CaseSensitivity::CaseInsensitive) > 0)
{
qDebug() << "Ok found at in middle of compound message, switching to RAW and decoding immediately";
rx_state[busNum] = RAWMODE;
unprocessedData[busNum] = decodeFrames(data, busNum);
}
break; break;
case RAWMODE: case RAWMODE:
decodeFrames(data, busNum); unprocessedData[busNum] = decodeFrames(unprocessedData[busNum] + data, busNum);
if(unprocessedData[busNum].length() > 128)
{
//the buffer has grown too much we need to clear it out, but what is good logic for that?
//the decodeFrames function strips out datat that doesn't have a '< frame' starting token, and in its
//recursive calling of itself it strips out data that preceedes valid frames, so this should never happen
qDebug() << "busNum: " << busNum << "- " << unprocessedData[busNum].length() << " bytes in unprocessedData, something is wrong, clearing...";
unprocessedData[busNum].clear();
}
break; break;
case ISOTP: case ISOTP:
break; break;
+2 -1
View File
@@ -57,7 +57,7 @@ private slots:
void invokeReadTCPData(); void invokeReadTCPData();
void deviceConnected(int busNum); void deviceConnected(int busNum);
void switchToRawMode(int busNum); void switchToRawMode(int busNum);
void decodeFrames(QString, int busNum); QString decodeFrames(QString, int busNum);
private: private:
void procRXData(QString, int busNum); void procRXData(QString, int busNum);
@@ -76,6 +76,7 @@ protected:
QByteArray buildData; QByteArray buildData;
QVarLengthArray<MODE> rx_state; QVarLengthArray<MODE> rx_state;
CANFrame buildFrame; CANFrame buildFrame;
QVarLengthArray<QString> unprocessedData;
}; };
+32 -12
View File
@@ -100,8 +100,15 @@ void DBCSignalHandler::sort()
DBC_MESSAGE* DBCMessageHandler::findMsgByID(uint32_t id) DBC_MESSAGE* DBCMessageHandler::findMsgByID(uint32_t id)
{ {
if (messages.count() == 0) return nullptr; if (messages.count() == 0) return nullptr;
DBC_MESSAGE *bestMatch = nullptr;
for (int i = 0; i < messages.count(); i++) for (int i = 0; i < messages.count(); i++)
{ {
if ( messages[i].ID == id )
{
return &messages[i];
}
if (matchingCriteria == J1939) if (matchingCriteria == J1939)
{ {
// include data page and extended data page in the pgn // include data page and extended data page in the pgn
@@ -112,7 +119,7 @@ DBC_MESSAGE* DBCMessageHandler::findMsgByID(uint32_t id)
pgn &= 0x3FF00; pgn &= 0x3FF00;
if ((messages[i].ID & 0x3FF0000) == (pgn << 8)) if ((messages[i].ID & 0x3FF0000) == (pgn << 8))
{ {
return &messages[i]; bestMatch = &messages[i];
} }
} }
else else
@@ -120,7 +127,7 @@ DBC_MESSAGE* DBCMessageHandler::findMsgByID(uint32_t id)
// PDU2 format // PDU2 format
if ((messages[i].ID & 0x3FFFF00) == (pgn << 8)) if ((messages[i].ID & 0x3FFFF00) == (pgn << 8))
{ {
return &messages[i]; bestMatch = &messages[i];
} }
} }
} }
@@ -129,17 +136,10 @@ DBC_MESSAGE* DBCMessageHandler::findMsgByID(uint32_t id)
// Match the bits 14-26 (Arbitration Id) of GMLAN 29bit header // Match the bits 14-26 (Arbitration Id) of GMLAN 29bit header
uint32_t arbId = id &0x3FFE000; uint32_t arbId = id &0x3FFE000;
if ( (arbId != 0) && (messages[i].ID & 0x3FFE000) == arbId ) if ( (arbId != 0) && (messages[i].ID & 0x3FFE000) == arbId )
return &messages[i]; bestMatch = &messages[i];
}
else
{
if ( messages[i].ID == id )
{
return &messages[i];
} }
} }
} return bestMatch;
return nullptr;
} }
DBC_MESSAGE* DBCMessageHandler::findMsgByIdx(int idx) DBC_MESSAGE* DBCMessageHandler::findMsgByIdx(int idx)
@@ -192,6 +192,7 @@ bool DBCMessageHandler::removeMessage(DBC_MESSAGE *msg)
{ {
messages.removeAt(i); messages.removeAt(i);
qDebug() << "Removed message at idx " << i; qDebug() << "Removed message at idx " << i;
break;
} }
} }
return true; return true;
@@ -336,7 +337,26 @@ DBC_NODE* DBCFile::findNodeByName(QString name)
if (dbc_nodes.length() == 0) return nullptr; if (dbc_nodes.length() == 0) return nullptr;
for (int i = 0; i < dbc_nodes.length(); i++) for (int i = 0; i < dbc_nodes.length(); i++)
{ {
if (dbc_nodes[i].name.compare(name, Qt::CaseInsensitive) == 0) if (name.compare(dbc_nodes[i].name, Qt::CaseInsensitive) == 0)
{
return &dbc_nodes[i];
}
}
return nullptr;
}
DBC_NODE* DBCFile::findNodeByNameAndComment(QString fullname)
{
QString nameAndComment;
if (dbc_nodes.length() == 0) return nullptr;
for (int i = 0; i < dbc_nodes.length(); i++)
{
if(dbc_nodes[i].comment.isEmpty())
nameAndComment = dbc_nodes[i].name;
else
nameAndComment = dbc_nodes[i].name + " - " + dbc_nodes[i].comment;
if (fullname.compare(nameAndComment, Qt::CaseInsensitive) == 0)
{ {
return &dbc_nodes[i]; return &dbc_nodes[i];
} }
+1
View File
@@ -72,6 +72,7 @@ public:
DBCFile(const DBCFile& cpy); DBCFile(const DBCFile& cpy);
DBCFile& operator=(const DBCFile& cpy); DBCFile& operator=(const DBCFile& cpy);
DBC_NODE *findNodeByName(QString name); DBC_NODE *findNodeByName(QString name);
DBC_NODE *findNodeByNameAndComment(QString fullname);
DBC_NODE *findNodeByIdx(int idx); DBC_NODE *findNodeByIdx(int idx);
DBC_ATTRIBUTE *findAttributeByName(QString name, DBC_ATTRIBUTE_TYPE type = ATTR_TYPE_ANY); DBC_ATTRIBUTE *findAttributeByName(QString name, DBC_ATTRIBUTE_TYPE type = ATTR_TYPE_ANY);
DBC_ATTRIBUTE *findAttributeByIdx(int idx); DBC_ATTRIBUTE *findAttributeByIdx(int idx);
+3 -2
View File
@@ -631,7 +631,7 @@ void DBCMainEditor::deleteCurrentTreeItem()
{ {
QTreeWidgetItem *currItem = ui->treeDBC->currentItem(); QTreeWidgetItem *currItem = ui->treeDBC->currentItem();
int typ = currItem->data(0, Qt::UserRole).toInt(); int typ = currItem->data(0, Qt::UserRole).toInt();
QString idString; QString idString, columnText;
int msgID; int msgID;
DBC_MESSAGE *msg; DBC_MESSAGE *msg;
DBC_NODE *node; DBC_NODE *node;
@@ -642,7 +642,8 @@ void DBCMainEditor::deleteCurrentTreeItem()
switch (typ) switch (typ)
{ {
case 1: //deleting a node cascades deletion down to messages and signals case 1: //deleting a node cascades deletion down to messages and signals
node = dbcFile->findNodeByName(currItem->text(0)); columnText = currItem->text(0);
node = dbcFile->findNodeByNameAndComment(columnText);
if (!node) return; if (!node) return;
for (int x = 0; x < dbcFile->messageHandler->getCount(); x++) for (int x = 0; x < dbcFile->messageHandler->getCount(); x++)
{ {
+3
View File
@@ -111,8 +111,11 @@ void DBCNodeEditor::showEvent(QShowEvent* event)
void DBCNodeEditor::refreshView() void DBCNodeEditor::refreshView()
{ {
if(dbcNode)
{
ui->lineComment->setText(dbcNode->comment); ui->lineComment->setText(dbcNode->comment);
ui->lineMsgName->setText(dbcNode->name); ui->lineMsgName->setText(dbcNode->name);
}
//generateSampleText(); //generateSampleText();
} }
+5 -1
View File
@@ -898,7 +898,11 @@ void FrameSenderWindow::processCellChange(int line, int col)
case 6: //Data bytes case 6: //Data bytes
for (int i = 0; i < 8; i++) sendingData[line].payload().data()[i] = 0; for (int i = 0; i < 8; i++) sendingData[line].payload().data()[i] = 0;
tokens = ui->tableSender->item(line, 6)->text().split(" "); #if QT_VERSION >= QT_VERSION_CHECK( 5, 14, 0 )
tokens = ui->tableSender->item(line, 6)->text().split(" ", Qt::SkipEmptyParts);
#else
tokens = ui->tableSender->item(line, 6)->text().split(" ", QString::SkipEmptyParts);
#endif
arr.clear(); arr.clear();
arr.reserve(tokens.count()); arr.reserve(tokens.count());
for (int j = 0; j < tokens.count(); j++) for (int j = 0; j < tokens.count(); j++)
+2 -1
View File
@@ -931,7 +931,8 @@ void JSEdit::resizeEvent(QResizeEvent *e)
void JSEdit::wheelEvent(QWheelEvent *e) void JSEdit::wheelEvent(QWheelEvent *e)
{ {
if (e->modifiers() == Qt::ControlModifier) { if (e->modifiers() == Qt::ControlModifier) {
int steps = e->delta() / 20; QPoint numDegrees = e->angleDelta();
int steps = numDegrees.y() / 20;
steps = qBound(-3, steps, 3); steps = qBound(-3, steps, 3);
QFont textFont = font(); QFont textFont = font();
int pointSize = textFont.pointSize() + steps; int pointSize = textFont.pointSize() + steps;
+19
View File
@@ -48,6 +48,7 @@ MainSettingsDialog::MainSettingsDialog(QWidget *parent) :
ui->cbLoadConnections->setChecked(settings.value("Main/SaveRestoreConnections", false).toBool()); ui->cbLoadConnections->setChecked(settings.value("Main/SaveRestoreConnections", false).toBool());
ui->spinFontSize->setValue(settings.value("Main/FontSize", ui->cbDisplayHex->font().pointSize()).toUInt()); ui->spinFontSize->setValue(settings.value("Main/FontSize", ui->cbDisplayHex->font().pointSize()).toUInt());
ui->cbFontFixedWidth->setChecked(settings.value("Main/FontFixedWidth", false).toBool());
bool secondsMode = settings.value("Main/TimeSeconds", false).toBool(); bool secondsMode = settings.value("Main/TimeSeconds", false).toBool();
bool clockMode = settings.value("Main/TimeClock", false).toBool(); bool clockMode = settings.value("Main/TimeClock", false).toBool();
@@ -90,6 +91,20 @@ MainSettingsDialog::MainSettingsDialog(QWidget *parent) :
ui->cbFilterLabeling->setChecked(settings.value("Main/FilterLabeling", true).toBool()); ui->cbFilterLabeling->setChecked(settings.value("Main/FilterLabeling", true).toBool());
ui->cbIgnoreDBCColors->setChecked(settings.value("Main/IgnoreDBCColors", false).toBool()); ui->cbIgnoreDBCColors->setChecked(settings.value("Main/IgnoreDBCColors", false).toBool());
int maxFramesDefault;
if (QSysInfo::WordSize > 32)
{
qDebug() << "64 bit OS detected. Requesting a large preallocation";
maxFramesDefault = 10000000;
}
else //if compiling for 32 bit you can't ask for gigabytes of preallocation so tone it down.
{
qDebug() << "32 bit OS detected. Requesting a much restricted prealloc";
maxFramesDefault = 2000000;
}
ui->spinMaximumFrames->setValue(settings.value("Main/MaximumFrames", maxFramesDefault).toInt());
//just for simplicity they all call the same function and that function updates all settings at once //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())); connect(ui->cbDisplayHex, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
connect(ui->cbFlowAutoRef, SIGNAL(toggled(bool)), this, SLOT(updateSettings())); connect(ui->cbFlowAutoRef, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
@@ -117,6 +132,8 @@ MainSettingsDialog::MainSettingsDialog(QWidget *parent) :
connect(ui->cbHexGraphFlow, SIGNAL(toggled(bool)), this, SLOT(updateSettings())); connect(ui->cbHexGraphFlow, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
connect(ui->cbHexGraphInfo, SIGNAL(toggled(bool)), this, SLOT(updateSettings())); connect(ui->cbHexGraphInfo, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
connect(ui->cbIgnoreDBCColors, SIGNAL(toggled(bool)), this, SLOT(updateSettings())); connect(ui->cbIgnoreDBCColors, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
connect(ui->spinMaximumFrames, SIGNAL(valueChanged(int)), this, SLOT(updateSettings()));
connect(ui->cbFontFixedWidth, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
installEventFilter(this); installEventFilter(this);
} }
@@ -183,6 +200,8 @@ void MainSettingsDialog::updateSettings()
settings.setValue("Remote/Pass", encPass); settings.setValue("Remote/Pass", encPass);
settings.setValue("Main/FilterLabeling", ui->cbFilterLabeling->isChecked()); settings.setValue("Main/FilterLabeling", ui->cbFilterLabeling->isChecked());
settings.setValue("Main/IgnoreDBCColors", ui->cbIgnoreDBCColors->isChecked()); settings.setValue("Main/IgnoreDBCColors", ui->cbIgnoreDBCColors->isChecked());
settings.setValue("Main/MaximumFrames", ui->spinMaximumFrames->value());
settings.setValue("Main/FontFixedWidth", ui->cbFontFixedWidth->isChecked());
settings.sync(); settings.sync();
emit updatedSettings(); emit updatedSettings();
+40 -4
View File
@@ -30,8 +30,10 @@ MainWindow::MainWindow(QWidget *parent) :
ui(new Ui::MainWindow) ui(new Ui::MainWindow)
{ {
ui->setupUi(this); ui->setupUi(this);
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
qRegisterMetaTypeStreamOperators<QVector<QString>>(); qRegisterMetaTypeStreamOperators<QVector<QString>>();
qRegisterMetaTypeStreamOperators<QVector<int>>(); qRegisterMetaTypeStreamOperators<QVector<int>>();
#endif
useHex = true; useHex = true;
@@ -55,12 +57,18 @@ MainWindow::MainWindow(QWidget *parent) :
verticalHeader->setSectionResizeMode(QHeaderView::Fixed); verticalHeader->setSectionResizeMode(QHeaderView::Fixed);
QSettings settings; QSettings settings;
int fontSize = settings.value("Main/FontSize", 9).toUInt(); int fontSize = settings.value("Main/FontSize", 9).toUInt();
QFont sysFont = QFont(); //get default font QFont sysFont;
if(settings.value("Main/FontFixedWidth", false).toBool())
sysFont = QFontDatabase::systemFont(QFontDatabase::FixedFont); //get default fixed width font
else
sysFont = QFont(); //get default font
sysFont.setPointSize(fontSize); sysFont.setPointSize(fontSize);
verticalHeader->setDefaultSectionSize(sysFont.pixelSize()); verticalHeader->setDefaultSectionSize(sysFont.pixelSize());
verticalHeader->setFont(QFont());
ui->canFramesView->setFont(sysFont); ui->canFramesView->setFont(sysFont);
QHeaderView *HorzHdr = ui->canFramesView->horizontalHeader(); QHeaderView *HorzHdr = ui->canFramesView->horizontalHeader();
HorzHdr->setFont(QFont());
HorzHdr->setStretchLastSection(true); //causes the data column to automatically fill the tableview HorzHdr->setStretchLastSection(true); //causes the data column to automatically fill the tableview
connect(HorzHdr, SIGNAL(sectionClicked(int)), this, SLOT(headerClicked(int))); connect(HorzHdr, SIGNAL(sectionClicked(int)), this, SLOT(headerClicked(int)));
@@ -141,6 +149,7 @@ MainWindow::MainWindow(QWidget *parent) :
connect(ui->cbInterpret, &QAbstractButton::toggled, this, &MainWindow::interpretToggled); connect(ui->cbInterpret, &QAbstractButton::toggled, this, &MainWindow::interpretToggled);
connect(ui->cbOverwrite, &QAbstractButton::toggled, this, &MainWindow::overwriteToggled); connect(ui->cbOverwrite, &QAbstractButton::toggled, this, &MainWindow::overwriteToggled);
connect(ui->cbPersistentFilters, &QAbstractButton::toggled, this, &MainWindow::presistentFiltersToggled);
connect(ui->listFilters, &QListWidget::itemChanged, this, &MainWindow::filterListItemChanged); connect(ui->listFilters, &QListWidget::itemChanged, this, &MainWindow::filterListItemChanged);
connect(ui->listBusFilters, &QListWidget::itemChanged, this, &MainWindow::busFilterListItemChanged); connect(ui->listBusFilters, &QListWidget::itemChanged, this, &MainWindow::busFilterListItemChanged);
@@ -177,7 +186,7 @@ MainWindow::MainWindow(QWidget *parent) :
updateTimer.setInterval(250); updateTimer.setInterval(250);
updateTimer.start(); updateTimer.start();
elapsedTime = new QTime; elapsedTime = new QElapsedTimer;
elapsedTime->start(); elapsedTime->start();
isConnected = false; isConnected = false;
@@ -616,6 +625,18 @@ void MainWindow::overwriteToggled(bool state)
} }
} }
void MainWindow::presistentFiltersToggled(bool state)
{
if (state)
{
model->setClearMode(true);
}
else
{
model->setClearMode(false);
}
}
void MainWindow::updateFilterList() void MainWindow::updateFilterList()
{ {
if (model == nullptr) return; if (model == nullptr) return;
@@ -1146,11 +1167,26 @@ void MainWindow::showTemporalGraphWindow()
//only create an instance of the object if we dont have one. Otherwise just display the existing one. //only create an instance of the object if we dont have one. Otherwise just display the existing one.
if (!temporalGraphWindow) if (!temporalGraphWindow)
{ {
const QVector<CANFrame> *frames;
if (!useFiltered) if (!useFiltered)
temporalGraphWindow = new TemporalGraphWindow(model->getListReference()); frames = model->getListReference();
else else
temporalGraphWindow = new TemporalGraphWindow(model->getFilteredListReference()); frames = model->getFilteredListReference();
if(frames->count() > 2000)
{
QMessageBox::StandardButton confirmDialog;
confirmDialog = QMessageBox::question(this, "Danger Will Robinson", "There are a lot of frames (>2000) to plot, this may take a while or crash the app. Crash likely with more than 10k frames. Continue?",
QMessageBox::Yes|QMessageBox::No);
if (confirmDialog == QMessageBox::No)
{
return;
} }
}
temporalGraphWindow = new TemporalGraphWindow(frames);
}
temporalGraphWindow->show(); temporalGraphWindow->show();
} }
+2 -1
View File
@@ -99,6 +99,7 @@ private slots:
void setupSendToLatestGraphWindow(); void setupSendToLatestGraphWindow();
void interpretToggled(bool); void interpretToggled(bool);
void overwriteToggled(bool); void overwriteToggled(bool);
void presistentFiltersToggled(bool state);
void logReceivedFrame(CANConnection*, QVector<CANFrame>); void logReceivedFrame(CANConnection*, QVector<CANFrame>);
void tickGUIUpdate(); void tickGUIUpdate();
void toggleCapture(); void toggleCapture();
@@ -137,7 +138,7 @@ private:
DBCHandler *dbcHandler; DBCHandler *dbcHandler;
QByteArray inputBuffer; QByteArray inputBuffer;
QTimer updateTimer; QTimer updateTimer;
QTime *elapsedTime; QElapsedTimer *elapsedTime;
int framesPerSec; int framesPerSec;
int rxFrames; int rxFrames;
bool inhibitFilterUpdate; bool inhibitFilterUpdate;
+1 -1
View File
@@ -129,7 +129,7 @@ class Q_MQTT_EXPORT Client : public QObject
Q_PROPERTY(quint8 _willQos READ willQos WRITE setWillQos) Q_PROPERTY(quint8 _willQos READ willQos WRITE setWillQos)
Q_PROPERTY(bool _willRetain READ willRetain WRITE setWillRetain) Q_PROPERTY(bool _willRetain READ willRetain WRITE setWillRetain)
Q_PROPERTY(QByteArray _willMessage READ willMessage WRITE setWillMessage) Q_PROPERTY(QByteArray _willMessage READ willMessage WRITE setWillMessage)
Q_PROPERTY(QString _connectionState READ connectionState) Q_PROPERTY(ConnectionState _connectionState READ connectionState)
#ifndef QT_NO_SSL #ifndef QT_NO_SSL
Q_PROPERTY(QSslConfiguration _sslConfiguration READ sslConfiguration WRITE setSslConfiguration) Q_PROPERTY(QSslConfiguration _sslConfiguration READ sslConfiguration WRITE setSslConfiguration)
#endif // QT_NO_SSL #endif // QT_NO_SSL
+2 -2
View File
@@ -41,9 +41,9 @@ QMQTT::Socket::Socket(QObject* parent)
connect(_socket.data(), &QTcpSocket::connected, this, &SocketInterface::connected); connect(_socket.data(), &QTcpSocket::connected, this, &SocketInterface::connected);
connect(_socket.data(), &QTcpSocket::disconnected, this, &SocketInterface::disconnected); connect(_socket.data(), &QTcpSocket::disconnected, this, &SocketInterface::disconnected);
connect(_socket.data(), connect(_socket.data(),
static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)>(&QTcpSocket::error), SIGNAL(error(QTcpSocket::error)),
this, this,
static_cast<void (SocketInterface::*)(QAbstractSocket::SocketError)>(&SocketInterface::error)); SLOT(errorHandler(SocketInterface::error)));
} }
QMQTT::Socket::~Socket() QMQTT::Socket::~Socket()
+2 -2
View File
@@ -46,9 +46,9 @@ QMQTT::SslSocket::SslSocket(const QSslConfiguration& config, QObject* parent)
connect(_socket.data(), &QSslSocket::encrypted, this, &SocketInterface::connected); connect(_socket.data(), &QSslSocket::encrypted, this, &SocketInterface::connected);
connect(_socket.data(), &QSslSocket::disconnected, this, &SocketInterface::disconnected); connect(_socket.data(), &QSslSocket::disconnected, this, &SocketInterface::disconnected);
connect(_socket.data(), connect(_socket.data(),
static_cast<void (QSslSocket::*)(QAbstractSocket::SocketError)>(&QSslSocket::error), SIGNAL(error(QSslSocket::error)),
this, this,
static_cast<void (SocketInterface::*)(QAbstractSocket::SocketError)>(&SocketInterface::error)); SLOT(errorHandler(SocketInterface::error)));
connect(_socket.data(), connect(_socket.data(),
static_cast<void (QSslSocket::*)(const QList<QSslError>&)>(&QSslSocket::sslErrors), static_cast<void (QSslSocket::*)(const QList<QSslError>&)>(&QSslSocket::sslErrors),
this, this,
+16 -28
View File
@@ -156,26 +156,8 @@ class QCPPolarGraph;
It provides QMetaObject-based reflection of its enums and flags via \a QCP::staticMetaObject. It provides QMetaObject-based reflection of its enums and flags via \a QCP::staticMetaObject.
*/ */
#ifndef Q_MOC_RUN
namespace QCP { namespace QCP {
#else Q_NAMESPACE
class QCP { // when in moc-run, make it look like a class, so we get Q_GADGET, Q_ENUMS/Q_FLAGS features in namespace
Q_GADGET
Q_ENUMS(ExportPen)
Q_ENUMS(ResolutionUnit)
Q_ENUMS(SignDomain)
Q_ENUMS(MarginSide)
Q_FLAGS(MarginSides)
Q_ENUMS(AntialiasedElement)
Q_FLAGS(AntialiasedElements)
Q_ENUMS(PlottingHint)
Q_FLAGS(PlottingHints)
Q_ENUMS(Interaction)
Q_FLAGS(Interactions)
Q_ENUMS(SelectionRectMode)
Q_ENUMS(SelectionType)
public:
#endif
/*! /*!
Defines the different units in which the image resolution can be specified in the export Defines the different units in which the image resolution can be specified in the export
@@ -318,6 +300,20 @@ enum SelectionType { stNone ///< The plottable is not selectable
,stMultipleDataRanges ///< Any combination of data points/ranges can be selected ,stMultipleDataRanges ///< Any combination of data points/ranges can be selected
}; };
Q_ENUM_NS(ExportPen)
Q_ENUM_NS(ResolutionUnit)
Q_ENUM_NS(SignDomain)
Q_ENUM_NS(MarginSide)
Q_FLAG_NS(MarginSides)
Q_ENUM_NS(AntialiasedElement)
Q_FLAG_NS(AntialiasedElements)
Q_ENUM_NS(PlottingHint)
Q_FLAG_NS(PlottingHints)
Q_ENUM_NS(Interaction)
Q_FLAG_NS(Interactions)
Q_ENUM_NS(SelectionRectMode)
Q_ENUM_NS(SelectionType)
/*! \internal /*! \internal
Returns whether the specified \a value is considered an invalid data value for plottables (i.e. Returns whether the specified \a value is considered an invalid data value for plottables (i.e.
@@ -386,15 +382,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::AntialiasedElements)
Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::PlottingHints) Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::PlottingHints)
Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::MarginSides) Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::MarginSides)
Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::Interactions) Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::Interactions)
Q_DECLARE_METATYPE(QCP::ExportPen) //no need to use Q_DECLARE_METATYPE on enum since Q_ENUM_NS adds enum as metatype automatically
Q_DECLARE_METATYPE(QCP::ResolutionUnit)
Q_DECLARE_METATYPE(QCP::SignDomain)
Q_DECLARE_METATYPE(QCP::MarginSide)
Q_DECLARE_METATYPE(QCP::AntialiasedElement)
Q_DECLARE_METATYPE(QCP::PlottingHint)
Q_DECLARE_METATYPE(QCP::Interaction)
Q_DECLARE_METATYPE(QCP::SelectionRectMode)
Q_DECLARE_METATYPE(QCP::SelectionType)
/* end of 'src/global.h' */ /* end of 'src/global.h' */
+2 -2
View File
@@ -2,7 +2,7 @@
#define SNIFFERITEM_H #define SNIFFERITEM_H
#include <QVariant> #include <QVariant>
#include <QTime> #include <QElapsedTimer>
#include "can_structs.h" #include "can_structs.h"
struct fstCan struct fstCan
@@ -50,7 +50,7 @@ private:
quint64 mCurrentTime; quint64 mCurrentTime;
quint64 mCurrSeqVal; quint64 mCurrSeqVal;
QTime mTime; QElapsedTimer mTime;
}; };
#endif // SNIFFERITEM_H #endif // SNIFFERITEM_H
+1 -1
View File
@@ -137,7 +137,7 @@ QVariant SnifferModel::data(const QModelIndex &index, int role) const
Qt::ItemFlags SnifferModel::flags(const QModelIndex &index) const Qt::ItemFlags SnifferModel::flags(const QModelIndex &index) const
{ {
if (!index.isValid()) if (!index.isValid())
return 0; return Qt::NoItemFlags;
return QAbstractItemModel::flags(index); return QAbstractItemModel::flags(index);
} }
+10 -1
View File
@@ -4,6 +4,9 @@
#include <QFile> #include <QFile>
#include <QFileDialog> #include <QFileDialog>
#include <QSettings> #include <QSettings>
#if QT_VERSION >= QT_VERSION_CHECK( 5, 10, 0 )
#include <QtCore/QRandomGenerator>
#endif
#include "connections/canconmanager.h" #include "connections/canconmanager.h"
#include "helpwindow.h" #include "helpwindow.h"
@@ -234,7 +237,13 @@ void ScriptingWindow::createNewScript()
container = new ScriptContainer(); container = new ScriptContainer();
container->fileName = "UNNAMED_" + QString::number((qrand() % 10000)) + ".js"; QString randomPart;
#if QT_VERSION < QT_VERSION_CHECK( 5, 10, 0 )
randomPart = QString::number((qrand() % 10000));
#else
randomPart = QString::number((QRandomGenerator::global()->bounded(10000)));
#endif
container->fileName = "UNNAMED_" + randomPart + ".js";
container->filePath = QString(); container->filePath = QString();
container->scriptText = QString(); container->scriptText = QString();
container->setScriptWindow(this); container->setScriptWindow(this);
+251 -10
View File
@@ -4,6 +4,9 @@
#include "mainwindow.h" #include "mainwindow.h"
#include <QDebug> #include <QDebug>
#define MSG_COL 1
#define VALUE_COL 2
SignalViewerWindow::SignalViewerWindow(const QVector<CANFrame> *frames, QWidget *parent) : SignalViewerWindow::SignalViewerWindow(const QVector<CANFrame> *frames, QWidget *parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::SignalViewerWindow) ui(new Ui::SignalViewerWindow)
@@ -14,21 +17,41 @@ SignalViewerWindow::SignalViewerWindow(const QVector<CANFrame> *frames, QWidget
modelFrames = frames; modelFrames = frames;
QStringList headers; QStringList headers;
headers << "Signal" << "Value"; headers << "Node" << "Signal" << "Value";
ui->tableViewer->setHorizontalHeaderLabels(headers); ui->tableViewer->setHorizontalHeaderLabels(headers);
ui->tableViewer->setColumnWidth(0, 150); ui->tableViewer->setColumnWidth(0, 100);
ui->tableViewer->setColumnWidth(1, 300); ui->tableViewer->setColumnWidth(1, 150);
QSettings settings;
QFont sysFont;
int fontSize = settings.value("Main/FontSize", 9).toUInt();
if(settings.value("Main/FontFixedWidth", false).toBool())
sysFont = QFontDatabase::systemFont(QFontDatabase::FixedFont); //get default fixed width font
else
sysFont = QFont(); //get default font
sysFont.setPointSize(fontSize);
ui->tableViewer->setFont(sysFont);
QHeaderView *HorzHdr = ui->tableViewer->horizontalHeader(); QHeaderView *HorzHdr = ui->tableViewer->horizontalHeader();
HorzHdr->setStretchLastSection(true); //causes the data column to automatically fill the tableview HorzHdr->setStretchLastSection(true); //causes the data column to automatically fill the tableview
HorzHdr->setFont(QFont());
QHeaderView *verticalHeader = ui->tableViewer->verticalHeader();
verticalHeader->setFont(QFont());
dbcHandler = DBCHandler::getReference(); dbcHandler = DBCHandler::getReference();
connect(ui->cbNodes, SIGNAL(currentIndexChanged(int)), this, SLOT(loadMessages(int)));
connect(ui->cbMessages, SIGNAL(currentIndexChanged(int)), this, SLOT(loadSignals(int))); connect(ui->cbMessages, SIGNAL(currentIndexChanged(int)), this, SLOT(loadSignals(int)));
connect(ui->btnAdd, SIGNAL(clicked(bool)), this, SLOT(addSignal())); connect(ui->btnAdd, SIGNAL(clicked(bool)), this, SLOT(addSignal()));
connect(MainWindow::getReference(), SIGNAL(framesUpdated(int)), this, SLOT(updatedFrames(int))); connect(MainWindow::getReference(), SIGNAL(framesUpdated(int)), this, SLOT(updatedFrames(int)));
connect(ui->btnRemove, SIGNAL(clicked(bool)), this, SLOT(removeSelectedSignal())); connect(ui->btnRemove, SIGNAL(clicked(bool)), this, SLOT(removeSelectedSignal()));
connect(ui->btnSave, SIGNAL(clicked(bool)), this, SLOT(saveSignalsFile()));
connect(ui->btnLoad, SIGNAL(clicked(bool)), this, SLOT(loadSignalsFile()));
connect(ui->btnAppend, SIGNAL(clicked(bool)), this, SLOT(appendSignalsFile()));
connect(ui->btnClear, SIGNAL(clicked(bool)), this, SLOT(clearSignalsTable()));
loadMessages(); loadNodes();
} }
SignalViewerWindow::~SignalViewerWindow() SignalViewerWindow::~SignalViewerWindow()
@@ -75,11 +98,11 @@ void SignalViewerWindow::processFrame(CANFrame &frame)
{ {
if (sig->processAsText(frame, sigString, false)) //if true we could interpret the signal so update it in the list if (sig->processAsText(frame, sigString, false)) //if true we could interpret the signal so update it in the list
{ {
QTableWidgetItem *item = ui->tableViewer->item(i, 1); QTableWidgetItem *item = ui->tableViewer->item(i, VALUE_COL);
if (!item) if (!item)
{ {
item = new QTableWidgetItem(sigString); item = new QTableWidgetItem(sigString);
ui->tableViewer->setItem(i, 1, item); ui->tableViewer->setItem(i, VALUE_COL, item);
} }
else item->setText(sigString); else item->setText(sigString);
} }
@@ -95,18 +118,66 @@ void SignalViewerWindow::removeSelectedSignal()
ui->tableViewer->removeRow(selRow); ui->tableViewer->removeRow(selRow);
} }
void SignalViewerWindow::loadMessages() 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; int numFiles;
ui->cbMessages->clear(); ui->cbNodes->clear();
if (dbcHandler == nullptr) return; if (dbcHandler == nullptr) return;
if ((numFiles = dbcHandler->getFileCount()) == 0) return; if ((numFiles = dbcHandler->getFileCount()) == 0) return;
qDebug() << numFiles; qDebug() << numFiles;
for (int f = 0; f < numFiles; f++) for (int f = 0; f < numFiles; f++)
{ {
qDebug() << dbcHandler->getFileByIdx(f)->messageHandler->getCount(); qDebug() << dbcHandler->getFileByIdx(f)->messageHandler->getCount();
QList<QString> names;
for (int x = 0; x < dbcHandler->getFileByIdx(f)->dbc_nodes.count(); x++)
{
QString name = dbcHandler->getFileByIdx(f)->dbc_nodes[x].name;
if(name != "Vector__XXX")
names.append(name);
}
if(names.count() > 0)
{
names.sort();
ui->cbNodes->addItem("----" + dbcHandler->getFileByIdx(f)->getFilename());
SetComboBoxItemEnabled(ui->cbNodes, ui->cbNodes->count() -1, false);
for(int i=0; i<names.count(); i++)
ui->cbNodes->addItem(names[i]);
}
}
}
void SignalViewerWindow::loadMessages(int idx)
{
int numFiles;
ui->cbMessages->clear();
if (dbcHandler == nullptr) return;
if ((numFiles = dbcHandler->getFileCount()) == 0) return;
qDebug() << numFiles;
QString nodeName = ui->cbNodes->itemText(idx);
for (int f = 0; f < numFiles; f++)
{
qDebug() << dbcHandler->getFileByIdx(f)->messageHandler->getCount();
for (int x = 0; x < dbcHandler->getFileByIdx(f)->messageHandler->getCount(); x++) for (int x = 0; x < dbcHandler->getFileByIdx(f)->messageHandler->getCount(); x++)
{ {
if(dbcHandler->getFileByIdx(f)->messageHandler->findMsgByIdx(x)->sender->name == nodeName)
ui->cbMessages->addItem(dbcHandler->getFileByIdx(f)->messageHandler->findMsgByIdx(x)->name); ui->cbMessages->addItem(dbcHandler->getFileByIdx(f)->messageHandler->findMsgByIdx(x)->name);
} }
} }
@@ -136,11 +207,181 @@ void SignalViewerWindow::addSignal()
DBC_SIGNAL *sig = msg->sigHandler->findSignalByName(ui->cbSignals->currentText()); DBC_SIGNAL *sig = msg->sigHandler->findSignalByName(ui->cbSignals->currentText());
if (!sig) return; if (!sig) return;
addSignal(sig);
}
void SignalViewerWindow::addSignal(DBC_SIGNAL *sig)
{
signalList.append(sig); signalList.append(sig);
int rowIdx = ui->tableViewer->rowCount(); int rowIdx = ui->tableViewer->rowCount();
ui->tableViewer->insertRow(rowIdx); ui->tableViewer->insertRow(rowIdx);
QTableWidgetItem *item = new QTableWidgetItem(sig->name); QTableWidgetItem *nodeitem = new QTableWidgetItem(sig->parentMessage->sender->name);
ui->tableViewer->setItem(rowIdx, 0, item); ui->tableViewer->setItem(rowIdx, 0, nodeitem);
QTableWidgetItem *msgitem = new QTableWidgetItem(sig->name);
ui->tableViewer->setItem(rowIdx, 1, msgitem);
}
void SignalViewerWindow::saveSignalsFile()
{
saveDefinitions();
}
void SignalViewerWindow::loadSignalsFile()
{
loadDefinitions(false);
}
void SignalViewerWindow::appendSignalsFile()
{
loadDefinitions(true);
}
void SignalViewerWindow::clearSignalsTable()
{
clearSignalsTable(true);
}
void SignalViewerWindow::clearSignalsTable(bool askForConfirmation)
{
if(askForConfirmation)
{
QMessageBox::StandardButton confirmDialog;
confirmDialog = QMessageBox::question(this, "Danger Will Robinson", "Are you sure you want to clear all of your signals?",
QMessageBox::Yes|QMessageBox::No);
if (confirmDialog == QMessageBox::No)
{
return;
}
}
signalList.clear();
ui->tableViewer->setRowCount(0);
}
void SignalViewerWindow::saveDefinitions()
{
QString filename;
QFileDialog dialog(this);
QSettings settings;
QStringList filters;
filters.append(QString(tr("SignalViewer definition (*.sdf)")));
dialog.setFileMode(QFileDialog::AnyFile);
dialog.setNameFilters(filters);
dialog.setViewMode(QFileDialog::Detail);
dialog.setAcceptMode(QFileDialog::AcceptSave);
dialog.setDirectory(settings.value("SignalViewer/LoadSaveDirectory", dialog.directory().path()).toString());
if (dialog.exec() == QDialog::Accepted)
{
filename = dialog.selectedFiles()[0];
settings.setValue("SignalViewer/LoadSaveDirectory", dialog.directory().path());
if (!filename.contains('.')) filename += ".sdf";
QFile *outFile = new QFile(filename);
if (!outFile->open(QIODevice::WriteOnly | QIODevice::Text))
return;
DBC_SIGNAL *sig;
for (int i = 0; i < signalList.count(); i++)
{
sig = signalList.at(i);
outFile->write("SV1");
outFile->putChar(',');
outFile->write(QString::number(sig->parentMessage->ID, 16).toUtf8());
outFile->putChar(',');
outFile->write(sig->parentMessage->name.toUtf8());
outFile->putChar(',');
outFile->write(sig->name.toUtf8());
outFile->write("\n");
}
outFile->close();
}
}
void SignalViewerWindow::loadDefinitions(bool append)
{
QString filename;
QFileDialog dialog;
QSettings settings;
QStringList filters;
filters.append(QString(tr("SignalViewer definition (*.sdf)")));
QList<DBC_SIGNAL *> loadedSignals;
if (dbcHandler == nullptr) return;
if (dbcHandler->getFileCount() == 0) dbcHandler->createBlankFile();
dialog.setFileMode(QFileDialog::ExistingFile);
dialog.setNameFilters(filters);
dialog.setViewMode(QFileDialog::Detail);
dialog.setDirectory(settings.value("SignalViewer/LoadSaveDirectory", dialog.directory().path()).toString());
if (dialog.exec() == QDialog::Accepted)
{
filename = dialog.selectedFiles()[0];
settings.setValue("SignalViewer/LoadSaveDirectory", dialog.directory().path());
QFile *inFile = new QFile(filename);
QByteArray line;
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
return;
while (!inFile->atEnd()) {
line = inFile->readLine().simplified();
if (line.length() > 2)
{
QList<QByteArray> tokens = line.split(',');
DBC_SIGNAL *sig;
if (tokens[0] == "SV1") //signal viewer save format v1
{
// = tokens[1].toUInt(nullptr, 16);
int msgId = tokens[1].toUInt(nullptr, 16);
QString msgName = QString(tokens[2]);
QString sigName = QString(tokens[3]);
DBC_MESSAGE *msg;;
if (msg = dbcHandler->findMessage(msgName))
{
sig = msg->sigHandler->findSignalByName(sigName);
loadedSignals.append(sig);
}
else if(msg = dbcHandler->findMessage(msgId))
{
sig = msg->sigHandler->findSignalByName(sigName);
//fix anything up about the name?
loadedSignals.append(sig);
}
else
{
qDebug() << "Couldn't find the message by name! " << msgName << " " << sigName;
}
}
}
}
inFile->close();
if(loadedSignals.count() > 0)
{
if(append == false)
{
clearSignalsTable(false);
}
for (int i=0; i<loadedSignals.count(); i++)
{
addSignal(loadedSignals[i]);
}
}
}
} }
+10 -1
View File
@@ -17,11 +17,20 @@ public:
~SignalViewerWindow(); ~SignalViewerWindow();
private slots: private slots:
void loadMessages(); void loadNodes();
void loadMessages(int idx);
void loadSignals(int idx); void loadSignals(int idx);
void addSignal(); void addSignal();
void addSignal(DBC_SIGNAL *sig);
void removeSelectedSignal(); void removeSelectedSignal();
void updatedFrames(int); void updatedFrames(int);
void saveSignalsFile();
void loadSignalsFile();
void appendSignalsFile();
void clearSignalsTable();
void clearSignalsTable(bool);
void saveDefinitions();
void loadDefinitions(bool);
private: private:
Ui::SignalViewerWindow *ui; Ui::SignalViewerWindow *ui;
+12
View File
@@ -31,6 +31,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QDateTime> #include <QDateTime>
#include <QCryptographicHash> #include <QCryptographicHash>
#include <QDataStream> #include <QDataStream>
#include <QIODevice>
#if QT_VERSION >= QT_VERSION_CHECK( 5, 10, 0 )
#include <QtCore/QRandomGenerator>
#endif
SimpleCrypt::SimpleCrypt(): SimpleCrypt::SimpleCrypt():
m_key(0), m_key(0),
@@ -38,7 +42,9 @@ SimpleCrypt::SimpleCrypt():
m_protectionMode(ProtectionChecksum), m_protectionMode(ProtectionChecksum),
m_lastError(ErrorNoError) m_lastError(ErrorNoError)
{ {
#if QT_VERSION < QT_VERSION_CHECK( 5, 10, 0 )
qsrand(uint(QDateTime::currentMSecsSinceEpoch() & 0xFFFF)); qsrand(uint(QDateTime::currentMSecsSinceEpoch() & 0xFFFF));
#endif
} }
SimpleCrypt::SimpleCrypt(quint64 key): SimpleCrypt::SimpleCrypt(quint64 key):
@@ -47,7 +53,9 @@ SimpleCrypt::SimpleCrypt(quint64 key):
m_protectionMode(ProtectionChecksum), m_protectionMode(ProtectionChecksum),
m_lastError(ErrorNoError) m_lastError(ErrorNoError)
{ {
#if QT_VERSION < QT_VERSION_CHECK( 5, 10, 0 )
qsrand(uint(QDateTime::currentMSecsSinceEpoch() & 0xFFFF)); qsrand(uint(QDateTime::currentMSecsSinceEpoch() & 0xFFFF));
#endif
splitKey(); splitKey();
} }
@@ -113,7 +121,11 @@ QByteArray SimpleCrypt::encryptToByteArray(QByteArray plaintext)
} }
//prepend a random char to the string //prepend a random char to the string
#if QT_VERSION < QT_VERSION_CHECK( 5, 10, 0 )
char randomChar = char(qrand() & 0xFF); char randomChar = char(qrand() & 0xFF);
#else
char randomChar = char(QRandomGenerator::global()->bounded(256));
#endif
ba = randomChar + integrityProtection + ba; ba = randomChar + integrityProtection + ba;
int pos(0); int pos(0);
+49 -2
View File
@@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>965</width> <width>965</width>
<height>678</height> <height>713</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@@ -80,6 +80,39 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="topMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_10">
<property name="text">
<string>Maximum Frames to Capture</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinMaximumFrames">
<property name="minimum">
<number>100000</number>
</property>
<property name="maximum">
<number>1000000000</number>
</property>
<property name="singleStep">
<number>100000</number>
</property>
<property name="value">
<number>10000000</number>
</property>
</widget>
</item>
</layout>
</item>
<item> <item>
<widget class="QGroupBox" name="groupBox_6"> <widget class="QGroupBox" name="groupBox_6">
<property name="title"> <property name="title">
@@ -158,9 +191,23 @@
<item> <item>
<widget class="QGroupBox" name="groupBox_7"> <widget class="QGroupBox" name="groupBox_7">
<property name="title"> <property name="title">
<string>Font Size</string> <string>Font</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_8"> <layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QCheckBox" name="cbFontFixedWidth">
<property name="text">
<string>Use fixed-width font in tables</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_11">
<property name="text">
<string>Size</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QSpinBox" name="spinFontSize"> <widget class="QSpinBox" name="spinFontSize">
<property name="minimum"> <property name="minimum">
+7
View File
@@ -227,6 +227,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QCheckBox" name="cbPersistentFilters">
<property name="text">
<string>Keep Filters When Clearing</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QCheckBox" name="cbAutoScroll"> <widget class="QCheckBox" name="cbAutoScroll">
<property name="text"> <property name="text">
+43 -1
View File
@@ -18,8 +18,11 @@
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="verticalLayout_2">
<item> <item>
<widget class="QTableWidget" name="tableViewer"> <widget class="QTableWidget" name="tableViewer">
<property name="sortingEnabled">
<bool>true</bool>
</property>
<property name="columnCount"> <property name="columnCount">
<number>2</number> <number>3</number>
</property> </property>
<attribute name="horizontalHeaderDefaultSectionSize"> <attribute name="horizontalHeaderDefaultSectionSize">
<number>300</number> <number>300</number>
@@ -32,6 +35,7 @@
</attribute> </attribute>
<column/> <column/>
<column/> <column/>
<column/>
</widget> </widget>
</item> </item>
<item> <item>
@@ -45,6 +49,16 @@
</item> </item>
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Node</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cbNodes"/>
</item>
<item> <item>
<widget class="QLabel" name="label"> <widget class="QLabel" name="label">
<property name="text"> <property name="text">
@@ -85,6 +99,34 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item>
<widget class="QPushButton" name="btnSave">
<property name="text">
<string>Save View</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnLoad">
<property name="text">
<string>Load View</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnAppend">
<property name="text">
<string>Append to View</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnClear">
<property name="text">
<string>Clear View</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
</layout> </layout>