From 40dbf253afcef48b21a601d4ea7fba24641fd9d5 Mon Sep 17 00:00:00 2001 From: Andy Huska Date: Mon, 19 Sep 2022 15:28:53 -0500 Subject: [PATCH 1/4] 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 2/4] 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 bd8582b8e36626fdb1ee8df46e297b9799fc028c Mon Sep 17 00:00:00 2001 From: Andy Huska Date: Wed, 28 Sep 2022 20:02:27 -0500 Subject: [PATCH 3/4] Added combobox for nodes so msg combobox isnt so long Added disabled filenames in node combobox so you can understand what is what Added node column to table Made table columns sortable so you can sort by node name or message name Want to make table fixed width font capable Want to make table rearrangable Want to make table rows shorter to fix more info in a window Want to make it possible to have multiple signal viewer windows Want to add ability to click on signals and add them to graphs like the main window --- signalviewerwindow.cpp | 75 ++++++++++++++++++++++++++++++++++------ signalviewerwindow.h | 3 +- ui/signalviewerwindow.ui | 16 ++++++++- 3 files changed, 81 insertions(+), 13 deletions(-) diff --git a/signalviewerwindow.cpp b/signalviewerwindow.cpp index cb70364..7d20531 100644 --- a/signalviewerwindow.cpp +++ b/signalviewerwindow.cpp @@ -4,6 +4,9 @@ #include "mainwindow.h" #include +#define MSG_COL 1 +#define VALUE_COL 2 + SignalViewerWindow::SignalViewerWindow(const QVector *frames, QWidget *parent) : QDialog(parent), ui(new Ui::SignalViewerWindow) @@ -14,15 +17,16 @@ SignalViewerWindow::SignalViewerWindow(const QVector *frames, QWidget modelFrames = frames; QStringList headers; - headers << "Signal" << "Value"; + headers << "Node" << "Signal" << "Value"; ui->tableViewer->setHorizontalHeaderLabels(headers); - ui->tableViewer->setColumnWidth(0, 150); - ui->tableViewer->setColumnWidth(1, 300); + ui->tableViewer->setColumnWidth(0, 100); + ui->tableViewer->setColumnWidth(1, 150); QHeaderView *HorzHdr = ui->tableViewer->horizontalHeader(); HorzHdr->setStretchLastSection(true); //causes the data column to automatically fill the tableview 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->btnAdd, SIGNAL(clicked(bool)), this, SLOT(addSignal())); connect(MainWindow::getReference(), SIGNAL(framesUpdated(int)), this, SLOT(updatedFrames(int))); @@ -32,7 +36,7 @@ SignalViewerWindow::SignalViewerWindow(const QVector *frames, QWidget connect(ui->btnAppend, SIGNAL(clicked(bool)), this, SLOT(appendSignalsFile())); connect(ui->btnClear, SIGNAL(clicked(bool)), this, SLOT(clearSignalsTable())); - loadMessages(); + loadNodes(); } SignalViewerWindow::~SignalViewerWindow() @@ -79,11 +83,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 { - QTableWidgetItem *item = ui->tableViewer->item(i, 1); + QTableWidgetItem *item = ui->tableViewer->item(i, VALUE_COL); if (!item) { item = new QTableWidgetItem(sigString); - ui->tableViewer->setItem(i, 1, item); + ui->tableViewer->setItem(i, VALUE_COL, item); } else item->setText(sigString); } @@ -99,20 +103,67 @@ void SignalViewerWindow::removeSelectedSignal() ui->tableViewer->removeRow(selRow); } -void SignalViewerWindow::loadMessages() +void SetComboBoxItemEnabled(QComboBox * comboBox, int index, bool enabled) +{ + auto * model = qobject_cast(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; - ui->cbMessages->clear(); + ui->cbNodes->clear(); if (dbcHandler == nullptr) return; if ((numFiles = dbcHandler->getFileCount()) == 0) return; qDebug() << numFiles; + for (int f = 0; f < numFiles; f++) + { + qDebug() << dbcHandler->getFileByIdx(f)->messageHandler->getCount(); + + QList 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; icbNodes->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++) { - ui->cbMessages->addItem(dbcHandler->getFileByIdx(f)->messageHandler->findMsgByIdx(x)->name); + if(dbcHandler->getFileByIdx(f)->messageHandler->findMsgByIdx(x)->sender->name == nodeName) + ui->cbMessages->addItem(dbcHandler->getFileByIdx(f)->messageHandler->findMsgByIdx(x)->name); } } } @@ -150,8 +201,10 @@ void SignalViewerWindow::addSignal(DBC_SIGNAL *sig) int rowIdx = ui->tableViewer->rowCount(); ui->tableViewer->insertRow(rowIdx); - QTableWidgetItem *item = new QTableWidgetItem(sig->parentMessage->sender->name + " - " + sig->name); - ui->tableViewer->setItem(rowIdx, 0, item); + QTableWidgetItem *nodeitem = new QTableWidgetItem(sig->parentMessage->sender->name); + ui->tableViewer->setItem(rowIdx, 0, nodeitem); + QTableWidgetItem *msgitem = new QTableWidgetItem(sig->name); + ui->tableViewer->setItem(rowIdx, 1, msgitem); } void SignalViewerWindow::saveSignalsFile() diff --git a/signalviewerwindow.h b/signalviewerwindow.h index fab979c..711fe2c 100644 --- a/signalviewerwindow.h +++ b/signalviewerwindow.h @@ -17,7 +17,8 @@ public: ~SignalViewerWindow(); private slots: - void loadMessages(); + void loadNodes(); + void loadMessages(int idx); void loadSignals(int idx); void addSignal(); void addSignal(DBC_SIGNAL *sig); diff --git a/ui/signalviewerwindow.ui b/ui/signalviewerwindow.ui index 0814757..8f1c75d 100644 --- a/ui/signalviewerwindow.ui +++ b/ui/signalviewerwindow.ui @@ -18,8 +18,11 @@ + + true + - 2 + 3 300 @@ -32,6 +35,7 @@ + @@ -45,6 +49,16 @@ + + + + Node + + + + + + From dc0b25bee8e569113ba5f942987656060cc79fa3 Mon Sep 17 00:00:00 2001 From: Andy Huska Date: Fri, 30 Sep 2022 16:33:07 -0500 Subject: [PATCH 4/4] Added setting for fixed width vs normal font in the data tables --- mainsettingsdialog.cpp | 3 +++ mainwindow.cpp | 8 +++++++- signalviewerwindow.cpp | 15 +++++++++++++++ ui/mainsettingsdialog.ui | 18 ++++++++++++++++-- 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/mainsettingsdialog.cpp b/mainsettingsdialog.cpp index 2da44ed..7cd1230 100644 --- a/mainsettingsdialog.cpp +++ b/mainsettingsdialog.cpp @@ -48,6 +48,7 @@ MainSettingsDialog::MainSettingsDialog(QWidget *parent) : ui->cbLoadConnections->setChecked(settings.value("Main/SaveRestoreConnections", false).toBool()); 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 clockMode = settings.value("Main/TimeClock", false).toBool(); @@ -132,6 +133,7 @@ MainSettingsDialog::MainSettingsDialog(QWidget *parent) : 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())); + connect(ui->cbFontFixedWidth, SIGNAL(toggled(bool)), this, SLOT(updateSettings())); installEventFilter(this); } @@ -199,6 +201,7 @@ void MainSettingsDialog::updateSettings() settings.setValue("Main/FilterLabeling", ui->cbFilterLabeling->isChecked()); settings.setValue("Main/IgnoreDBCColors", ui->cbIgnoreDBCColors->isChecked()); settings.setValue("Main/MaximumFrames", ui->spinMaximumFrames->value()); + settings.setValue("Main/FontFixedWidth", ui->cbFontFixedWidth->isChecked()); settings.sync(); emit updatedSettings(); diff --git a/mainwindow.cpp b/mainwindow.cpp index e1184f1..e84da30 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -57,12 +57,18 @@ MainWindow::MainWindow(QWidget *parent) : verticalHeader->setSectionResizeMode(QHeaderView::Fixed); QSettings settings; int fontSize = settings.value("Main/FontSize", 9).toUInt(); - QFont sysFont = QFontDatabase::systemFont(QFontDatabase::FixedFont); //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); verticalHeader->setDefaultSectionSize(sysFont.pixelSize()); + verticalHeader->setFont(QFont()); ui->canFramesView->setFont(sysFont); QHeaderView *HorzHdr = ui->canFramesView->horizontalHeader(); + HorzHdr->setFont(QFont()); HorzHdr->setStretchLastSection(true); //causes the data column to automatically fill the tableview connect(HorzHdr, SIGNAL(sectionClicked(int)), this, SLOT(headerClicked(int))); diff --git a/signalviewerwindow.cpp b/signalviewerwindow.cpp index 7d20531..c061074 100644 --- a/signalviewerwindow.cpp +++ b/signalviewerwindow.cpp @@ -21,8 +21,23 @@ SignalViewerWindow::SignalViewerWindow(const QVector *frames, QWidget ui->tableViewer->setHorizontalHeaderLabels(headers); ui->tableViewer->setColumnWidth(0, 100); 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(); 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(); diff --git a/ui/mainsettingsdialog.ui b/ui/mainsettingsdialog.ui index d119b08..cb61d4d 100644 --- a/ui/mainsettingsdialog.ui +++ b/ui/mainsettingsdialog.ui @@ -7,7 +7,7 @@ 0 0 965 - 678 + 713 @@ -191,9 +191,23 @@ - Font Size + Font + + + + Use fixed-width font in tables + + + + + + + Size + + +