Merge branch 'master' of github.com:collin80/SavvyCAN
This commit is contained in:
+45
-8
@@ -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();
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
@@ -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];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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
@@ -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,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
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user