From 742956d46cd610515eb96a771d8b94ba8528cf5e Mon Sep 17 00:00:00 2001 From: Andy Huska Date: Sat, 17 Sep 2022 12:33:15 -0500 Subject: [PATCH 01/16] Working on finding a way to prevent bad_alloc crash, temp stuff in place like prealloc size, and frames list resize (prob need to keep list below size limit to prevent chaos...10M msgs or so mabe) --- canframemodel.cpp | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/canframemodel.cpp b/canframemodel.cpp index 735236b..4945679 100644 --- a/canframemodel.cpp +++ b/canframemodel.cpp @@ -49,7 +49,7 @@ CANFrameModel::CANFrameModel(QObject *parent) if (QSysInfo::WordSize > 32) { qDebug() << "64 bit OS detected. Requesting a large preallocation"; - preallocSize = 10000000; + preallocSize = 10000; //000; } else //if compiling for 32 bit you can't ask for gigabytes of preallocation so tone it down. { @@ -673,13 +673,39 @@ void CANFrameModel::addFrame(const CANFrame& frame, bool autoRefresh = false) if (!overwriteDups) { - frames.append(tempFrame); - if (filters[tempFrame.frameId()] && busFilters[tempFrame.bus]) + bool alloc_ok = true; + + for(int i=0; i<3; i++) { - if (autoRefresh) beginInsertRows(QModelIndex(), filteredFrames.count(), filteredFrames.count()); - tempFrame.frameCount = 1; - filteredFrames.append(tempFrame); - if (autoRefresh) endInsertRows(); + try + { + if(alloc_ok == false) + { + qDebug() << "Trying to remove " << (frames.length() >> 3) << " from frames. Try #" << i ; + frames.remove(0, frames.length() >> 3); + qDebug() << "frames length now: " << (frames.length()) << "trying to alloc again" ; + alloc_ok = true; + } + + frames.append(tempFrame); + break; + } + catch (const std::exception& ex) + { + alloc_ok = false; + qDebug() << "addFrame failed to append. frames.length(): " << frames.length() << " Exception: " << ex.what(); + } + } + + if(alloc_ok) + { + if (filters[tempFrame.frameId()] && busFilters[tempFrame.bus]) + { + if (autoRefresh) beginInsertRows(QModelIndex(), filteredFrames.count(), filteredFrames.count()); + tempFrame.frameCount = 1; + filteredFrames.append(tempFrame); + if (autoRefresh) endInsertRows(); + } } } else //yes, overwrite dups @@ -779,7 +805,7 @@ int CANFrameModel::sendBulkRefresh() if (lastUpdateNumFrames == 0 && !overwriteDups) return 0; if (filteredFrames.count() == 0) return 0; - qDebug() << "Bulk refresh of " << lastUpdateNumFrames; + //qDebug() << "Bulk refresh of " << lastUpdateNumFrames; beginResetModel(); endResetModel(); From 195c90c4154cd22ddb2e2b22489f14608e894f33 Mon Sep 17 00:00:00 2001 From: Andy Huska Date: Sun, 18 Sep 2022 13:01:34 -0500 Subject: [PATCH 02/16] change the max amount of the reserved space for the frames and filteredFrames vectors to be 99% of the capacity instead of 95%. Reset initial capacity to be 10M frames for 64-bit machines now that testing is done. Want to make the capacity adjustable by user, too. --- canframemodel.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/canframemodel.cpp b/canframemodel.cpp index 4945679..616978b 100644 --- a/canframemodel.cpp +++ b/canframemodel.cpp @@ -49,7 +49,7 @@ CANFrameModel::CANFrameModel(QObject *parent) if (QSysInfo::WordSize > 32) { qDebug() << "64 bit OS detected. Requesting a large preallocation"; - preallocSize = 10000; //000; + preallocSize = 10000000; } else //if compiling for 32 bit you can't ask for gigabytes of preallocation so tone it down. { @@ -679,14 +679,6 @@ void CANFrameModel::addFrame(const CANFrame& frame, bool autoRefresh = false) { try { - if(alloc_ok == false) - { - qDebug() << "Trying to remove " << (frames.length() >> 3) << " from frames. Try #" << i ; - frames.remove(0, frames.length() >> 3); - qDebug() << "frames length now: " << (frames.length()) << "trying to alloc again" ; - alloc_ok = true; - } - frames.append(tempFrame); break; } @@ -754,6 +746,20 @@ void CANFrameModel::addFrame(const CANFrame& frame, bool autoRefresh = false) void CANFrameModel::addFrames(const CANConnection*, const QVector& pFrames) { + if(frames.length() > frames.capacity() * 0.99) + { + qDebug() << "Frames count: " << frames.length() << " of " << frames.capacity() << " capacity, removing first " << frames.capacity() * 0.05 << " frames"; + frames.remove(0, 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 " << filteredFrames.capacity() * 0.05 << " frames"; + filteredFrames.remove(0, filteredFrames.capacity() * 0.05); + qDebug() << "filteredFrames removed, new count: " << filteredFrames.length(); + } + foreach(const CANFrame& frame, pFrames) { addFrame(frame); From d56b35ea91bf40be0af57cd6185917d3d1588b95 Mon Sep 17 00:00:00 2001 From: Andy Huska Date: Mon, 19 Sep 2022 13:10:33 -0500 Subject: [PATCH 03/16] Made max # of frames an option in preferences, restart to take effect --- canframemodel.cpp | 10 +++++++--- mainsettingsdialog.cpp | 16 ++++++++++++++++ ui/mainsettingsdialog.ui | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/canframemodel.cpp b/canframemodel.cpp index 616978b..c4a8309 100644 --- a/canframemodel.cpp +++ b/canframemodel.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "utility.h" CANFrameModel::~CANFrameModel() @@ -45,18 +46,21 @@ int CANFrameModel::columnCount(const QModelIndex &index) const CANFrameModel::CANFrameModel(QObject *parent) : QAbstractTableModel(parent) { - + int maxFramesDefault; if (QSysInfo::WordSize > 32) { 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. { qDebug() << "32 bit OS detected. Requesting a much restricted prealloc"; - preallocSize = 2000000; + maxFramesDefault = 2000000; } + QSettings settings; + int preallocSize = settings.value("Main/MaximumFrames", maxFramesDefault).toInt(); + frames.reserve(preallocSize); filteredFrames.reserve(preallocSize); //the goal is to prevent a reallocation from ever happening diff --git a/mainsettingsdialog.cpp b/mainsettingsdialog.cpp index 77bf257..2da44ed 100644 --- a/mainsettingsdialog.cpp +++ b/mainsettingsdialog.cpp @@ -90,6 +90,20 @@ MainSettingsDialog::MainSettingsDialog(QWidget *parent) : ui->cbFilterLabeling->setChecked(settings.value("Main/FilterLabeling", true).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 connect(ui->cbDisplayHex, SIGNAL(toggled(bool)), this, SLOT(updateSettings())); connect(ui->cbFlowAutoRef, SIGNAL(toggled(bool)), this, SLOT(updateSettings())); @@ -117,6 +131,7 @@ MainSettingsDialog::MainSettingsDialog(QWidget *parent) : connect(ui->cbHexGraphFlow, 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->spinMaximumFrames, SIGNAL(valueChanged(int)), this, SLOT(updateSettings())); installEventFilter(this); } @@ -183,6 +198,7 @@ void MainSettingsDialog::updateSettings() settings.setValue("Remote/Pass", encPass); settings.setValue("Main/FilterLabeling", ui->cbFilterLabeling->isChecked()); settings.setValue("Main/IgnoreDBCColors", ui->cbIgnoreDBCColors->isChecked()); + settings.setValue("Main/MaximumFrames", ui->spinMaximumFrames->value()); settings.sync(); emit updatedSettings(); diff --git a/ui/mainsettingsdialog.ui b/ui/mainsettingsdialog.ui index 586e4e0..d119b08 100644 --- a/ui/mainsettingsdialog.ui +++ b/ui/mainsettingsdialog.ui @@ -80,6 +80,39 @@ + + + + 0 + + + 0 + + + + + Maximum Frames to Capture + + + + + + + 100000 + + + 1000000000 + + + 100000 + + + 10000000 + + + + + From 6fa84df7e02aea58163ca215532444e1c286989e Mon Sep 17 00:00:00 2001 From: Andy Huska Date: Mon, 19 Sep 2022 13:31:00 -0500 Subject: [PATCH 04/16] Added ability to maintain bus and msg filters when clearing frames --- canframemodel.cpp | 13 +++++++++++-- canframemodel.h | 2 ++ mainwindow.cpp | 13 +++++++++++++ mainwindow.h | 1 + ui/mainwindow.ui | 7 +++++++ 5 files changed, 34 insertions(+), 2 deletions(-) diff --git a/canframemodel.cpp b/canframemodel.cpp index c4a8309..8ca4a5a 100644 --- a/canframemodel.cpp +++ b/canframemodel.cpp @@ -67,6 +67,7 @@ CANFrameModel::CANFrameModel(QObject *parent) dbcHandler = DBCHandler::getReference(); interpretFrames = false; overwriteDups = false; + filtersPersistDuringClear = false; useHexMode = true; timeSeconds = false; timeOffset = 0; @@ -200,6 +201,11 @@ void CANFrameModel::setOverwriteMode(bool mode) endResetModel(); } +void CANFrameModel::setClearMode(bool mode) +{ + filtersPersistDuringClear = mode; +} + void CANFrameModel::setFilterState(unsigned int ID, bool state) { if (!filters.contains(ID)) return; @@ -832,8 +838,11 @@ void CANFrameModel::clearFrames() this->beginResetModel(); frames.clear(); filteredFrames.clear(); - filters.clear(); - busFilters.clear(); + if(filtersPersistDuringClear == false) + { + filters.clear(); + busFilters.clear(); + } frames.reserve(preallocSize); filteredFrames.reserve(preallocSize); this->endResetModel(); diff --git a/canframemodel.h b/canframemodel.h index edb65b5..49ad74d 100644 --- a/canframemodel.h +++ b/canframemodel.h @@ -46,6 +46,7 @@ public: bool getInterpretMode(); void setOverwriteMode(bool); void setHexMode(bool); + void setClearMode(bool mode); void setSysTimeMode(bool); void setMillisMode(bool mode); void setIgnoreDBCColors(bool mode); @@ -89,6 +90,7 @@ private: QMutex mutex; bool interpretFrames; //should we use the dbcHandler? bool overwriteDups; //should we display all frames or only the newest for each ID? + bool filtersPersistDuringClear; QString timeFormat; bool useHexMode; bool timeSeconds; diff --git a/mainwindow.cpp b/mainwindow.cpp index f32125a..1923063 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -141,6 +141,7 @@ MainWindow::MainWindow(QWidget *parent) : connect(ui->cbInterpret, &QAbstractButton::toggled, this, &MainWindow::interpretToggled); 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->listBusFilters, &QListWidget::itemChanged, this, &MainWindow::busFilterListItemChanged); @@ -616,6 +617,18 @@ void MainWindow::overwriteToggled(bool state) } } +void MainWindow::presistentFiltersToggled(bool state) +{ + if (state) + { + model->setClearMode(true); + } + else + { + model->setClearMode(false); + } +} + void MainWindow::updateFilterList() { if (model == nullptr) return; diff --git a/mainwindow.h b/mainwindow.h index 0b0fd90..39bb612 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -99,6 +99,7 @@ private slots: void setupSendToLatestGraphWindow(); void interpretToggled(bool); void overwriteToggled(bool); + void presistentFiltersToggled(bool state); void logReceivedFrame(CANConnection*, QVector); void tickGUIUpdate(); void toggleCapture(); diff --git a/ui/mainwindow.ui b/ui/mainwindow.ui index 4fb01d8..77e1b5a 100644 --- a/ui/mainwindow.ui +++ b/ui/mainwindow.ui @@ -227,6 +227,13 @@ + + + + Keep Filters When Clearing + + + From cb94cac2057cab2121bccfce0f4255e100e017bb Mon Sep 17 00:00:00 2001 From: Andy Huska Date: Mon, 19 Sep 2022 13:47:57 -0500 Subject: [PATCH 05/16] Fixed issue where filteredFrames was having its capacity changed when adjusting filters due to appending a QVector of frames which appears to change the capacity to the number of items appended. Also fixed bug where preallocsize was being locally defined and therefore the global version wasn't being updated with unknown effets. --- canframemodel.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/canframemodel.cpp b/canframemodel.cpp index c4a8309..cdcaa19 100644 --- a/canframemodel.cpp +++ b/canframemodel.cpp @@ -59,7 +59,7 @@ CANFrameModel::CANFrameModel(QObject *parent) } QSettings settings; - int preallocSize = settings.value("Main/MaximumFrames", maxFramesDefault).toInt(); + preallocSize = settings.value("Main/MaximumFrames", maxFramesDefault).toInt(); frames.reserve(preallocSize); filteredFrames.reserve(preallocSize); //the goal is to prevent a reallocation from ever happening @@ -752,15 +752,15 @@ void CANFrameModel::addFrames(const CANConnection*, const QVector& pFr { if(frames.length() > frames.capacity() * 0.99) { - qDebug() << "Frames count: " << frames.length() << " of " << frames.capacity() << " capacity, removing first " << frames.capacity() * 0.05 << " frames"; - frames.remove(0, frames.capacity() * 0.05); + 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 " << filteredFrames.capacity() * 0.05 << " frames"; - filteredFrames.remove(0, filteredFrames.capacity() * 0.05); + 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(); } @@ -790,8 +790,8 @@ void CANFrameModel::sendRefresh() mutex.lock(); beginResetModel(); filteredFrames.clear(); - filteredFrames.reserve(preallocSize); filteredFrames.append(tempContainer); + filteredFrames.reserve(preallocSize); lastUpdateNumFrames = 0; endResetModel(); From 40dbf253afcef48b21a601d4ea7fba24641fd9d5 Mon Sep 17 00:00:00 2001 From: Andy Huska Date: Mon, 19 Sep 2022 15:28:53 -0500 Subject: [PATCH 06/16] Saving, loading, clearing, and appending signal lists working!! --- mainwindow.cpp | 19 ++++- signalviewerwindow.cpp | 174 ++++++++++++++++++++++++++++++++++++++- signalviewerwindow.h | 8 ++ ui/signalviewerwindow.ui | 28 +++++++ 4 files changed, 226 insertions(+), 3 deletions(-) diff --git a/mainwindow.cpp b/mainwindow.cpp index 1923063..4617956 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1159,11 +1159,26 @@ void MainWindow::showTemporalGraphWindow() //only create an instance of the object if we dont have one. Otherwise just display the existing one. if (!temporalGraphWindow) { + const QVector *frames; if (!useFiltered) - temporalGraphWindow = new TemporalGraphWindow(model->getListReference()); + frames = model->getListReference(); 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(); } diff --git a/signalviewerwindow.cpp b/signalviewerwindow.cpp index 9f926f6..cb70364 100644 --- a/signalviewerwindow.cpp +++ b/signalviewerwindow.cpp @@ -27,6 +27,10 @@ SignalViewerWindow::SignalViewerWindow(const QVector *frames, QWidget connect(ui->btnAdd, SIGNAL(clicked(bool)), this, SLOT(addSignal())); connect(MainWindow::getReference(), SIGNAL(framesUpdated(int)), this, SLOT(updatedFrames(int))); 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(); } @@ -137,11 +141,179 @@ void SignalViewerWindow::addSignal() DBC_SIGNAL *sig = msg->sigHandler->findSignalByName(ui->cbSignals->currentText()); if (!sig) return; + addSignal(sig); +} + +void SignalViewerWindow::addSignal(DBC_SIGNAL *sig) +{ signalList.append(sig); int rowIdx = ui->tableViewer->rowCount(); ui->tableViewer->insertRow(rowIdx); - QTableWidgetItem *item = new QTableWidgetItem(msg->sender->name + " - " + sig->name); + QTableWidgetItem *item = new QTableWidgetItem(sig->parentMessage->sender->name + " - " + sig->name); ui->tableViewer->setItem(rowIdx, 0, item); +} +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 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 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 + + + + Save View + + + + + + + Load View + + + + + + + Append to View + + + + + + + Clear View + + + From 9e9195b34e51220ca89d836e1282bc27fb554d4b Mon Sep 17 00:00:00 2001 From: Andy Huska Date: Mon, 19 Sep 2022 16:13:30 -0500 Subject: [PATCH 07/16] changed default data table font to be fixed-width for easier reading --- mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mainwindow.cpp b/mainwindow.cpp index 4617956..a77ea1f 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -55,7 +55,7 @@ MainWindow::MainWindow(QWidget *parent) : verticalHeader->setSectionResizeMode(QHeaderView::Fixed); QSettings settings; int fontSize = settings.value("Main/FontSize", 9).toUInt(); - QFont sysFont = QFont(); //get default font + QFont sysFont = QFontDatabase::systemFont(QFontDatabase::FixedFont); //get default font sysFont.setPointSize(fontSize); verticalHeader->setDefaultSectionSize(sysFont.pixelSize()); ui->canFramesView->setFont(sysFont); From 13c920f97110128ece5642c41f31d2208a71d5f4 Mon Sep 17 00:00:00 2001 From: Andy Huska Date: Tue, 20 Sep 2022 07:46:30 -0500 Subject: [PATCH 08/16] Fixed regression where non-commented node would not delete Fixed odd crash due to dbcNode being null on refresh --- dbc/dbchandler.cpp | 6 +++++- dbc/dbcnodeeditor.cpp | 7 +++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/dbc/dbchandler.cpp b/dbc/dbchandler.cpp index 6e29ad7..d60dd1b 100644 --- a/dbc/dbchandler.cpp +++ b/dbc/dbchandler.cpp @@ -351,7 +351,11 @@ DBC_NODE* DBCFile::findNodeByNameAndComment(QString fullname) if (dbc_nodes.length() == 0) return nullptr; for (int i = 0; i < dbc_nodes.length(); i++) { - nameAndComment = dbc_nodes[i].name + " - " + dbc_nodes[i].comment; + 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]; diff --git a/dbc/dbcnodeeditor.cpp b/dbc/dbcnodeeditor.cpp index e8363a3..f553fb4 100644 --- a/dbc/dbcnodeeditor.cpp +++ b/dbc/dbcnodeeditor.cpp @@ -111,8 +111,11 @@ void DBCNodeEditor::showEvent(QShowEvent* event) void DBCNodeEditor::refreshView() { - ui->lineComment->setText(dbcNode->comment); - ui->lineMsgName->setText(dbcNode->name); + if(dbcNode) + { + ui->lineComment->setText(dbcNode->comment); + ui->lineMsgName->setText(dbcNode->name); + } //generateSampleText(); } From f38e0b0bfaecd7197fa00cae2e7d9dfd1100b637 Mon Sep 17 00:00:00 2001 From: Andy Huska Date: Fri, 23 Sep 2022 15:28:41 -0500 Subject: [PATCH 09/16] Took out unnecessary exception recover code Cuz app is going to crash anyway, no need to make a mess --- canframemodel.cpp | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/canframemodel.cpp b/canframemodel.cpp index 8ca4a5a..94f3ce0 100644 --- a/canframemodel.cpp +++ b/canframemodel.cpp @@ -61,8 +61,9 @@ CANFrameModel::CANFrameModel(QObject *parent) QSettings settings; int preallocSize = settings.value("Main/MaximumFrames", maxFramesDefault).toInt(); + //the goal is to prevent a reallocation from ever happening frames.reserve(preallocSize); - filteredFrames.reserve(preallocSize); //the goal is to prevent a reallocation from ever happening + filteredFrames.reserve(preallocSize); dbcHandler = DBCHandler::getReference(); interpretFrames = false; @@ -685,18 +686,14 @@ void CANFrameModel::addFrame(const CANFrame& frame, bool autoRefresh = false) { bool alloc_ok = true; - for(int i=0; i<3; i++) + try { - try - { - frames.append(tempFrame); - break; - } - catch (const std::exception& ex) - { - alloc_ok = false; - qDebug() << "addFrame failed to append. frames.length(): " << frames.length() << " Exception: " << ex.what(); - } + frames.append(tempFrame); + } + catch (const std::exception& ex) + { + alloc_ok = false; + qDebug() << "addFrame failed to append. App is probably going to crash. frames.length(): " << frames.length() << " Exception: " << ex.what(); } if(alloc_ok) From 5ffe161210aef98a51068234ead07b391ab0d34f Mon Sep 17 00:00:00 2001 From: Andy Huska Date: Fri, 23 Sep 2022 15:30:58 -0500 Subject: [PATCH 10/16] more clean up --- canframemodel.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/canframemodel.cpp b/canframemodel.cpp index 94f3ce0..df75171 100644 --- a/canframemodel.cpp +++ b/canframemodel.cpp @@ -684,20 +684,10 @@ void CANFrameModel::addFrame(const CANFrame& frame, bool autoRefresh = false) if (!overwriteDups) { - bool alloc_ok = true; - try { frames.append(tempFrame); - } - catch (const std::exception& ex) - { - alloc_ok = false; - qDebug() << "addFrame failed to append. App is probably going to crash. frames.length(): " << frames.length() << " Exception: " << ex.what(); - } - if(alloc_ok) - { if (filters[tempFrame.frameId()] && busFilters[tempFrame.bus]) { if (autoRefresh) beginInsertRows(QModelIndex(), filteredFrames.count(), filteredFrames.count()); @@ -706,6 +696,10 @@ void CANFrameModel::addFrame(const CANFrame& frame, bool autoRefresh = false) 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 { From 07db2874070bf836da82ce092f948429e12d6221 Mon Sep 17 00:00:00 2001 From: Ludovic LANGE Date: Sat, 24 Sep 2022 17:27:39 +0200 Subject: [PATCH 11/16] replace qrand/qsrand with QRandomGenerator (qt6) Since Qt5, qrand/qsrand methods [are deprecated](https://doc.qt.io/qt-5/qtglobal-obsolete.html#qrand). Qt6 remove those methods, thus we need to use instead a [QRandomGenerator](https://doc.qt.io/qt-6/qrandomgenerator.html). QElapsedTimer is available since Qt5.10, and is already used in the source code. --- scriptingwindow.cpp | 11 ++++++++++- simplecrypt.cpp | 12 ++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/scriptingwindow.cpp b/scriptingwindow.cpp index 1d5f378..1f24dee 100644 --- a/scriptingwindow.cpp +++ b/scriptingwindow.cpp @@ -4,6 +4,9 @@ #include #include #include +#if QT_VERSION >= QT_VERSION_CHECK( 5, 10, 0 ) +#include +#endif #include "connections/canconmanager.h" #include "helpwindow.h" @@ -234,7 +237,13 @@ void ScriptingWindow::createNewScript() 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->scriptText = QString(); container->setScriptWindow(this); diff --git a/simplecrypt.cpp b/simplecrypt.cpp index 79a16ba..51f4271 100644 --- a/simplecrypt.cpp +++ b/simplecrypt.cpp @@ -31,6 +31,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include +#if QT_VERSION >= QT_VERSION_CHECK( 5, 10, 0 ) +#include +#endif SimpleCrypt::SimpleCrypt(): m_key(0), @@ -38,7 +42,9 @@ SimpleCrypt::SimpleCrypt(): m_protectionMode(ProtectionChecksum), m_lastError(ErrorNoError) { +#if QT_VERSION < QT_VERSION_CHECK( 5, 10, 0 ) qsrand(uint(QDateTime::currentMSecsSinceEpoch() & 0xFFFF)); +#endif } SimpleCrypt::SimpleCrypt(quint64 key): @@ -47,7 +53,9 @@ SimpleCrypt::SimpleCrypt(quint64 key): m_protectionMode(ProtectionChecksum), m_lastError(ErrorNoError) { +#if QT_VERSION < QT_VERSION_CHECK( 5, 10, 0 ) qsrand(uint(QDateTime::currentMSecsSinceEpoch() & 0xFFFF)); +#endif splitKey(); } @@ -113,7 +121,11 @@ QByteArray SimpleCrypt::encryptToByteArray(QByteArray plaintext) } //prepend a random char to the string +#if QT_VERSION < QT_VERSION_CHECK( 5, 10, 0 ) char randomChar = char(qrand() & 0xFF); +#else + char randomChar = char(QRandomGenerator::global()->bounded(256)); +#endif ba = randomChar + integrityProtection + ba; int pos(0); From 9fb86e649ff436dd78755c9405e93ddc2d52b428 Mon Sep 17 00:00:00 2001 From: Ludovic LANGE Date: Sat, 24 Sep 2022 17:51:25 +0200 Subject: [PATCH 12/16] remove qRegisterMetaTypeStreamOperators (qt6) Since Qt6, some methods of [QMetaType are removed](https://doc.qt.io/qt-6/qtcore-changes-qt6.html#the-qmetatype-class). We remove `qRegisterMetaTypeStreamOperators()` calls for Qt >= 6 --- connections/connectionwindow.cpp | 2 ++ mainwindow.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/connections/connectionwindow.cpp b/connections/connectionwindow.cpp index a446078..e277e58 100644 --- a/connections/connectionwindow.cpp +++ b/connections/connectionwindow.cpp @@ -501,8 +501,10 @@ CANConnection* ConnectionWindow::create(CANCon::type pTye, QString pPortName, QS void ConnectionWindow::loadConnections() { +#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) qRegisterMetaTypeStreamOperators(); qRegisterMetaTypeStreamOperators>(); +#endif QSettings settings; diff --git a/mainwindow.cpp b/mainwindow.cpp index f32125a..24c013d 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -30,8 +30,10 @@ MainWindow::MainWindow(QWidget *parent) : ui(new Ui::MainWindow) { ui->setupUi(this); +#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) qRegisterMetaTypeStreamOperators>(); qRegisterMetaTypeStreamOperators>(); +#endif useHex = true; From 5a18c611e1e056e4f34952d3bce160304343fe93 Mon Sep 17 00:00:00 2001 From: Ludovic LANGE Date: Sat, 24 Sep 2022 17:04:26 +0200 Subject: [PATCH 13/16] replace QTime with QElapsedTimer when possible (qt6) Since Qt5, some methods of QTime [are deprecated](https://doc.qt.io/qt-5/qtime-obsolete.html). Qt6 remove those methods, thus in two instances we need to use a [QElapsedTimer](https://doc.qt.io/qt-6/qelapsedtimer.html) instead of a QTime. QElapsedTimer is available since Qt5.4, and is already used in the source code. --- mainwindow.cpp | 2 +- mainwindow.h | 2 +- re/sniffer/snifferitem.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mainwindow.cpp b/mainwindow.cpp index f32125a..ee9da8c 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -177,7 +177,7 @@ MainWindow::MainWindow(QWidget *parent) : updateTimer.setInterval(250); updateTimer.start(); - elapsedTime = new QTime; + elapsedTime = new QElapsedTimer; elapsedTime->start(); isConnected = false; diff --git a/mainwindow.h b/mainwindow.h index 0b0fd90..b4febdb 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -137,7 +137,7 @@ private: DBCHandler *dbcHandler; QByteArray inputBuffer; QTimer updateTimer; - QTime *elapsedTime; + QElapsedTimer *elapsedTime; int framesPerSec; int rxFrames; bool inhibitFilterUpdate; diff --git a/re/sniffer/snifferitem.h b/re/sniffer/snifferitem.h index 0995a10..ea0a086 100644 --- a/re/sniffer/snifferitem.h +++ b/re/sniffer/snifferitem.h @@ -2,7 +2,7 @@ #define SNIFFERITEM_H #include -#include +#include #include "can_structs.h" struct fstCan @@ -50,7 +50,7 @@ private: quint64 mCurrentTime; quint64 mCurrSeqVal; - QTime mTime; + QElapsedTimer mTime; }; #endif // SNIFFERITEM_H From c2fc1f179ec2265a28305d93a840fe22e2de9a15 Mon Sep 17 00:00:00 2001 From: Ludovic LANGE Date: Sat, 24 Sep 2022 22:06:09 +0200 Subject: [PATCH 14/16] replace BackgroundColorRole/TextColorRole with BackgroundRole/ForegroundRole (qt6) Since long time ago (12yrs), Qt::BackgroundColorRole/Qt::TextColorRole are aliased by Qt::BackgroundRole/Qt::ForegroundRole and raise a deprecation warning. Qt6 remove those values, thus we need to use Qt::BackgroundRole/Qt::ForegroundRole. --- canframemodel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/canframemodel.cpp b/canframemodel.cpp index cdcaa19..c69080f 100644 --- a/canframemodel.cpp +++ b/canframemodel.cpp @@ -408,7 +408,7 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const const unsigned char *data = reinterpret_cast(thisFrame.payload().constData()); int dataLen = thisFrame.payload().count(); - if (role == Qt::BackgroundColorRole) + if (role == Qt::BackgroundRole) { if (dbcHandler != nullptr && interpretFrames && !ignoreDBCColors) { @@ -441,7 +441,7 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const } } - if (role == Qt::TextColorRole) + if (role == Qt::ForegroundRole) { if (dbcHandler != nullptr && interpretFrames && !ignoreDBCColors) { From 5ac5a7d45f2cbca2c0af3daf76068d12b51398c4 Mon Sep 17 00:00:00 2001 From: Ludovic LANGE Date: Sat, 24 Sep 2022 22:13:02 +0200 Subject: [PATCH 15/16] replace QAtomicInt load()/store() with loadRelaxed()/storeRelaxed() Since Qt5, some methods of QAtomicInteger [are deprecated](https://doc.qt.io/qt-5/qatomicinteger-obsolete.html). Qt6 remove those methods, thus we need to replace them. --- connections/canconnection.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connections/canconnection.cpp b/connections/canconnection.cpp index 8f0e231..ba145ee 100644 --- a/connections/canconnection.cpp +++ b/connections/canconnection.cpp @@ -245,11 +245,11 @@ CANCon::type CANConnection::getType() { CANCon::status CANConnection::getStatus() { - return (CANCon::status) mStatus.load(); + return (CANCon::status) mStatus.loadRelaxed(); } void CANConnection::setStatus(CANCon::status pStatus) { - mStatus.store(pStatus); + mStatus.storeRelaxed(pStatus); } bool CANConnection::isCapSuspended() { From 97844ad1e546295248c311db4f4d28f071245c50 Mon Sep 17 00:00:00 2001 From: Ludovic LANGE Date: Sat, 24 Sep 2022 22:22:15 +0200 Subject: [PATCH 16/16] make QCustomPlot compatible with Qt6.2+ (qt6) Cf the discussion here: https://www.qcustomplot.com/index.php/support/forum/2380 --- qcustomplot.h | 44 ++++++++++++++++---------------------------- 1 file changed, 16 insertions(+), 28 deletions(-) diff --git a/qcustomplot.h b/qcustomplot.h index 8f0f78b..170850b 100644 --- a/qcustomplot.h +++ b/qcustomplot.h @@ -156,26 +156,8 @@ class QCPPolarGraph; It provides QMetaObject-based reflection of its enums and flags via \a QCP::staticMetaObject. */ -#ifndef Q_MOC_RUN namespace QCP { -#else -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 + Q_NAMESPACE /*! 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 }; + 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 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::MarginSides) Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::Interactions) -Q_DECLARE_METATYPE(QCP::ExportPen) -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) +//no need to use Q_DECLARE_METATYPE on enum since Q_ENUM_NS adds enum as metatype automatically /* end of 'src/global.h' */