From 1177e81becba680f2dcf31f62601aec1520ddf57 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Sun, 24 Feb 2019 16:57:18 -0500 Subject: [PATCH 01/33] Fix for crash in Flow View when a frame doesn't have 8 data bytes --- re/flowviewwindow.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/re/flowviewwindow.cpp b/re/flowviewwindow.cpp index 0587b7c..f2e3184 100644 --- a/re/flowviewwindow.cpp +++ b/re/flowviewwindow.cpp @@ -444,7 +444,8 @@ void FlowViewWindow::updatedFrames(int numFrames) { for (int k = 0; k < 8; k++) { - graphRef[k]->addData(newX[k], newY[k]); + if (graphRef[k] && graphRef[k]->data()) + graphRef[k]->addData(newX[k], newY[k]); } ui->graphView->replot(); updateDataView(); @@ -465,6 +466,8 @@ void FlowViewWindow::createGraph(int byteNum) int tempVal; float minval=1000000, maxval = -100000; + qDebug() << "Create Graph " << byteNum; + bool graphByTime = ui->cbTimeGraph->isChecked(); int numEntries = frameCache.count(); @@ -533,6 +536,7 @@ void FlowViewWindow::updateFrameLabel() void FlowViewWindow::changeID(QString newID) { + qDebug() << "change id " << newID; //parse the ID and then load up the frame cache with just messages with that ID. uint32_t id = (uint32_t)Utility::ParseStringToNum(newID); frameCache.clear(); @@ -555,7 +559,8 @@ void FlowViewWindow::changeID(QString newID) if (frameCache.count() == 0) return; removeAllGraphs(); - for (uint32_t c = 0; c < frameCache.at(0).len; c++) + //for (uint32_t c = 0; c < frameCache.at(0).len; c++) + for (uint32_t c = 0; c < 8; c++) { createGraph(c); } From 53c5641038661ab7d2fb42c382b32a565f0157cd Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Sun, 24 Feb 2019 16:59:18 -0500 Subject: [PATCH 02/33] Update version number --- config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.h b/config.h index 5febcc8..48ad1bf 100644 --- a/config.h +++ b/config.h @@ -1,7 +1,7 @@ #ifndef CONFIG #define CONFIG -#define VERSION 190 +#define VERSION 191 //try to keep this in sync. //SavvyCAN will complain if you connect a GVRET board with a revision From b91dad5f03ce06cf7f4583a86912a4ee1d14df92 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Sun, 24 Feb 2019 20:45:27 -0500 Subject: [PATCH 03/33] Reorder Tabs for preference window, add preference for whether to load and save CAN bus connections. --- connections/connectionwindow.cpp | 8 ++++++-- mainsettingsdialog.cpp | 3 +++ ui/mainsettingsdialog.ui | 16 +++++++++++++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/connections/connectionwindow.cpp b/connections/connectionwindow.cpp index b1512ba..5ce5407 100644 --- a/connections/connectionwindow.cpp +++ b/connections/connectionwindow.cpp @@ -8,6 +8,7 @@ #include "connections/canconfactory.h" #include "connections/canconmanager.h" #include "canbus.h" +#include ConnectionWindow::ConnectionWindow(QWidget *parent) : QDialog(parent), @@ -41,8 +42,11 @@ ConnectionWindow::ConnectionWindow(QWidget *parent) : ui->btnSendText->setEnabled(false); ui->lineSend->setEnabled(false); - /* load connection configuration */ - loadConnections(); + if (settings.value("Main/SaveRestoreConnections", false).toBool()) + { + /* load connection configuration */ + loadConnections(); + } ui->rbSocketCAN->setEnabled(isSerialBusAvailable()); diff --git a/mainsettingsdialog.cpp b/mainsettingsdialog.cpp index 2dd0a38..1a503d5 100644 --- a/mainsettingsdialog.cpp +++ b/mainsettingsdialog.cpp @@ -31,6 +31,7 @@ MainSettingsDialog::MainSettingsDialog(QWidget *parent) : ui->lineRemoteHost->setText(settings->value("Remote/Host", "api.savvycan.com").toString()); ui->lineRemotePort->setText(settings->value("Remote/Port", "21315").toString()); // = 0x5343 = SC. Yep, really creative port number ui->cbAutoStartRemote->setChecked(settings->value("Remote/AutoStart", false).toBool()); + ui->cbLoadConnections->setChecked(settings->value("Main/SaveRestoreConnections", false).toBool()); ui->spinFontSize->setValue(settings->value("Main/FontSize", ui->cbDisplayHex->font().pointSize()).toUInt()); @@ -82,6 +83,7 @@ MainSettingsDialog::MainSettingsDialog(QWidget *parent) : connect(ui->cbAutoStartRemote, SIGNAL(toggled(bool)), this, SLOT(updateSettings())); connect(ui->lineRemoteHost, SIGNAL(editingFinished()), this, SLOT(updateSettings())); connect(ui->lineRemotePort, SIGNAL(editingFinished()), this, SLOT(updateSettings())); + connect(ui->cbLoadConnections, SIGNAL(toggled(bool)), this, SLOT(updateSettings())); installEventFilter(this); } @@ -127,6 +129,7 @@ void MainSettingsDialog::updateSettings() settings->setValue("Main/AutoScroll", ui->cbMainAutoScroll->isChecked()); settings->setValue("Playback/AutoLoop", ui->cbPlaybackLoop->isChecked()); settings->setValue("Main/SaveRestorePositions", ui->cbRestorePositions->isChecked()); + settings->setValue("Main/SaveRestoreConnections", ui->cbLoadConnections->isChecked()); settings->setValue("Main/ValidateComm", ui->cbValidate->isChecked()); settings->setValue("Playback/DefSpeed", ui->spinPlaybackSpeed->value()); settings->setValue("Main/TimeSeconds", ui->rbSeconds->isChecked()); diff --git a/ui/mainsettingsdialog.ui b/ui/mainsettingsdialog.ui index 1b790dd..05de6aa 100644 --- a/ui/mainsettingsdialog.ui +++ b/ui/mainsettingsdialog.ui @@ -45,6 +45,13 @@ + + + + Save/Restore CAN bus connections + + + @@ -337,20 +344,27 @@ + cbMainAutoScroll cbRestorePositions + cbLoadConnections cbDisplayHex cbValidate + cbUseFiltered + cbUseOpenGL rbSeconds rbMicros rbSysClock lineClockFormat - cbMainAutoScroll + spinFontSize cbFlowUseTimestamp cbFlowAutoRef cbPlaybackLoop spinPlaybackSpeed comboSendingBus cbInfoAutoExpand + lineRemoteHost + lineRemotePort + cbAutoStartRemote From 31961361dd8d6b6dc87cf9a6000c1fc5565a0d17 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Tue, 26 Feb 2019 20:28:19 -0500 Subject: [PATCH 04/33] Make the main view model use the system colors and alternate row background --- canframemodel.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/canframemodel.cpp b/canframemodel.cpp index eea4ae0..41f4f7c 100644 --- a/canframemodel.cpp +++ b/canframemodel.cpp @@ -227,6 +227,7 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const int dLen; QString tempString; CANFrame thisFrame; + static bool rowFlip = false; if (!index.isValid()) return QVariant(); @@ -246,8 +247,9 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const return msg->bgColor; } } - //return QApplication::palette().color(QPalette::Button); - return QColor(Qt::white); + rowFlip = !rowFlip; + if (rowFlip) return QApplication::palette().color(QPalette::Base); + else return QApplication::palette().color(QPalette::AlternateBase); } if (role == Qt::TextAlignmentRole) From 118034b003c9fb3387280c34622d540d530e95bc Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Tue, 26 Feb 2019 20:33:34 -0500 Subject: [PATCH 05/33] Fix the just added fun checkerboard pattern in the main frame view --- canframemodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/canframemodel.cpp b/canframemodel.cpp index 41f4f7c..d4108fa 100644 --- a/canframemodel.cpp +++ b/canframemodel.cpp @@ -247,7 +247,7 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const return msg->bgColor; } } - rowFlip = !rowFlip; + rowFlip = (index.row() % 2); if (rowFlip) return QApplication::palette().color(QPalette::Base); else return QApplication::palette().color(QPalette::AlternateBase); } From e5e8b5ffb1eee1342c00cdf65867b5fd4b693f99 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Tue, 26 Feb 2019 20:45:54 -0500 Subject: [PATCH 06/33] Make the CAN databits grid respect the system coloring scheme better --- candatagrid.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/candatagrid.cpp b/candatagrid.cpp index adbbd08..8327608 100644 --- a/candatagrid.cpp +++ b/candatagrid.cpp @@ -73,7 +73,7 @@ void CANDataGrid::paintEvent(QPaintEvent *event) //The left most column has "BYTES" written vertically down it //the next left most column has "0 1 2 3 4 5 6 7" written down along the grid - painter.setPen(QPen(Qt::black)); + painter.setPen(QPen(QApplication::palette().color(QPalette::Text))); QFont mainFont; mainFont.setPixelSize(qMin(xSector, ySector) - 10); painter.setFont(mainFont); From e6ea25011386833717178579e6f4aa0052c4fb17 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Tue, 26 Feb 2019 20:46:28 -0500 Subject: [PATCH 07/33] Tweaked the graph a bit in Flowview to make the X axis labels more sensible. --- re/flowviewwindow.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/re/flowviewwindow.cpp b/re/flowviewwindow.cpp index f2e3184..5092bd6 100644 --- a/re/flowviewwindow.cpp +++ b/re/flowviewwindow.cpp @@ -56,7 +56,8 @@ FlowViewWindow::FlowViewWindow(const QVector *frames, QWidget *parent) //ui->graphView->xAxis->setAutoSubTicks(false); //ui->graphView->xAxis->setAutoTicks(false); QCPAxisTicker *xTicker = new QCPAxisTicker(); - xTicker->setTickCount(10); + xTicker->setTickCount(5); + xTicker->setTickStepStrategy(QCPAxisTicker::tssReadability); ui->graphView->xAxis->setTicker(QSharedPointer(xTicker)); //ui->graphView->xAxis->setAutoTickStep(false); //ui->graphView->xAxis->setAutoSubTicks(false); From 35c22936c3ee2e77b80472acdc14e18adacd3778 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Tue, 26 Feb 2019 21:33:04 -0500 Subject: [PATCH 08/33] Allow the program to "send" frames even if no buses are configured. These frames will show up in the main frame list and can be operated on as if they came into the program. It is likely that only the playback window will work for this special use. Other sending windows are to follow. --- connections/canconmanager.cpp | 18 ++++++++++++++++++ connections/canconmanager.h | 4 +++- connections/connectionwindow.cpp | 1 + 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/connections/canconmanager.cpp b/connections/canconmanager.cpp index b3428a3..56540d4 100644 --- a/connections/canconmanager.cpp +++ b/connections/canconmanager.cpp @@ -2,6 +2,7 @@ #include #include "canconmanager.h" +#include "canconfactory.h" CANConManager* CANConManager::mInstance = NULL; @@ -80,6 +81,17 @@ void CANConManager::refreshCanList() { QObject* sender_p = QObject::sender(); + if (mConns.count() == 0) + { + if(buslessFrames.size()) { + tempFrames.clear(); + tempFrames.append(buslessFrames); //make a copy and pass that copy + buslessFrames.clear(); //delete all frames from the original + emit framesReceived(nullptr, tempFrames); + } + return; + } + if( sender_p != &mTimer) { /* if we are not the sender, the signal is coming from a connection */ @@ -176,6 +188,12 @@ bool CANConManager::sendFrame(const CANFrame& pFrame) CANFrame workingFrame = pFrame; CANFrame *txFrame; + if (mConns.count() == 0) + { + buslessFrames.append(pFrame); + return true; + } + foreach (CANConnection* conn, mConns) { //check if this CAN connection is supposed to handle the requested bus diff --git a/connections/canconmanager.h b/connections/canconmanager.h index 26c6c76..5023f25 100644 --- a/connections/canconmanager.h +++ b/connections/canconmanager.h @@ -77,7 +77,9 @@ private: QElapsedTimer mElapsedTimer; uint64_t mTimestampBasis; uint32_t mNumActiveBuses; - bool useSystemTime; + bool useSystemTime; + QVector buslessFrames; + QVector tempFrames; }; #endif // CANCONNECTIONMODEL_H diff --git a/connections/connectionwindow.cpp b/connections/connectionwindow.cpp index 5ce5407..1c6ae84 100644 --- a/connections/connectionwindow.cpp +++ b/connections/connectionwindow.cpp @@ -260,6 +260,7 @@ void ConnectionWindow::handleOKButton() if( ! CANConManager::getInstance()->getByName(getPortName()) ) { /* create connection */ + //qDebug() << "Create connection type: " << getConnectionType() << " port: " << getPortName() << " driver: " << getDriverName(); conn_p = create(getConnectionType(), getPortName(), getDriverName()); if(!conn_p) return; From f72c24bd05951dc8fccf18bbc66194fbea90adb2 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Tue, 26 Feb 2019 21:35:56 -0500 Subject: [PATCH 09/33] Update version number --- config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.h b/config.h index 48ad1bf..d0168bd 100644 --- a/config.h +++ b/config.h @@ -1,7 +1,7 @@ #ifndef CONFIG #define CONFIG -#define VERSION 191 +#define VERSION 192 //try to keep this in sync. //SavvyCAN will complain if you connect a GVRET board with a revision From 5d427e8db4ff445d16d89dffadc2bb8317a31cdf Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Tue, 26 Feb 2019 22:02:33 -0500 Subject: [PATCH 10/33] Fixes to the sniffer visuals to allow them to adapt to dark themes in the OS. --- re/sniffer/SnifferDelegate.cpp | 3 ++- re/sniffer/sniffermodel.cpp | 17 +++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/re/sniffer/SnifferDelegate.cpp b/re/sniffer/SnifferDelegate.cpp index 82b2fdd..cb6a000 100644 --- a/re/sniffer/SnifferDelegate.cpp +++ b/re/sniffer/SnifferDelegate.cpp @@ -1,5 +1,6 @@ #include "SnifferDelegate.h" #include +#include #include #include "utility.h" #include "re/sniffer/snifferitem.h" @@ -101,7 +102,7 @@ void SnifferDelegate::paint(QPainter *painter, const QStyleOptionViewItem &optio //painter->setPen(QPen(QColor(v,v,v,255))); painter->setOpacity(1.0); - painter->setPen(Qt::black); + painter->setPen(QApplication::palette().color(QPalette::Text)); painter->setFont(mainFont); painter->drawText(QRect(viewport.left(), viewport.top() + xSector + yOffset, xSpan, mainFontInfo->pixelSize()), Qt::AlignCenter, Utility::formatNumber(val)); } diff --git a/re/sniffer/sniffermodel.cpp b/re/sniffer/sniffermodel.cpp index c55163c..8f455ed 100644 --- a/re/sniffer/sniffermodel.cpp +++ b/re/sniffer/sniffermodel.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include "sniffermodel.h" #include "snifferwindow.h" #include "SnifferDelegate.h" @@ -69,13 +71,20 @@ QVariant SnifferModel::data(const QModelIndex &index, int role) const } case Qt::ForegroundRole: { - if (!mFadeInactive || col < 2) return QBrush(Qt::black); + if (!mFadeInactive || col < 2) return QApplication::palette().brush(QPalette::Text); int v = item->getSeqInterval(col - 2) * 10; //qDebug() << "mTS: " << mTimeSequence << " gDT(" << (col - 2) << ") " << item->getDataTimestamp(col - 2); if (v > 225) v = 225; if (v < 0) v = 0; - return QBrush(QColor(v,v,v,255)); - break; + QColor TextColor = QApplication::palette().color(QPalette::Text); + if (TextColor.red() + TextColor.green() + TextColor.blue() < 200) //text defaults to being dark + { + return QBrush(QColor(v,v,v,255)); + } + else //text defaults to being light + { + return QBrush(QColor(255-v,255-v,255-v,255)); + } } case Qt::BackgroundRole: @@ -95,7 +104,7 @@ QVariant SnifferModel::data(const QModelIndex &index, int role) const case dc::DEINC: return QBrush(Qt::red); default: - break; + return QApplication::palette().brush(QPalette::Base); } } break; From 75c2693a97b7780b3a702d76716465eb109ce4fb Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Tue, 26 Feb 2019 22:20:45 -0500 Subject: [PATCH 11/33] Additional updates to make coloring better for dark themes --- re/sniffer/SnifferDelegate.cpp | 16 ++++++++++++++-- re/sniffer/SnifferDelegate.h | 3 ++- re/sniffer/sniffermodel.cpp | 21 ++++++++++++++++----- re/sniffer/sniffermodel.h | 1 + 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/re/sniffer/SnifferDelegate.cpp b/re/sniffer/SnifferDelegate.cpp index cb6a000..543d0e8 100644 --- a/re/sniffer/SnifferDelegate.cpp +++ b/re/sniffer/SnifferDelegate.cpp @@ -7,14 +7,26 @@ SnifferDelegate::SnifferDelegate(QWidget *parent) : QItemDelegate(parent) { + QColor TextColor = QApplication::palette().color(QPalette::Text); + if (TextColor.red() + TextColor.green() + TextColor.blue() < 200) + { + mDarkMode = false; + redBrush = QBrush(Qt::red); + greenBrush = QBrush(Qt::green); + } + else + { + mDarkMode = true; + redBrush = QBrush(QColor(128,0,0)); + greenBrush = QBrush(QColor(0,128,0)); + } blackBrush = QBrush(Qt::black); whiteBrush = QBrush(Qt::white); - redBrush = QBrush(Qt::red); - greenBrush = QBrush(Qt::green); grayBrush = QBrush(QColor(230,230,230)); mainFont.setPointSize(10); mainFontInfo = new QFontInfo(mainFont); mFadeInactive = false; + } bool SnifferDelegate::getFadeInactive() diff --git a/re/sniffer/SnifferDelegate.h b/re/sniffer/SnifferDelegate.h index 693c259..9c98ed5 100644 --- a/re/sniffer/SnifferDelegate.h +++ b/re/sniffer/SnifferDelegate.h @@ -21,7 +21,8 @@ private: QBrush blackBrush, whiteBrush, redBrush, greenBrush, grayBrush; QFont mainFont; QFontInfo* mainFontInfo; - bool mFadeInactive; + bool mFadeInactive; + bool mDarkMode; }; #endif diff --git a/re/sniffer/sniffermodel.cpp b/re/sniffer/sniffermodel.cpp index 8f455ed..2fb0b77 100644 --- a/re/sniffer/sniffermodel.cpp +++ b/re/sniffer/sniffermodel.cpp @@ -13,6 +13,12 @@ SnifferModel::SnifferModel(QObject *parent) mMuteNotched(false), mTimeSequence(0) { + QColor TextColor = QApplication::palette().color(QPalette::Text); + if (TextColor.red() + TextColor.green() + TextColor.blue() < 200) + { + mDarkMode = false; + } + else mDarkMode = true; } SnifferModel::~SnifferModel() @@ -76,8 +82,8 @@ QVariant SnifferModel::data(const QModelIndex &index, int role) const //qDebug() << "mTS: " << mTimeSequence << " gDT(" << (col - 2) << ") " << item->getDataTimestamp(col - 2); if (v > 225) v = 225; if (v < 0) v = 0; - QColor TextColor = QApplication::palette().color(QPalette::Text); - if (TextColor.red() + TextColor.green() + TextColor.blue() < 200) //text defaults to being dark + + if (!mDarkMode) //text defaults to being dark { return QBrush(QColor(v,v,v,255)); } @@ -92,7 +98,10 @@ QVariant SnifferModel::data(const QModelIndex &index, int role) const if(tc::ID==col) { if(item->elapsed() > 4000) - return QBrush(Qt::red); + { + if (!mDarkMode) return QBrush(Qt::red); + return QBrush(QColor(128,0,0)); + } } else if(tc::DATA_0<=col && col<=tc::DATA_7) { @@ -100,9 +109,11 @@ QVariant SnifferModel::data(const QModelIndex &index, int role) const switch(change) { case dc::INC: - return QBrush(Qt::green); + if (!mDarkMode) return QBrush(Qt::green); + return QBrush(QColor(0,128,0)); case dc::DEINC: - return QBrush(Qt::red); + if (!mDarkMode) return QBrush(Qt::red); + return QBrush(QColor(128,0,0)); default: return QApplication::palette().brush(QPalette::Base); } diff --git a/re/sniffer/sniffermodel.h b/re/sniffer/sniffermodel.h index 4945cd2..04ee5f8 100644 --- a/re/sniffer/sniffermodel.h +++ b/re/sniffer/sniffermodel.h @@ -63,6 +63,7 @@ private: bool mNeverExpire; bool mFadeInactive; bool mMuteNotched; + bool mDarkMode; quint32 mTimeSequence; }; From 70e8af85af9748ed7236ebf283d1b5b7a76d3f3a Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Wed, 27 Feb 2019 20:29:08 -0500 Subject: [PATCH 12/33] Added ability to automatically find ESP32RET devices on the local network --- connections/connectionwindow.cpp | 31 +++++++++++++++++++++++++++---- connections/connectionwindow.h | 4 ++++ ui/connectionwindow.ui | 5 ++++- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/connections/connectionwindow.cpp b/connections/connectionwindow.cpp index 1c6ae84..07f6804 100644 --- a/connections/connectionwindow.cpp +++ b/connections/connectionwindow.cpp @@ -1,4 +1,5 @@ #include +#include #include #include "connectionwindow.h" @@ -67,8 +68,24 @@ ConnectionWindow::ConnectionWindow(QWidget *parent) : ui->lblDeviceType->setHidden(true); ui->cbDeviceType->setHidden(true); + + rxBroadcast = new QUdpSocket(this); + rxBroadcast->bind(QHostAddress::AnyIPv4, 17222); + + connect(rxBroadcast, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams())); } + +void ConnectionWindow::readPendingDatagrams() +{ + while (rxBroadcast->hasPendingDatagrams()) { + QNetworkDatagram datagram = rxBroadcast->receiveDatagram(); + if (!remoteDeviceIP.contains(datagram.senderAddress().toString())) + { + remoteDeviceIP.append(datagram.senderAddress().toString()); + } + } +} ConnectionWindow::~ConnectionWindow() { QList& conns = CANConManager::getInstance()->getConnections(); @@ -373,9 +390,14 @@ void ConnectionWindow::selectSocketCan() void ConnectionWindow::selectRemote() { ui->lPort->setText("IP Address:"); - ui->stPort->setCurrentWidget(ui->etPage); + ui->stPort->setCurrentWidget(ui->cbPage); ui->lblDeviceType->setHidden(true); ui->cbDeviceType->setHidden(true); + ui->cbPort->clear(); + foreach(QString pName, remoteDeviceIP) + { + ui->cbPort->addItem(pName); + } } void ConnectionWindow::setSpeed(int speed0) @@ -421,7 +443,9 @@ void ConnectionWindow::setPortName(CANCon::type pType, QString pPortName, QStrin } case CANCon::REMOTE: { - ui->lePort->setText(pPortName); + int idx = ui->cbPort->findText(pPortName); + if (idx > -1) ui->cbPort->setCurrentIndex(idx); + else ui->cbPort->addItem(pPortName); break; } default: {} @@ -440,9 +464,8 @@ QString ConnectionWindow::getPortName() switch( getConnectionType() ) { case CANCon::GVRET_SERIAL: case CANCon::SERIALBUS: - return ui->cbPort->currentText(); case CANCon::REMOTE: - return ui->lePort->text(); + return ui->cbPort->currentText(); default: qDebug() << "getPortName: can't get port"; } diff --git a/connections/connectionwindow.h b/connections/connectionwindow.h index 7b44a1d..515d34e 100644 --- a/connections/connectionwindow.h +++ b/connections/connectionwindow.h @@ -10,6 +10,7 @@ #include #include #include +#include #include "canconnectionmodel.h" #include "connections/canconnection.h" @@ -61,6 +62,7 @@ private slots: void handleSendHex(); void handleSendText(); void connectionStatus(CANConStatus); + void readPendingDatagrams(); private: Ui::ConnectionWindow *ui; @@ -68,6 +70,8 @@ private: QList canDevices; QSettings *settings; CANConnectionModel *connModel; + QUdpSocket *rxBroadcast; + QVector remoteDeviceIP; void selectSerial(); void selectKvaser(); diff --git a/ui/connectionwindow.ui b/ui/connectionwindow.ui index b679a1b..0e52eae 100644 --- a/ui/connectionwindow.ui +++ b/ui/connectionwindow.ui @@ -152,7 +152,7 @@ Qt::LeftToRight - 0 + 1 @@ -179,6 +179,9 @@ 16777215 + + true + From ec49413f6153dc04168a7e5cd30b26ddbe2af184 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Tue, 5 Mar 2019 21:25:32 -0500 Subject: [PATCH 13/33] Major revamp of the connection window. Hopefully it is more clear and intuitive now. --- SavvyCAN.pro | 9 +- config.h | 2 +- connections/canbus.cpp | 2 +- connections/canbus.h | 2 +- connections/canconmanager.cpp | 11 + connections/canconmanager.h | 1 + connections/canconnection.cpp | 2 +- connections/canconnectionmodel.cpp | 154 ++-------- connections/canconnectionmodel.h | 5 +- connections/connectionwindow.cpp | 420 ++++++++-------------------- connections/connectionwindow.h | 35 +-- connections/gvretserial.cpp | 6 +- connections/newconnectiondialog.cpp | 177 ++++++++++++ connections/newconnectiondialog.h | 47 ++++ connections/serialbusconnection.cpp | 4 +- ui/connectionwindow.ui | 286 +++++++------------ ui/newconnectiondialog.ui | 109 ++++++++ 17 files changed, 611 insertions(+), 661 deletions(-) create mode 100644 connections/newconnectiondialog.cpp create mode 100644 connections/newconnectiondialog.h create mode 100644 ui/newconnectiondialog.ui diff --git a/SavvyCAN.pro b/SavvyCAN.pro index 0ef31a1..1e02488 100644 --- a/SavvyCAN.pro +++ b/SavvyCAN.pro @@ -66,7 +66,8 @@ SOURCES += main.cpp\ frameplaybackobject.cpp \ helpwindow.cpp \ blfhandler.cpp \ - re/sniffer/SnifferDelegate.cpp + re/sniffer/SnifferDelegate.cpp \ + connections/newconnectiondialog.cpp HEADERS += mainwindow.h \ can_structs.h \ @@ -123,7 +124,8 @@ HEADERS += mainwindow.h \ frameplaybackobject.h \ helpwindow.h \ blfhandler.h \ - re/sniffer/SnifferDelegate.h + re/sniffer/SnifferDelegate.h \ + connections/newconnectiondialog.h FORMS += ui/candatagrid.ui \ ui/connectionwindow.ui \ @@ -150,7 +152,8 @@ FORMS += ui/candatagrid.ui \ ui/udsscanwindow.ui \ ui/bisectwindow.ui \ ui/signalviewerwindow.ui \ - helpwindow.ui + helpwindow.ui \ + ui/newconnectiondialog.ui DISTFILES += diff --git a/config.h b/config.h index d0168bd..3db1f12 100644 --- a/config.h +++ b/config.h @@ -1,7 +1,7 @@ #ifndef CONFIG #define CONFIG -#define VERSION 192 +#define VERSION 193 //try to keep this in sync. //SavvyCAN will complain if you connect a GVRET board with a revision diff --git a/connections/canbus.cpp b/connections/canbus.cpp index 13aeb11..24238f7 100644 --- a/connections/canbus.cpp +++ b/connections/canbus.cpp @@ -40,7 +40,7 @@ void CANBus::setSingleWire(bool mode){ singleWire = mode; } -void CANBus::setEnabled(bool mode){ +void CANBus::setActive(bool mode){ //qDebug() << "CANBUS SetEnabled = " << mode; active = mode; } diff --git a/connections/canbus.h b/connections/canbus.h index 73f945f..fb2d382 100644 --- a/connections/canbus.h +++ b/connections/canbus.h @@ -20,7 +20,7 @@ public: void setSpeed(int); // new speed void setListenOnly(bool); //bool for whether to only listen void setSingleWire(bool); //bool for whether to use single wire mode - void setEnabled(bool); //whether this bus should be enabled or not. + void setActive(bool); //whether this bus should be enabled or not. int getSpeed(); bool isListenOnly(); bool isSingleWire(); diff --git a/connections/canconmanager.cpp b/connections/canconmanager.cpp index 56540d4..20e0b3f 100644 --- a/connections/canconmanager.cpp +++ b/connections/canconmanager.cpp @@ -77,6 +77,17 @@ int CANConManager::getNumBuses() return buses; } +int CANConManager::getBusBase(CANConnection *which) +{ + int buses = 0; + foreach(CANConnection* conn_p, mConns) + { + if (conn_p != which) buses += conn_p->getNumBuses(); + else return buses; + } + return -1; +} + void CANConManager::refreshCanList() { QObject* sender_p = QObject::sender(); diff --git a/connections/canconmanager.h b/connections/canconmanager.h index 5023f25..5a5f9dc 100644 --- a/connections/canconmanager.h +++ b/connections/canconmanager.h @@ -26,6 +26,7 @@ public: void resetTimeBasis(); int getNumBuses(); + int getBusBase(CANConnection *); /** * @brief sendFrame sends a single frame out the desired bus diff --git a/connections/canconnection.cpp b/connections/canconnection.cpp index ec99099..6a41758 100644 --- a/connections/canconnection.cpp +++ b/connections/canconnection.cpp @@ -210,7 +210,7 @@ void CANConnection::setConfigured(int pBusId, bool pConfigured) { bool CANConnection::getBusConfig(int pBusId, CANBus& pBus) { if( pBusId < 0 || pBusId >= getNumBuses() || !isConfigured(pBusId)) return false; - + qDebug() << "getBusConfig id: " << pBusId; pBus = mBusData[pBusId].mBus; return true; } diff --git a/connections/canconnectionmodel.cpp b/connections/canconnectionmodel.cpp index ac07450..12d4f25 100644 --- a/connections/canconnectionmodel.cpp +++ b/connections/canconnectionmodel.cpp @@ -12,14 +12,11 @@ CANConnectionModel::~CANConnectionModel() } enum class Column { - Bus = 0, ///< A sequential number describing the bus - Type = 1, ///< The CAN driver/backend type, e.g. GVRET, peakcan, or socketcan + Type = 0, ///< The CAN driver/backend type, e.g. GVRET, peakcan, or socketcan + Subtype = 1, ///< Mostly used by SerialBus devices to pick the sub type Port = 2, ///< The CAN hardware port, e.g. can0 for socketcan - Speed = 3, ///< The bus speed in bit/second - ListenOnly = 4, ///< True if the bus is in listen-only mode - SingleWire = 5, ///< True if the bus operates in single-wire mode - Active = 6, ///< True if the bus is activated for sending and receiving - Status = 7 ///< The bus status as text message + NumBuses = 3, ///< Number of buses exposed by this device. Usually non-GVRET devices will just have one + Status = 4 ///< The bus status as text message }; QVariant CANConnectionModel::headerData(int section, Qt::Orientation orientation, int role) const @@ -31,20 +28,14 @@ QVariant CANConnectionModel::headerData(int section, Qt::Orientation orientation { switch (Column(section)) { - case Column::Bus: - return QString(tr("Bus")); case Column::Type: return QString(tr("Type")); + case Column::Subtype: + return QString(tr("Subtype")); case Column::Port: return QString(tr("Port")); - case Column::Speed: - return QString(tr("Speed")); - case Column::ListenOnly: - return QString(tr("Listen Only")); - case Column::SingleWire: - return QString(tr("Single Wire")); - case Column::Active: - return QString(tr("Active")); + case Column::NumBuses: + return QString(tr("Buses")); case Column::Status: return QString(tr("Status")); } @@ -59,7 +50,7 @@ QVariant CANConnectionModel::headerData(int section, Qt::Orientation orientation int CANConnectionModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent); - return 8; + return 5; } @@ -67,78 +58,9 @@ int CANConnectionModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); - int rows = 0; QList& conns = CANConManager::getInstance()->getConnections(); - foreach(const CANConnection* conn_p, conns) - rows += conn_p->getNumBuses(); - - //qDebug() << "Num Rows: " << rows; - - return rows; -} - -Qt::ItemFlags CANConnectionModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - return Qt::ItemFlag::NoItemFlags; - - int busId; - CANConnection *conn_p = getAtIdx(index.row(), busId); - if (!conn_p) return Qt::ItemFlag::NoItemFlags; - - //socketcan is limited for what you can set but the other serialbus - //devices should be able to set the stuff. For now let anyone try - //and the underlying drivers can do with them as they will - bool editParams = true; - //if (conn_p->getType() == CANCon::GVRET_SERIAL) editParams = true; - - switch (Column(index.column())) - { - case Column::Speed: - if (editParams) return Qt::ItemFlag::ItemIsEditable | Qt::ItemFlag::ItemIsEnabled; - return Qt::ItemFlag::NoItemFlags; - case Column::ListenOnly: - case Column::SingleWire: - if (editParams) return Qt::ItemFlag::ItemIsEditable | Qt::ItemFlag::ItemIsEnabled | Qt::ItemFlag::ItemIsUserCheckable; - return Qt::ItemFlag::NoItemFlags; - case Column::Active: - return Qt::ItemFlag::ItemIsEditable | Qt::ItemFlag::ItemIsEnabled | Qt::ItemFlag::ItemIsUserCheckable; - default: - return Qt::ItemFlag::ItemIsEnabled; - } -} - -bool CANConnectionModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - qDebug() << "setData: " << index.row() << ":" << index.column() << " role: " << role << " Val: " << value; - - int busId; - CANConnection *conn_p = getAtIdx(index.row(), busId); - if (!conn_p) return false; - CANBus bus; - bool ret; - ret = conn_p->getBusSettings(busId, bus); - if (!ret) return false; - - switch (Column(index.column())) - { - case Column::Speed: - bus.speed = value.toInt(); - break; - case Column::ListenOnly: - bus.listenOnly = value.toBool(); - break; - case Column::SingleWire: - bus.singleWire = value.toBool(); - break; - case Column::Active: - bus.active = value.toBool(); - break; - default: {} - } - conn_p->setBusSettings(busId, bus); - return true; + return conns.count(); } QVariant CANConnectionModel::data(const QModelIndex &index, int role) const @@ -147,23 +69,16 @@ QVariant CANConnectionModel::data(const QModelIndex &index, int role) const return QVariant(); //qDebug() << "Row: " << index.row(); - int busId; - CANConnection *conn_p = getAtIdx(index.row(), busId); - CANBus bus; + CANConnection *conn_p = getAtIdx(index.row()); bool ret; if (!conn_p) return QVariant(); - ret = conn_p->getBusSettings(busId, bus); - bool isSocketCAN = (conn_p->getType() == CANCon::SERIALBUS) ? true: false; - //qDebug() << "ConnP: " << conn_p << " ret " << ret; + bool isSocketCAN = (conn_p->getType() == CANCon::SERIALBUS) ? true: false; if (role == Qt::DisplayRole) { switch (Column(index.column())) { - case Column::Bus: - //return QString::number(busId); - return QString::number(index.row()); case Column::Type: if (conn_p) switch (conn_p->getType()) { @@ -178,34 +93,16 @@ QVariant CANConnectionModel::data(const QModelIndex &index, int role) const if (conn_p) return conn_p->getPort(); else qDebug() << "Tried to show connection port but connection was NULL"; break; - case Column::Speed: - if(!ret) return QVariant(); - if (!isSocketCAN) return QString::number(bus.speed); - else return QString("N/A"); - case Column::ListenOnly: - return QVariant(); - case Column::SingleWire: - return QVariant(); - case Column::Active: - return QVariant(); + case Column::Subtype: + return conn_p->getDriver(); + break; + case Column::NumBuses: + return conn_p->getNumBuses(); + break; case Column::Status: return (conn_p->getStatus()==CANCon::CONNECTED) ? "Connected" : "Not Connected"; } } - if (role == Qt::CheckStateRole) - { - switch (Column(index.column())) - { - case Column::ListenOnly: - return (bus.listenOnly) ? Qt::Checked : Qt::Unchecked; - case Column::SingleWire: - return (bus.singleWire) ? Qt::Checked : Qt::Unchecked; - case Column::Active: - return (bus.active) ? Qt::Checked : Qt::Unchecked; - default: {} - } - } - return QVariant(); } @@ -230,25 +127,14 @@ void CANConnectionModel::remove(CANConnection* pConn_p) } -CANConnection* CANConnectionModel::getAtIdx(int pIdx, int& pBusId) const +CANConnection* CANConnectionModel::getAtIdx(int pIdx) const { if (pIdx < 0) return NULL; - int i=0; QList& conns = CANConManager::getInstance()->getConnections(); - foreach(CANConnection* conn_p, conns) - { - if( i <= pIdx && pIdx < i+conn_p->getNumBuses() ) { - pBusId = pIdx - i; - return conn_p; - } - - i+= conn_p->getNumBuses(); - } - - return NULL; + return conns.at(pIdx); } void CANConnectionModel::refresh(int pIndex) diff --git a/connections/canconnectionmodel.h b/connections/canconnectionmodel.h index f4a0094..8ea3ed3 100644 --- a/connections/canconnectionmodel.h +++ b/connections/canconnectionmodel.h @@ -21,15 +21,12 @@ public: int columnCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - Qt::ItemFlags flags(const QModelIndex &index) const override; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; - int rowCount(const QModelIndex &parent = QModelIndex()) const override; void add(CANConnection* pConn_p); void remove(CANConnection* pConn_p); - CANConnection* getAtIdx(int, int&) const; + CANConnection* getAtIdx(int) const; void refresh(int pIndex=-1); }; diff --git a/connections/connectionwindow.cpp b/connections/connectionwindow.cpp index 07f6804..86c592b 100644 --- a/connections/connectionwindow.cpp +++ b/connections/connectionwindow.cpp @@ -10,6 +10,7 @@ #include "connections/canconmanager.h" #include "canbus.h" #include +#include ConnectionWindow::ConnectionWindow(QWidget *parent) : QDialog(parent), @@ -24,16 +25,15 @@ ConnectionWindow::ConnectionWindow(QWidget *parent) : qRegisterMetaType("const CANFrame *"); qRegisterMetaType *>("const QList *"); + + //List of devices with details. None of it can be edited. connection type, serialbus type, port name, number of buses, status connModel = new CANConnectionModel(this); ui->tableConnections->setModel(connModel); - ui->tableConnections->setColumnWidth(0, 40); - ui->tableConnections->setColumnWidth(1, 70); - ui->tableConnections->setColumnWidth(2, 70); + ui->tableConnections->setColumnWidth(0, 100); + ui->tableConnections->setColumnWidth(1, 100); + ui->tableConnections->setColumnWidth(2, 100); ui->tableConnections->setColumnWidth(3, 70); - ui->tableConnections->setColumnWidth(4, 70); - ui->tableConnections->setColumnWidth(5, 70); - ui->tableConnections->setColumnWidth(6, 70); - ui->tableConnections->setColumnWidth(7, 90); + ui->tableConnections->setColumnWidth(4, 200); QHeaderView *HorzHdr = ui->tableConnections->horizontalHeader(); HorzHdr->setStretchLastSection(true); //causes the data column to automatically fill the tableview @@ -47,32 +47,30 @@ ConnectionWindow::ConnectionWindow(QWidget *parent) : { /* load connection configuration */ loadConnections(); - } + } - ui->rbSocketCAN->setEnabled(isSerialBusAvailable()); - - connect(ui->btnOK, &QAbstractButton::clicked, this, &ConnectionWindow::handleOKButton); - connect(ui->rbGVRET, &QAbstractButton::clicked, this, &ConnectionWindow::handleConnTypeChanged); - connect(ui->rbSocketCAN, &QAbstractButton::clicked, this, &ConnectionWindow::handleConnTypeChanged); - connect(ui->rbRemote, &QAbstractButton::clicked, this, &ConnectionWindow::handleConnTypeChanged); - connect(ui->cbDeviceType, QOverload::of(&QComboBox::currentIndexChanged), this, &ConnectionWindow::handleDeviceTypeChanged); - connect(ui->tableConnections->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &ConnectionWindow::currentRowChanged); - connect(ui->btnActivateAll, &QPushButton::clicked, this, &ConnectionWindow::handleEnableAll); - connect(ui->btnDeactivateAll, &QPushButton::clicked, this, &ConnectionWindow::handleDisableAll); - connect(ui->btnReconnect, &QPushButton::clicked, this, &ConnectionWindow::handleReconnect); - connect(ui->btnRemoveBus, &QPushButton::clicked, this, &ConnectionWindow::handleRemoveConn); - connect(ui->btnClearDebug, &QPushButton::clicked, this, &ConnectionWindow::handleClearDebugText); + connect(ui->btnDisconnect, &QPushButton::clicked, this, &ConnectionWindow::handleRemoveConn); connect(ui->btnSendHex, &QPushButton::clicked, this, &ConnectionWindow::handleSendHex); connect(ui->btnSendText, &QPushButton::clicked, this, &ConnectionWindow::handleSendText); connect(ui->ckEnableConsole, &QCheckBox::toggled, this, &ConnectionWindow::consoleEnableChanged); + connect(ui->btnClearDebug, &QPushButton::clicked, this, &ConnectionWindow::handleClearDebugText); + connect(ui->btnNewConnection, &QPushButton::clicked, this, &ConnectionWindow::handleNewConn); + connect(ui->tableConnections->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &ConnectionWindow::currentRowChanged); + connect(ui->tabBuses, &QTabBar::currentChanged, this, &ConnectionWindow::currentTabChanged); + connect(ui->btnSaveBus, &QPushButton::clicked, this, &ConnectionWindow::saveBusSettings); - ui->lblDeviceType->setHidden(true); - ui->cbDeviceType->setHidden(true); + ui->cbBusSpeed->addItem("50000"); + ui->cbBusSpeed->addItem("100000"); + ui->cbBusSpeed->addItem("125000"); + ui->cbBusSpeed->addItem("250000"); + ui->cbBusSpeed->addItem("500000"); + ui->cbBusSpeed->addItem("1000000"); rxBroadcast = new QUdpSocket(this); rxBroadcast->bind(QHostAddress::AnyIPv4, 17222); connect(rxBroadcast, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams())); + } @@ -114,7 +112,6 @@ void ConnectionWindow::showEvent(QShowEvent* event) readSettings(); ui->tableConnections->selectRow(0); currentRowChanged(ui->tableConnections->currentIndex(), ui->tableConnections->currentIndex()); - handleConnTypeChanged(); } void ConnectionWindow::closeEvent(QCloseEvent *event) @@ -163,48 +160,6 @@ void ConnectionWindow::writeSettings() } } -void ConnectionWindow::setSuspendAll(bool pSuspend) -{ - QList& conns = CANConManager::getInstance()->getConnections(); - - foreach(CANConnection* conn_p, conns) - conn_p->suspend(pSuspend); - - connModel->refresh(); -} - - -void ConnectionWindow::setActiveAll(bool pActive) -{ - CANBus bus; - QList& conns = CANConManager::getInstance()->getConnections(); - - foreach(CANConnection* conn_p, conns) - { - for(int i=0 ; igetNumBuses() ; i++) { - if( conn_p->getBusSettings(i, bus) ) { - bus.active = pActive; - conn_p->setBusSettings(i, bus); - } - } - } - - connModel->refresh(); -} - -void ConnectionWindow::handleReconnect() -{ - int selIdx = ui->tableConnections->selectionModel()->currentIndex().row(); - if (selIdx <0) return; - - int busId; - CANConnection* conn_p = connModel->getAtIdx(selIdx, busId); - if(!conn_p) return; - - conn_p->stop(); - conn_p->start(); -} - void ConnectionWindow::consoleEnableChanged(bool checked) { ui->textConsole->setEnabled(checked); ui->btnClearDebug->setEnabled(checked); @@ -229,35 +184,21 @@ void ConnectionWindow::consoleEnableChanged(bool checked) { void ConnectionWindow::handleNewConn() { - ui->tableConnections->setCurrentIndex(QModelIndex()); - currentRowChanged(ui->tableConnections->currentIndex(), ui->tableConnections->currentIndex()); -} + NewConnectionDialog *thisDialog = new NewConnectionDialog(&remoteDeviceIP); + CANCon::type newType; + QString newPort; + QString newDriver; + CANConnection *conn; - -void ConnectionWindow::handleEnableAll() -{ - setActiveAll(true); -} - -void ConnectionWindow::handleDisableAll() -{ - setActiveAll(false); -} - -void ConnectionWindow::handleConnTypeChanged() -{ - if (ui->rbGVRET->isChecked()) selectSerial(); - if (ui->rbSocketCAN->isChecked()) selectSocketCan(); - if (ui->rbRemote->isChecked()) selectRemote(); -} - -void ConnectionWindow::handleDeviceTypeChanged() -{ - ui->cbPort->clear(); - canDevices = QCanBus::instance()->availableDevices(ui->cbDeviceType->currentText()); - - for (int i = 0; i < canDevices.count(); i++) - ui->cbPort->addItem(canDevices[i].name()); + if (thisDialog->exec() == QDialog::Accepted) + { + newType = thisDialog->getConnectionType(); + newPort = thisDialog->getPortName(); + newDriver = thisDialog->getDriverName(); + conn = create(newType, newPort, newDriver); + if (conn) connModel->add(conn); + } + delete thisDialog; } /* status */ @@ -269,22 +210,79 @@ void ConnectionWindow::connectionStatus(CANConStatus pStatus) connModel->refresh(); } - -void ConnectionWindow::handleOKButton() +void ConnectionWindow::saveBusSettings() { - CANConnection* conn_p = nullptr; + int selIdx = ui->tableConnections->currentIndex().row(); + int offset = ui->tabBuses->currentIndex(); - if( ! CANConManager::getInstance()->getByName(getPortName()) ) - { - /* create connection */ - //qDebug() << "Create connection type: " << getConnectionType() << " port: " << getPortName() << " driver: " << getDriverName(); - conn_p = create(getConnectionType(), getPortName(), getDriverName()); - if(!conn_p) - return; - /* add connection to model */ - connModel->add(conn_p); - consoleEnableChanged(ui->ckEnableConsole->isChecked()); + /* set parameters */ + if (selIdx == -1) { + return; } + else + { + CANConnection* conn_p = connModel->getAtIdx(selIdx); + CANBus bus; + if(!conn_p) return; + + if (!conn_p->getBusSettings(offset, bus)) + { + qDebug() << "Could not retrieve bus settings!"; + return; + } + + bus.setSpeed(ui->cbBusSpeed->currentText().toInt()); + bus.setActive(ui->ckEnable->isChecked()); + bus.setListenOnly(ui->ckListenOnly->isChecked()); + conn_p->setBusSettings(offset, bus); + } +} + +void ConnectionWindow::populateBusDetails(int offset) +{ + int selIdx = ui->tableConnections->currentIndex().row(); + + /* set parameters */ + if (selIdx == -1) { + return; + } + else + { + bool ret; + int numBuses; + + CANConnection* conn_p = connModel->getAtIdx(selIdx); + CANBus bus; + if(!conn_p) return; + + if (!conn_p->getBusSettings(offset, bus)) + { + qDebug() << "Could not retrieve bus settings!"; + return; + } + + int busBase = CANConManager::getInstance()->getBusBase(conn_p); + ui->lblBusNum->setText(QString::number(busBase + offset)); + ui->ckListenOnly->setChecked(bus.isListenOnly()); + ui->ckEnable->setChecked(bus.isActive()); + + bool found = false; + for (int i = 0; i < ui->cbBusSpeed->count(); i++) + { + if (bus.getSpeed() == ui->cbBusSpeed->itemText(i).toInt()) + { + found = true; + ui->cbBusSpeed->setCurrentIndex(i); + break; + } + } + if (!found) ui->cbBusSpeed->addItem(QString::number(bus.getSpeed())); + } +} + +void ConnectionWindow::currentTabChanged(int newIdx) +{ + populateBusDetails(newIdx); } void ConnectionWindow::currentRowChanged(const QModelIndex ¤t, const QModelIndex &previous) @@ -293,43 +291,33 @@ void ConnectionWindow::currentRowChanged(const QModelIndex ¤t, const QMode int selIdx = current.row(); - int busId; - - disconnect(connModel->getAtIdx(previous.row(), busId), SIGNAL(debugOutput(QString)), 0, 0); - disconnect(this, SIGNAL(sendDebugData(QByteArray)), connModel->getAtIdx(previous.row(), busId), SLOT(debugInput(QByteArray))); -return; - - /* enable / diable connection type */ - ui->stPort->setEnabled(selIdx==-1); - ui->gbType->setEnabled(selIdx==-1); - ui->lPort->setEnabled(selIdx==-1); + disconnect(connModel->getAtIdx(previous.row()), SIGNAL(debugOutput(QString)), 0, 0); + disconnect(this, SIGNAL(sendDebugData(QByteArray)), connModel->getAtIdx(previous.row()), SLOT(debugInput(QByteArray))); /* set parameters */ - if (selIdx == -1) - { - ui->btnOK->setText(tr("Create New Connection")); - ui->rbGVRET->setChecked(true); - setSpeed(0); - setPortName(CANCon::GVRET_SERIAL, "", ""); + if (selIdx == -1) { + ui->groupBus->setEnabled(false); + return; } else { bool ret; - CANBus bus; - CANConnection* conn_p = connModel->getAtIdx(selIdx, busId); + ui->groupBus->setEnabled(true); + int numBuses; + + CANConnection* conn_p = connModel->getAtIdx(selIdx); if(!conn_p) return; - if (ui->ckEnableConsole->isChecked()) { //only connect if console is actually enabled - connect(conn_p, SIGNAL(debugOutput(QString)), this, SLOT(getDebugText(QString))); - connect(this, SIGNAL(sendDebugData(QByteArray)), conn_p, SLOT(debugInput(QByteArray))); + numBuses = conn_p->getNumBuses(); + if (numBuses == 1) //remove all tabs if there is only one bus + { + for (int i = 0; i < ui->tabBuses->count(); i++) ui->tabBuses->removeTab(0); } - - ret = conn_p->getBusSettings(busId, bus); - if(!ret) return; - - ui->btnOK->setText(tr("Update Connection Settings")); - setSpeed(bus.getSpeed()); - setPortName(conn_p->getType(), conn_p->getPort(), conn_p->getDriver()); + else + { + for (int i = 0; i < numBuses; i++) ui->tabBuses->addTab(QString::number(i+1)); + } + populateBusDetails(0); } } @@ -357,152 +345,6 @@ void ConnectionWindow::handleSendText() { emit sendDebugData(bytes); } -void ConnectionWindow::selectSerial() -{ - ui->lPort->setText("Port:"); - /* set combobox page visible */ - ui->stPort->setCurrentWidget(ui->cbPage); - ui->lblDeviceType->setHidden(true); - ui->cbDeviceType->setHidden(true); - - ui->cbPort->clear(); - ports = QSerialPortInfo::availablePorts(); - - for (int i = 0; i < ports.count(); i++) - ui->cbPort->addItem(ports[i].portName()); -} - -void ConnectionWindow::selectSocketCan() -{ - ui->lPort->setText("Port:"); - /* set edit text page visible */ - ui->stPort->setCurrentWidget(ui->cbPage); - ui->lblDeviceType->setHidden(false); - ui->cbDeviceType->setHidden(false); - - ui->cbDeviceType->clear(); - QStringList plugins; - plugins = QCanBus::instance()->plugins(); - for (int i = 0; i < plugins.count(); i++) - ui->cbDeviceType->addItem(plugins[i]); -} - -void ConnectionWindow::selectRemote() -{ - ui->lPort->setText("IP Address:"); - ui->stPort->setCurrentWidget(ui->cbPage); - ui->lblDeviceType->setHidden(true); - ui->cbDeviceType->setHidden(true); - ui->cbPort->clear(); - foreach(QString pName, remoteDeviceIP) - { - ui->cbPort->addItem(pName); - } -} - -void ConnectionWindow::setSpeed(int speed0) -{ - Q_UNUSED(speed0); -} - -void ConnectionWindow::setPortName(CANCon::type pType, QString pPortName, QString pDriver) -{ - switch(pType) - { - case CANCon::GVRET_SERIAL: - ui->rbGVRET->setChecked(true); - break; - case CANCon::SERIALBUS: - ui->rbSocketCAN->setChecked(true); - //you can't configure any of the below three with socketcan so dim them out - break; - default: {} - } - - /* refresh names whenever needed */ - handleConnTypeChanged(); - - switch(pType) - { - case CANCon::GVRET_SERIAL: - { - int idx = ui->cbPort->findText(pPortName); - if( idx<0 ) idx=0; - ui->cbPort->setCurrentIndex(idx); - break; - } - case CANCon::SERIALBUS: - { - int idx = ui->cbDeviceType->findText(pDriver); - if (idx < 0) idx = 0; - ui->cbDeviceType->setCurrentIndex(idx); - idx = ui->cbPort->findText(pPortName); - if( idx < 0 ) idx = 0; - ui->cbPort->setCurrentIndex(idx); - break; - } - case CANCon::REMOTE: - { - int idx = ui->cbPort->findText(pPortName); - if (idx > -1) ui->cbPort->setCurrentIndex(idx); - else ui->cbPort->addItem(pPortName); - break; - } - default: {} - } -} - - -//-1 means leave it at whatever it booted up to. 0 means disable. Otherwise the actual rate we want. -int ConnectionWindow::getSpeed() -{ - return -1; -} - -QString ConnectionWindow::getPortName() -{ - switch( getConnectionType() ) { - case CANCon::GVRET_SERIAL: - case CANCon::SERIALBUS: - case CANCon::REMOTE: - return ui->cbPort->currentText(); - default: - qDebug() << "getPortName: can't get port"; - } - - return ""; -} - -QString ConnectionWindow::getDriverName() -{ - if (getConnectionType() == CANCon::SERIALBUS) - { - return ui->cbDeviceType->currentText(); - } - - return ""; -} - -CANCon::type ConnectionWindow::getConnectionType() -{ - if (ui->rbGVRET->isChecked()) return CANCon::GVRET_SERIAL; - if (ui->rbSocketCAN->isChecked()) return CANCon::SERIALBUS; - if (ui->rbRemote->isChecked()) return CANCon::REMOTE; - qDebug() << "getConnectionType: error"; - return CANCon::NONE; -} - - -void ConnectionWindow::setSWMode(bool mode) -{ - Q_UNUSED(mode); -} - -bool ConnectionWindow::getSWMode() -{ - return false; -} - void ConnectionWindow::handleRemoveConn() { int selIdx = ui->tableConnections->selectionModel()->currentIndex().row(); @@ -510,8 +352,7 @@ void ConnectionWindow::handleRemoveConn() qDebug() << "remove connection at index: " << selIdx; - int busId; - CANConnection* conn_p = connModel->getAtIdx(selIdx, busId); + CANConnection* conn_p = connModel->getAtIdx(selIdx); if(!conn_p) return; /* remove connection from model & manager */ @@ -525,19 +366,6 @@ void ConnectionWindow::handleRemoveConn() ui->tableConnections->selectRow(0); } -void ConnectionWindow::handleRevert() -{ - -} - - -bool ConnectionWindow::isSerialBusAvailable() -{ - if (QCanBus::instance()->plugins().count() > 0) return true; - return false; -} - - CANConnection* ConnectionWindow::create(CANCon::type pTye, QString pPortName, QString pDriver) { CANConnection* conn_p; diff --git a/connections/connectionwindow.h b/connections/connectionwindow.h index 515d34e..bf6bd77 100644 --- a/connections/connectionwindow.h +++ b/connections/connectionwindow.h @@ -3,8 +3,8 @@ -#include #include +#include #include #include #include @@ -30,61 +30,36 @@ public: explicit ConnectionWindow(QWidget *parent = 0); ~ConnectionWindow(); - CANCon::type getConnectionType(); - bool getSWMode(); - signals: void updateBusSettings(CANBus *bus); void updatePortName(QString port); void sendDebugData(QByteArray bytes); public slots: - void setSpeed(int speed0); - void setSWMode(bool mode); - - void setSuspendAll(bool pSuspend); - void getDebugText(QString debugText); private slots: - void handleOKButton(); - void handleConnTypeChanged(); - void handleDeviceTypeChanged(); void currentRowChanged(const QModelIndex ¤t, const QModelIndex &previous); + void currentTabChanged(int newIdx); void consoleEnableChanged(bool checked); void handleRemoveConn(); - void handleEnableAll(); - void handleDisableAll(); - void handleReconnect(); - void handleRevert(); void handleNewConn(); void handleClearDebugText(); void handleSendHex(); void handleSendText(); + void saveBusSettings(); void connectionStatus(CANConStatus); void readPendingDatagrams(); private: - Ui::ConnectionWindow *ui; - QList ports; - QList canDevices; + Ui::ConnectionWindow *ui; QSettings *settings; CANConnectionModel *connModel; QUdpSocket *rxBroadcast; QVector remoteDeviceIP; - void selectSerial(); - void selectKvaser(); - void selectSocketCan(); - void selectRemote(); - bool isSerialBusAvailable(); - int getSpeed(); - QString getPortName(); - QString getDriverName(); - void setPortName(CANCon::type pType, QString pPortName, QString pDriver); - - void setActiveAll(bool pActive); CANConnection* create(CANCon::type pTye, QString pPortName, QString pDriver); + void populateBusDetails(int offset); void loadConnections(); void saveConnections(); void showEvent(QShowEvent *); diff --git a/connections/gvretserial.cpp b/connections/gvretserial.cpp index 86d1b0f..0d42518 100644 --- a/connections/gvretserial.cpp +++ b/connections/gvretserial.cpp @@ -819,8 +819,8 @@ void GVRetSerial::procRXChar(unsigned char c) qDebug() << "Baud 1 = " << can1Baud; mBusData[0].mBus.setSpeed(can0Baud); mBusData[1].mBus.setSpeed(can1Baud); - mBusData[0].mBus.setEnabled(can0Enabled); - mBusData[1].mBus.setEnabled(can1Enabled); + mBusData[0].mBus.setActive(can0Enabled); + mBusData[1].mBus.setActive(can1Enabled); mBusData[0].mConfigured = true; mBusData[1].mConfigured = true; @@ -962,7 +962,7 @@ void GVRetSerial::procRXChar(unsigned char c) if (getNumBuses() > 2) { mBusData[2].mBus.setSpeed(swcanBaud); - mBusData[2].mBus.setEnabled(swcanEnabled); + mBusData[2].mBus.setActive(swcanEnabled); } setStatus(CANCon::CONNECTED); diff --git a/connections/newconnectiondialog.cpp b/connections/newconnectiondialog.cpp new file mode 100644 index 0000000..ad15569 --- /dev/null +++ b/connections/newconnectiondialog.cpp @@ -0,0 +1,177 @@ +#include +#include "newconnectiondialog.h" +#include "ui_newconnectiondialog.h" + +NewConnectionDialog::NewConnectionDialog(QVector* ips, QWidget *parent) : + QDialog(parent), + ui(new Ui::NewConnectionDialog), + remoteDeviceIP(ips) +{ + ui->setupUi(this); + + ui->rbSocketCAN->setEnabled(isSerialBusAvailable()); + + connect(ui->rbGVRET, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged); + connect(ui->rbSocketCAN, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged); + connect(ui->rbRemote, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged); + connect(ui->cbDeviceType, QOverload::of(&QComboBox::currentIndexChanged), this, &NewConnectionDialog::handleDeviceTypeChanged); + connect(ui->btnOK, &QPushButton::clicked, this, &NewConnectionDialog::handleCreateButton); + + ui->lblDeviceType->setHidden(true); + ui->cbDeviceType->setHidden(true); + selectSerial(); +} + +NewConnectionDialog::~NewConnectionDialog() +{ + delete ui; +} + +void NewConnectionDialog::handleCreateButton() +{ + accept(); +} + +void NewConnectionDialog::handleConnTypeChanged() +{ + if (ui->rbGVRET->isChecked()) selectSerial(); + if (ui->rbSocketCAN->isChecked()) selectSocketCan(); + if (ui->rbRemote->isChecked()) selectRemote(); +} + +void NewConnectionDialog::handleDeviceTypeChanged() +{ + + ui->cbPort->clear(); + canDevices = QCanBus::instance()->availableDevices(ui->cbDeviceType->currentText()); + + for (int i = 0; i < canDevices.count(); i++) + ui->cbPort->addItem(canDevices[i].name()); +} + +void NewConnectionDialog::selectSerial() +{ + ui->lPort->setText("Serial Port:"); + + ui->lblDeviceType->setHidden(true); + ui->cbDeviceType->setHidden(true); + + ui->cbPort->clear(); + ports = QSerialPortInfo::availablePorts(); + + for (int i = 0; i < ports.count(); i++) + ui->cbPort->addItem(ports[i].portName()); +} + +void NewConnectionDialog::selectSocketCan() +{ + ui->lPort->setText("Port:"); + ui->lblDeviceType->setHidden(false); + ui->cbDeviceType->setHidden(false); + + ui->cbDeviceType->clear(); + QStringList plugins; + plugins = QCanBus::instance()->plugins(); + for (int i = 0; i < plugins.count(); i++) + ui->cbDeviceType->addItem(plugins[i]); + +} + +void NewConnectionDialog::selectRemote() +{ + ui->lPort->setText("IP Address:"); + ui->lblDeviceType->setHidden(true); + ui->cbDeviceType->setHidden(true); + ui->cbPort->clear(); + foreach(QString pName, *remoteDeviceIP) + { + ui->cbPort->addItem(pName); + } +} + +void NewConnectionDialog::setPortName(CANCon::type pType, QString pPortName, QString pDriver) +{ + + switch(pType) + { + case CANCon::GVRET_SERIAL: + ui->rbGVRET->setChecked(true); + break; + case CANCon::SERIALBUS: + ui->rbSocketCAN->setChecked(true); + //you can't configure any of the below three with socketcan so dim them out + break; + default: {} + } + + /* refresh names whenever needed */ + //handleConnTypeChanged(); + + switch(pType) + { + case CANCon::GVRET_SERIAL: + { + int idx = ui->cbPort->findText(pPortName); + if( idx<0 ) idx=0; + ui->cbPort->setCurrentIndex(idx); + break; + } + case CANCon::SERIALBUS: + { + int idx = ui->cbDeviceType->findText(pDriver); + if (idx < 0) idx = 0; + ui->cbDeviceType->setCurrentIndex(idx); + idx = ui->cbPort->findText(pPortName); + if( idx < 0 ) idx = 0; + ui->cbPort->setCurrentIndex(idx); + break; + } + case CANCon::REMOTE: + { + int idx = ui->cbPort->findText(pPortName); + if (idx > -1) ui->cbPort->setCurrentIndex(idx); + else ui->cbPort->addItem(pPortName); + break; + } + default: {} + } +} + +QString NewConnectionDialog::getPortName() +{ + switch( getConnectionType() ) { + case CANCon::GVRET_SERIAL: + case CANCon::SERIALBUS: + case CANCon::REMOTE: + return ui->cbPort->currentText(); + default: + qDebug() << "getPortName: can't get port"; + } + + return ""; +} + +QString NewConnectionDialog::getDriverName() +{ + if (getConnectionType() == CANCon::SERIALBUS) + { + return ui->cbDeviceType->currentText(); + } + return "N/A"; +} + +CANCon::type NewConnectionDialog::getConnectionType() +{ + if (ui->rbGVRET->isChecked()) return CANCon::GVRET_SERIAL; + if (ui->rbSocketCAN->isChecked()) return CANCon::SERIALBUS; + if (ui->rbRemote->isChecked()) return CANCon::REMOTE; + qDebug() << "getConnectionType: error"; + + return CANCon::NONE; +} + +bool NewConnectionDialog::isSerialBusAvailable() +{ + if (QCanBus::instance()->plugins().count() > 0) return true; + return false; +} diff --git a/connections/newconnectiondialog.h b/connections/newconnectiondialog.h new file mode 100644 index 0000000..f826b70 --- /dev/null +++ b/connections/newconnectiondialog.h @@ -0,0 +1,47 @@ +#ifndef NEWCONNECTIONDIALOG_H +#define NEWCONNECTIONDIALOG_H + +#include +#include +#include +#include +#include +#include "canconnectionmodel.h" +#include "connections/canconnection.h" + +namespace Ui { +class NewConnectionDialog; +} + +class NewConnectionDialog : public QDialog +{ + Q_OBJECT + +public: + explicit NewConnectionDialog(QVector* ips, QWidget *parent = nullptr); + ~NewConnectionDialog(); + + CANCon::type getConnectionType(); + QString getPortName(); + QString getDriverName(); + +public slots: + void handleConnTypeChanged(); + void handleDeviceTypeChanged(); + void handleCreateButton(); + +private: + Ui::NewConnectionDialog *ui; + QList ports; + QList canDevices; + QVector* remoteDeviceIP; + + void selectSerial(); + void selectKvaser(); + void selectSocketCan(); + void selectRemote(); + bool isSerialBusAvailable(); + void setPortName(CANCon::type pType, QString pPortName, QString pDriver); +}; + +#endif // NEWCONNECTIONDIALOG_H diff --git a/connections/serialbusconnection.cpp b/connections/serialbusconnection.cpp index af67b9e..03891ff 100644 --- a/connections/serialbusconnection.cpp +++ b/connections/serialbusconnection.cpp @@ -46,7 +46,7 @@ void SerialBusConnection::piStarted() mTimer.setInterval(1000); mTimer.setSingleShot(false); //keep ticking mTimer.start(); - mBusData[0].mBus.setEnabled(true); + mBusData[0].mBus.setActive(true); mBusData[0].mConfigured = true; } @@ -281,7 +281,7 @@ void SerialBusConnection::testConnection() { CANBus bus; if(getBusConfig(0, bus)) { - bus.setEnabled(true); + bus.setActive(true); setBusSettings(0, bus); } diff --git a/ui/connectionwindow.ui b/ui/connectionwindow.ui index 0e52eae..d132606 100644 --- a/ui/connectionwindow.ui +++ b/ui/connectionwindow.ui @@ -19,7 +19,7 @@ - Connections: + Connected Devices: @@ -37,195 +37,104 @@ - - - - - Reconnect - - - - - - - Remove Selected Connection - - - - - - - Activate All Connections - - - - - - - Deactivate All Connections - - - - + + + Add New Device Connection + + + + + + + Disconnect Selected Device + + + + + + + false + + + Bus Details: + + + Qt::AlignCenter + + + + + + + + + + + CAN Bus Number: + + + + + + + + + + + + + + Speed: + + + + + + + + + + Listen Only: + + + + + + + + + + + + + + Enable Bus: + + + + + + + + + + + + + + Save Bus Settings + + + + + + + - - - - Connection Type - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - GVRET Serial - - - true - - - - - - - false - - - QT SerialBus Devices (SocketCAN, PeakCAN, etc) - - - - - - - Remote Host - - - - - - - - - - Device Type: - - - - - - - - - - - 0 - 0 - - - - Port: - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - Qt::LeftToRight - - - 1 - - - - - 0 - 0 - - - - Qt::LeftToRight - - - - - - - 0 - 0 - - - - - 341 - 16777215 - - - - true - - - - - - - - - - - - 0 - 0 - - - - - - - - - - - - - - Create New Connection - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - @@ -299,6 +208,13 @@ + + + QTabBar + QWidget +
qtabbar.h
+
+
diff --git a/ui/newconnectiondialog.ui b/ui/newconnectiondialog.ui new file mode 100644 index 0000000..de55127 --- /dev/null +++ b/ui/newconnectiondialog.ui @@ -0,0 +1,109 @@ + + + NewConnectionDialog + + + + 0 + 0 + 356 + 282 + + + + New Connection + + + + + + Connection Type + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + Serial Connection + + + true + + + + + + + false + + + QT SerialBus Devices (SocketCAN, PeakCAN, etc) + + + + + + + Network connection + + + + + + + + + + SerialBus Device Type: + + + + + + + + + + + 0 + 0 + + + + Serial Port: + + + + + + + + 0 + 0 + + + + + 341 + 16777215 + + + + true + + + + + + + Create New Connection + + + + + + + + From f23abe170f768a4562b1d9ead1b7e71559be67ed Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Wed, 6 Mar 2019 19:59:19 -0500 Subject: [PATCH 14/33] Fix a glitch with the new connection window and bus settings --- connections/connectionwindow.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/connections/connectionwindow.cpp b/connections/connectionwindow.cpp index 86c592b..5ab3f69 100644 --- a/connections/connectionwindow.cpp +++ b/connections/connectionwindow.cpp @@ -309,14 +309,11 @@ void ConnectionWindow::currentRowChanged(const QModelIndex ¤t, const QMode if(!conn_p) return; numBuses = conn_p->getNumBuses(); - if (numBuses == 1) //remove all tabs if there is only one bus - { - for (int i = 0; i < ui->tabBuses->count(); i++) ui->tabBuses->removeTab(0); - } - else - { - for (int i = 0; i < numBuses; i++) ui->tabBuses->addTab(QString::number(i+1)); - } + int numB = ui->tabBuses->count(); + for (int i = 0; i < numB; i++) ui->tabBuses->removeTab(0); + + if (numBuses > 1) for (int i = 0; i < numBuses; i++) ui->tabBuses->addTab(QString::number(i+1)); + populateBusDetails(0); } } From 591ebe71df7df5c116145b2b5596c7b107fc5db3 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Wed, 6 Mar 2019 20:20:40 -0500 Subject: [PATCH 15/33] Fixes to debug console in connection window --- connections/connectionwindow.cpp | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/connections/connectionwindow.cpp b/connections/connectionwindow.cpp index 5ab3f69..0c2faea 100644 --- a/connections/connectionwindow.cpp +++ b/connections/connectionwindow.cpp @@ -167,18 +167,20 @@ void ConnectionWindow::consoleEnableChanged(bool checked) { ui->btnSendText->setEnabled(checked); ui->lineSend->setEnabled(checked); - QList& conns = CANConManager::getInstance()->getConnections(); + int selIdx = ui->tableConnections->currentIndex().row(); - foreach(CANConnection* conn_p, conns) - { - if (checked) { //enable console - connect(conn_p, SIGNAL(debugOutput(QString)), this, SLOT(getDebugText(QString))); - connect(this, SIGNAL(sendDebugData(QByteArray)), conn_p, SLOT(debugInput(QByteArray))); - } - else { //turn it off - disconnect(conn_p, SIGNAL(debugOutput(QString)), nullptr, nullptr); - disconnect(this, SIGNAL(sendDebugData(QByteArray)), conn_p, SLOT(debugInput(QByteArray))); - } + if (selIdx == -1) + return; + + CANConnection* conn_p = connModel->getAtIdx(selIdx); + + if (checked) { //enable console + connect(conn_p, SIGNAL(debugOutput(QString)), this, SLOT(getDebugText(QString))); + connect(this, SIGNAL(sendDebugData(QByteArray)), conn_p, SLOT(debugInput(QByteArray))); + } + else { //turn it off + disconnect(conn_p, SIGNAL(debugOutput(QString)), nullptr, nullptr); + disconnect(this, SIGNAL(sendDebugData(QByteArray)), conn_p, SLOT(debugInput(QByteArray))); } } @@ -315,6 +317,11 @@ void ConnectionWindow::currentRowChanged(const QModelIndex ¤t, const QMode if (numBuses > 1) for (int i = 0; i < numBuses; i++) ui->tabBuses->addTab(QString::number(i+1)); populateBusDetails(0); + if (ui->ckEnableConsole->isChecked()) + { + connect(conn_p, SIGNAL(debugOutput(QString)), this, SLOT(getDebugText(QString))); + connect(this, SIGNAL(sendDebugData(QByteArray)), conn_p, SLOT(debugInput(QByteArray))); + } } } From bf0492e0840c26adea38de51aaf140c26b88d7b5 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Wed, 6 Mar 2019 21:02:24 -0500 Subject: [PATCH 16/33] Fix an issue with automatic remote detection when multiple instances of SavvyCAN are running. --- connections/connectionwindow.cpp | 8 ++++++-- connections/newconnectiondialog.cpp | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/connections/connectionwindow.cpp b/connections/connectionwindow.cpp index 0c2faea..dff1476 100644 --- a/connections/connectionwindow.cpp +++ b/connections/connectionwindow.cpp @@ -31,7 +31,7 @@ ConnectionWindow::ConnectionWindow(QWidget *parent) : ui->tableConnections->setModel(connModel); ui->tableConnections->setColumnWidth(0, 100); ui->tableConnections->setColumnWidth(1, 100); - ui->tableConnections->setColumnWidth(2, 100); + ui->tableConnections->setColumnWidth(2, 130); ui->tableConnections->setColumnWidth(3, 70); ui->tableConnections->setColumnWidth(4, 200); QHeaderView *HorzHdr = ui->tableConnections->horizontalHeader(); @@ -67,7 +67,9 @@ ConnectionWindow::ConnectionWindow(QWidget *parent) : ui->cbBusSpeed->addItem("1000000"); rxBroadcast = new QUdpSocket(this); - rxBroadcast->bind(QHostAddress::AnyIPv4, 17222); + //Need to make sure it tries to share the address in case there are + //multiple instances of SavvyCAN running. + rxBroadcast->bind(QHostAddress::AnyIPv4, 17222, QAbstractSocket::ShareAddress); connect(rxBroadcast, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams())); @@ -76,11 +78,13 @@ ConnectionWindow::ConnectionWindow(QWidget *parent) : void ConnectionWindow::readPendingDatagrams() { + //qDebug() << "Got a UDP frame!"; while (rxBroadcast->hasPendingDatagrams()) { QNetworkDatagram datagram = rxBroadcast->receiveDatagram(); if (!remoteDeviceIP.contains(datagram.senderAddress().toString())) { remoteDeviceIP.append(datagram.senderAddress().toString()); + //qDebug() << "Add new remote IP " << datagram.senderAddress().toString(); } } } diff --git a/connections/newconnectiondialog.cpp b/connections/newconnectiondialog.cpp index ad15569..92ee31b 100644 --- a/connections/newconnectiondialog.cpp +++ b/connections/newconnectiondialog.cpp @@ -20,6 +20,8 @@ NewConnectionDialog::NewConnectionDialog(QVector* ips, QWidget *parent) ui->lblDeviceType->setHidden(true); ui->cbDeviceType->setHidden(true); selectSerial(); + + qDebug() << "Was passed " << remoteDeviceIP->count() << " remote IPs"; } NewConnectionDialog::~NewConnectionDialog() From ef5f41644a280e4626285e7200defa230e9ef7a0 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Mon, 11 Mar 2019 20:35:23 -0400 Subject: [PATCH 17/33] Add CANalyzer ASC saving --- framefileio.cpp | 170 +++++++++++++++++++++++++++++++++++++----------- framefileio.h | 1 + 2 files changed, 134 insertions(+), 37 deletions(-) diff --git a/framefileio.cpp b/framefileio.cpp index 713aecd..0e35579 100644 --- a/framefileio.cpp +++ b/framefileio.cpp @@ -2,6 +2,7 @@ #include #include +#include #include @@ -32,6 +33,7 @@ bool FrameFileIO::saveFrameFile(QString &fileName, const QVector* fram filters.append(QString(tr("Vehicle Spy (*.csv *.CSV)"))); filters.append(QString(tr("Candump/Kayak(*.log)"))); filters.append(QString(tr("Cabana Log(*.csv *.CSV)"))); + filters.append(QString(tr("CANalyzer Ascii Log (*.asc *.ASC)"))); dialog.setFileMode(QFileDialog::AnyFile); dialog.setNameFilters(filters); @@ -111,6 +113,12 @@ bool FrameFileIO::saveFrameFile(QString &fileName, const QVector* fram if (!filename.contains('.')) filename += ".csv"; result = saveCabanaFile(filename, frameCache); } + if (dialog.selectedNameFilter() == filters[11]) + { + if (!filename.contains('.')) filename += ".asc"; + result = saveCanalyzerASC(filename, frameCache); + } + progress.cancel(); if (result) @@ -555,7 +563,7 @@ bool FrameFileIO::loadPCANFile(QString filename, QVector* frames) { if (fileVersion == 1) { - thisFrame.timestamp = (uint32_t)(line.mid(10, 8).simplified().toFloat() * 1000.0); + thisFrame.timestamp = (uint64_t)(line.mid(10, 8).simplified().toDouble() * 1000.0); thisFrame.ID = line.mid(28, 8).simplified().toUInt(NULL, 16); if (thisFrame.ID < 0x1FFFFFFF) { @@ -587,7 +595,7 @@ bool FrameFileIO::loadPCANFile(QString filename, QVector* frames) } else if (fileVersion == 2) { - thisFrame.timestamp = (uint32_t)(line.mid(8, 13).simplified().toFloat() * 1000.0); + thisFrame.timestamp = (uint64_t)(line.mid(8, 13).simplified().toDouble() * 1000.0); thisFrame.ID = line.mid(25, 8).simplified().toUInt(NULL, 16); if (thisFrame.ID < 0x1FFFFFFF) { @@ -667,7 +675,7 @@ bool FrameFileIO::loadCanalyzerASC(QString filename, QVector* frames) QList tokens = line.simplified().split(' '); if (tokens.length() > 4) { - thisFrame.timestamp = (uint32_t)(tokens[0].toFloat() * 1000000.0); + thisFrame.timestamp = (uint64_t)(tokens[0].toDouble() * (double)1000000.0); thisFrame.ID = tokens[2].toUInt(NULL, 16); thisFrame.len = tokens[5].toUInt(); thisFrame.isReceived = tokens[3].toUpper().contains("RX"); @@ -696,6 +704,67 @@ bool FrameFileIO::loadCanalyzerASC(QString filename, QVector* frames) return !foundErrors; } +bool FrameFileIO::saveCanalyzerASC(QString filename, const QVector* frames) +{ + QFile *outFile = new QFile(filename); + int lineCounter = 0; + + if (!outFile->open(QIODevice::WriteOnly | QIODevice::Text)) + { + delete outFile; + return false; + } + + QDateTime now; + now = QDateTime::currentDateTime(); + outFile->write("date " + now.toString("MMM-dd HH:mm:ss.zzz").toUtf8()); + outFile->write("\nbase hex timestamps absolute\n"); + outFile->write("no internal event logging\n"); + outFile->write("// version 11.0.0\n"); + + for (int c = 0; c < frames->count(); c++) + { + lineCounter++; + if (lineCounter > 100) + { + qApp->processEvents(); + lineCounter = 0; + } + + outFile->write(QString::number(frames->at(c).timestamp / 1000000.0, 'f', 6).toUtf8()); + outFile->putChar(' '); + outFile->write(QString::number(frames->at(c).bus).toUtf8()); + outFile->write(" "); + if (frames->at(c).extended) + outFile->write(QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8()); + else + { + outFile->write(QString::number(frames->at(c).ID, 16).toUpper().rightJustified(3, '0').toUtf8()); + outFile->write(" "); + } + outFile->write(" "); + + if (frames->at(c).isReceived) outFile->write("Rx d "); + else outFile->write("Tx d "); + + outFile->write(QString::number(frames->at(c).len).toUtf8()); + outFile->putChar(' '); + + for (unsigned int temp = 0; temp < frames->at(c).len; temp++) + { + outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8()); + outFile->putChar(' '); + } + + outFile->write("\n"); + } + outFile->close(); + delete outFile; + + return true; +} + +//this one is pretty complicated and handled by it's own class bool FrameFileIO::loadCanalyzerBLF(QString filename, QVector *frames) { BLFHandler blf; @@ -1819,12 +1888,21 @@ bool FrameFileIO::saveCanDumpFile(QString filename, const QVector * fr delete outFile; return true; } -/* (0.003800) vcan0 164#0000c01aa8000013 */ + +/* + (0.003800) vcan0 164#0000c01aa8000013 + or + (1551774790.942758) can1 7A8 [8] F4 DC D1 83 0E 02 00 00 +*/ bool FrameFileIO::loadCanDumpFile(QString filename, QVector* frames) { QFile *inFile = new QFile(filename); CANFrame thisFrame; QByteArray line; + QList tokens; + QRegExp timeExp("^\\((\\S+)\\)$"); + QRegExp IdValExp("^(\\S+)#(\\S+)$"); + QRegExp valExp("(\\S{2})"); int lineCounter = 0; int pos = 0; bool ret; @@ -1847,50 +1925,68 @@ bool FrameFileIO::loadCanDumpFile(QString filename, QVector* frames) if (line.length() > 1) { /* tokenize */ - QList tokens = line.split(' '); + tokens.clear(); + tokens = line.simplified().split(' '); if(tokens.count()<3) continue; /* timestamp */ - QRegExp timeExp("^\\((\\S+)\\)$"); ret = timeExp.exactMatch(tokens[0]); if(!ret) continue; - thisFrame.timestamp = timeExp.cap(1).toDouble(&ret) * 1000000; + thisFrame.timestamp = (uint64_t)(timeExp.cap(1).toDouble(&ret) * (double)1000000.0); if(!ret) continue; - /* ID & value */ - QRegExp IdValExp("^(\\S+)#(\\S+)\n$"); - qDebug() << tokens[2]; - ret = IdValExp.exactMatch(tokens[2]); - if(!ret) continue; - - /* ID */ - thisFrame.ID = IdValExp.cap(1).toInt(&ret, 16); - if (IdValExp.cap(1).length() > 3) { - thisFrame.extended = true; - } else { - thisFrame.extended = false; - } - if(!ret) continue; - - QString val= IdValExp.cap(2); - QRegExp valExp("(\\S{2})"); - - pos = 0; - thisFrame.len = 0; - if (val.startsWith("R") && val.at(1).isDigit()) { - thisFrame.len = val.at(1).toLatin1() - '0'; - thisFrame.remote = true; - } else { + if (line.contains('[')) //the expanded format (second one from the above list) + { + //(1551774790.942758) can1 7A8 [8] F4 DC D1 83 0E 02 00 00 + // 0 1 2 3 4 5 6 7 8 9 10 11 + thisFrame.ID = tokens[2].toULong(nullptr, 16); + if (thisFrame.ID > 0x7FF) thisFrame.extended = true; + else thisFrame.extended = false; thisFrame.remote = false; - /* val byte per byte */ - while ((pos = valExp.indexIn(val, pos)) != -1) + thisFrame.len = tokens[3].at(1) - '0'; + for (int c = 0; c < thisFrame.len; c++) { - thisFrame.data[thisFrame.len] = valExp.cap(1).toInt(&ret, 16); - if(!ret) continue; + thisFrame.data[c] = tokens[4 + c].toInt(nullptr, 16); + } + } + else //the more concise format (first one from list above) + { + /* ID & value */ + //qDebug() << tokens[2]; + ret = IdValExp.exactMatch(tokens[2]); + if(!ret) + { + qDebug() << "ID regex didn't match!"; + continue; + } - thisFrame.len++; - pos += valExp.matchedLength(); + /* ID */ + thisFrame.ID = IdValExp.cap(1).toInt(&ret, 16); + if (IdValExp.cap(1).length() > 3) { + thisFrame.extended = true; + } else { + thisFrame.extended = false; + } + + QString val= IdValExp.cap(2); + + pos = 0; + thisFrame.len = 0; + if (val.startsWith("R") && val.at(1).isDigit()) { + thisFrame.len = val.at(1).toLatin1() - '0'; + thisFrame.remote = true; + } else { + thisFrame.remote = false; + /* val byte per byte */ + while ((pos = valExp.indexIn(val, pos)) != -1) + { + thisFrame.data[thisFrame.len] = valExp.cap(1).toInt(&ret, 16); + if(!ret) continue; + + thisFrame.len++; + pos += valExp.matchedLength(); + } } } diff --git a/framefileio.h b/framefileio.h index c60e1c7..2eea45b 100644 --- a/framefileio.h +++ b/framefileio.h @@ -57,6 +57,7 @@ public: static bool saveVehicleSpyFile(QString, const QVector*); static bool saveCanDumpFile(QString filename, const QVector * frames); static bool saveCabanaFile(QString filename, const QVector* frames); + static bool saveCanalyzerASC(QString filename, const QVector* frames); static bool openContinuousNative(); static bool closeContinuousNative(); static bool writeContinuousNative(const QVector*, int); From c9880be2c59cd702fe47ed19b026a75299c33a79 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Mon, 11 Mar 2019 20:53:45 -0400 Subject: [PATCH 18/33] Add caching to the DBC signal system so that we can show all the signals in overwrite mode. --- canframemodel.cpp | 8 +++++++- dbc/dbc_classes.cpp | 24 +++++++++++++++--------- dbc/dbc_classes.h | 2 ++ 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/canframemodel.cpp b/canframemodel.cpp index d4108fa..e82238f 100644 --- a/canframemodel.cpp +++ b/canframemodel.cpp @@ -334,11 +334,17 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const for (int j = 0; j < msg->sigHandler->getCount(); j++) { QString sigString; - if (msg->sigHandler->findSignalByIdx(j)->processAsText(thisFrame, sigString)) + DBC_SIGNAL* sig = msg->sigHandler->findSignalByIdx(j); + if (sig->processAsText(thisFrame, sigString)) { tempString.append(sigString); tempString.append("\n"); } + else if (sig->isMultiplexed && overwriteDups) //wasn't in this exact frame but is in the message. Use cached value + { + tempString.append(sig->makePrettyOutput(sig->cachedValue.toDouble(), sig->cachedValue.toLongLong())); + tempString.append("\n"); + } } } } diff --git a/dbc/dbc_classes.cpp b/dbc/dbc_classes.cpp index 7d8f013..f9106e1 100644 --- a/dbc/dbc_classes.cpp +++ b/dbc/dbc_classes.cpp @@ -49,6 +49,7 @@ bool DBC_SIGNAL::processAsText(const CANFrame &frame, QString &outString) int bytes = signalSize / 8; for (int x = 0; x < bytes; x++) buildString.append(frame.data[startByte + x]); outString = buildString; + cachedValue = outString; return true; } @@ -69,7 +70,7 @@ bool DBC_SIGNAL::processAsText(const CANFrame &frame, QString &outString) { result = Utility::processIntegerSignal(frame.data, startBit, signalSize, intelByteOrder, isSigned); endResult = ((double)result * factor) + bias; - result = (int64_t)endResult; + result = (int64_t)endResult; } else if (valType == SP_FLOAT) { @@ -94,6 +95,13 @@ bool DBC_SIGNAL::processAsText(const CANFrame &frame, QString &outString) endResult = (*((double *)(&result)) * factor) + bias; } + outString = makePrettyOutput(endResult, result); + cachedValue = endResult; + return true; +} + +QString DBC_SIGNAL::makePrettyOutput(double floatVal, int64_t intVal) +{ QString outputString; outputString = name + ": "; @@ -103,22 +111,20 @@ bool DBC_SIGNAL::processAsText(const CANFrame &frame, QString &outString) bool foundVal = false; for (int x = 0; x < valList.count(); x++) { - if (valList.at(x).value == result) + if (valList.at(x).value == intVal) { outputString += valList.at(x).descript; foundVal = true; break; } } - if (!foundVal) outputString += QString::number(endResult) + unitName; + if (!foundVal) outputString += QString::number(intVal) + unitName; } else //otherwise display the actual number and unit (if it exists) { - outputString += QString::number(endResult) + unitName; + outputString += QString::number(floatVal) + unitName; } - - outString = outputString; - return true; + return outputString; } //Works quite a bit like the above version but this one is cut down and only will return int32_t which is perfect for @@ -158,7 +164,7 @@ bool DBC_SIGNAL::processAsInt(const CANFrame &frame, int32_t &outValue) double endResult = ((double)result * factor) + bias; result = (int32_t)endResult; - + cachedValue = result; outValue = result; return true; } @@ -230,7 +236,7 @@ bool DBC_SIGNAL::processAsDouble(const CANFrame &frame, double &outValue) result = Utility::processIntegerSignal(frame.data, 0, 64, false, false); endResult = (*((double *)(&result)) * factor) + bias; } - + cachedValue = endResult; outValue = endResult; return true; } diff --git a/dbc/dbc_classes.h b/dbc/dbc_classes.h index d71544b..76fe85b 100644 --- a/dbc/dbc_classes.h +++ b/dbc/dbc_classes.h @@ -97,12 +97,14 @@ public: //TODO: this is sloppy. It shouldn't all be public! DBC_MESSAGE *parentMessage; QString unitName; QString comment; + QVariant cachedValue; QList attributes; QList valList; bool processAsText(const CANFrame &frame, QString &outString); bool processAsInt(const CANFrame &frame, int32_t &outValue); bool processAsDouble(const CANFrame &frame, double &outValue); + QString makePrettyOutput(double floatVal, int64_t intVal); DBC_ATTRIBUTE_VALUE *findAttrValByName(QString name); DBC_ATTRIBUTE_VALUE *findAttrValByIdx(int idx); }; From f16660ba5209938427cf097e5a8af2d693591a32 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Mon, 11 Mar 2019 21:42:19 -0400 Subject: [PATCH 19/33] Add ability to clone DBC signals. F2 will also do this from the keyboard (very handy!) --- connections/canconmanager.cpp | 1 + dbc/dbcsignaleditor.cpp | 45 ++++++++++++++++++++++++++++++++++- dbc/dbcsignaleditor.h | 1 + 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/connections/canconmanager.cpp b/connections/canconmanager.cpp index 20e0b3f..014248f 100644 --- a/connections/canconmanager.cpp +++ b/connections/canconmanager.cpp @@ -94,6 +94,7 @@ void CANConManager::refreshCanList() if (mConns.count() == 0) { + //TODO: Seems to crash under heavy load. Find out why. if(buslessFrames.size()) { tempFrames.clear(); tempFrames.append(buslessFrames); //make a copy and pass that copy diff --git a/dbc/dbcsignaleditor.cpp b/dbc/dbcsignaleditor.cpp index 5e47d0a..d86353d 100644 --- a/dbc/dbcsignaleditor.cpp +++ b/dbc/dbcsignaleditor.cpp @@ -232,6 +232,9 @@ bool DBCSignalEditor::eventFilter(QObject *obj, QEvent *event) case Qt::Key_F1: HelpWindow::getRef()->showHelp("signaleditor.html"); break; + case Qt::Key_F2: + cloneSignal(); + break; } return true; } else { @@ -324,7 +327,11 @@ void DBCSignalEditor::onCustomMenuSignals(QPoint point) menu->setAttribute(Qt::WA_DeleteOnClose); menu->addAction(tr("Add a new signal"), this, SLOT(addNewSignal())); - menu->addAction(tr("Delete currently selected signal"), this, SLOT(deleteCurrentSignal())); + if (ui->signalsList->currentRow() != -1) + { + menu->addAction(tr("Clone currently selected signal"), this, SLOT(cloneSignal())); + menu->addAction(tr("Delete currently selected signal"), this, SLOT(deleteCurrentSignal())); + } menu->popup(ui->signalsList->mapToGlobal(point)); } @@ -365,7 +372,43 @@ void DBCSignalEditor::addNewSignal() /* this will call clickSignalList */ ui->signalsList->addItem(newName); ui->signalsList->setCurrentRow(ui->signalsList->count()-1); +} +void DBCSignalEditor::cloneSignal() +{ + int num = qrand() % 100; + + int idx = ui->signalsList->currentRow(); + if (idx < 0) return; + + DBC_SIGNAL *oldSig = dbcMessage->sigHandler->findSignalByIdx(idx); + if (!oldSig) return; + + QString newName = oldSig->name + QString::number(num); + DBC_SIGNAL newSig; + newSig.name = newName; + newSig.bias = oldSig->bias; + newSig.factor = oldSig->factor; + newSig.intelByteOrder = oldSig->intelByteOrder; + newSig.max = oldSig->max; + newSig.min = oldSig->min; + newSig.receiver = oldSig->receiver; + newSig.signalSize = oldSig->signalSize; + newSig.startBit = oldSig->startBit; + newSig.valType = oldSig->valType; + newSig.valList.append(oldSig->valList); + newSig.isMultiplexed = oldSig->isMultiplexed; + newSig.isMultiplexor = oldSig->isMultiplexor; //maybe should force this false since you can't have two or more! + newSig.multiplexValue = oldSig->multiplexValue; + newSig.parentMessage = dbcMessage; + + dbcMessage->sigHandler->addSignal(newSig); + + /* add item at the end of the list */ + ui->signalsList->addItem(newName); + + //unlike adding a signal we don't want to select the new signal here. + //ui->signalsList->setCurrentRow(ui->signalsList->count()-1); } void DBCSignalEditor::deleteCurrentSignal() diff --git a/dbc/dbcsignaleditor.h b/dbc/dbcsignaleditor.h index 97b883f..e807f58 100644 --- a/dbc/dbcsignaleditor.h +++ b/dbc/dbcsignaleditor.h @@ -27,6 +27,7 @@ private slots: void onCustomMenuSignals(QPoint); void onCustomMenuValues(QPoint); void addNewSignal(); + void cloneSignal(); void deleteCurrentSignal(); void deleteCurrentValue(); From 8145c9d49bef44f2697e175a058db5e9f1b34b4f Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Tue, 12 Mar 2019 19:24:48 -0400 Subject: [PATCH 20/33] Increase version number --- config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.h b/config.h index 3db1f12..4ff12bb 100644 --- a/config.h +++ b/config.h @@ -1,7 +1,7 @@ #ifndef CONFIG #define CONFIG -#define VERSION 193 +#define VERSION 194 //try to keep this in sync. //SavvyCAN will complain if you connect a GVRET board with a revision From 1d218774dceb9454c8934259e661f16fb692c212 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Thu, 14 Mar 2019 19:28:05 -0400 Subject: [PATCH 21/33] Various changes to the file comparator window to make it a lot easier to undestand. --- re/filecomparatorwindow.cpp | 12 +++---- ui/filecomparatorwindow.ui | 64 ++++++++++++++++++++++++++++++++++--- 2 files changed, 66 insertions(+), 10 deletions(-) diff --git a/re/filecomparatorwindow.cpp b/re/filecomparatorwindow.cpp index a2e8d5b..ac20406 100644 --- a/re/filecomparatorwindow.cpp +++ b/re/filecomparatorwindow.cpp @@ -16,7 +16,7 @@ FileComparatorWindow::FileComparatorWindow(QWidget *parent) : connect(ui->btnClear, SIGNAL(clicked(bool)), this, SLOT(clearReference())); ui->lblFirstFile->setText(""); - ui->lblRefFrames->setText("0"); + ui->lblRefFrames->setText("Loaded frames: 0"); installEventFilter(this); } @@ -95,7 +95,7 @@ void FileComparatorWindow::loadReferenceFile() QString resultingFileName; if (FrameFileIO::loadFrameFile(resultingFileName, &referenceFrames)) { - ui->lblRefFrames->setText(QString::number(referenceFrames.length())); + ui->lblRefFrames->setText("Loaded frames: " + QString::number(referenceFrames.length())); if (interestedFrames.count() > 0 && referenceFrames.count() > 0) calculateDetails(); } } @@ -123,10 +123,10 @@ void FileComparatorWindow::calculateDetails() if (!uniqueInterested) { referenceOnlyBase = new QTreeWidgetItem(); - referenceOnlyBase->setText(0, "IDs found only in reference frames"); + referenceOnlyBase->setText(0, "IDs found only in Side 2 - Reference frames"); } sharedBase = new QTreeWidgetItem(); - sharedBase->setText(0,"IDs found in both places"); + sharedBase->setText(0,"IDs found on both sides"); //first we have to fill out the data structures to get ready to do the report for (int x = 0; x < interestedFrames.count(); x++) @@ -240,7 +240,7 @@ void FileComparatorWindow::calculateDetails() if (!uniqueInterested) { bitmapBaseReference = new QTreeWidgetItem(); - bitmapBaseReference->setText(0, "Bits set only in reference frames"); + bitmapBaseReference->setText(0, "Bits set only in Side 2 - Reference frames"); } sharedItem->addChild(bitmapBaseInterested); if (!uniqueInterested) sharedItem->addChild(bitmapBaseReference); @@ -277,7 +277,7 @@ void FileComparatorWindow::calculateDetails() if (!uniqueInterested) { valuesReference = new QTreeWidgetItem(); - valuesReference->setText(0, "Values found only in reference frames"); + valuesReference->setText(0, "Values found only in Side 2 - Reference frames"); } valuesBase->addChild(valuesInterested); if (!uniqueInterested) valuesBase->addChild(valuesReference); diff --git a/ui/filecomparatorwindow.ui b/ui/filecomparatorwindow.ui index 0711cca..94e6685 100644 --- a/ui/filecomparatorwindow.ui +++ b/ui/filecomparatorwindow.ui @@ -15,13 +15,31 @@ - + + + + + + 16 + + + + SIDE 1 + + + Qt::AlignCenter + + + - File of interest: + Single file to compare to side 2: + + + Qt::AlignCenter @@ -41,12 +59,40 @@ + + + + Qt::Vertical + + + + + + + + 16 + + + + Side 2 + + + Qt::AlignCenter + + + - <html><head/><body><p>Loaded reference frames:</p></body></html> + One or more files to compare with the single file on side1: + + + Qt::AlignCenter + + + true @@ -79,10 +125,20 @@
+ + + + Qt::Horizontal + + + + + true + - Show only unique data for interested file + Show only data unique to Side 1 From c157da0a90d4f9b191002578f978cb7fd7520488 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Thu, 14 Mar 2019 19:32:14 -0400 Subject: [PATCH 22/33] Add back in the ability to suspend/resume all buses from the main screen. Whoops, it got deleted by accident! --- connections/connectionwindow.cpp | 10 ++++++++++ connections/connectionwindow.h | 2 ++ 2 files changed, 12 insertions(+) diff --git a/connections/connectionwindow.cpp b/connections/connectionwindow.cpp index dff1476..5155e5f 100644 --- a/connections/connectionwindow.cpp +++ b/connections/connectionwindow.cpp @@ -216,6 +216,16 @@ void ConnectionWindow::connectionStatus(CANConStatus pStatus) connModel->refresh(); } +void ConnectionWindow::setSuspendAll(bool pSuspend) +{ + QList& conns = CANConManager::getInstance()->getConnections(); + + foreach(CANConnection* conn_p, conns) + conn_p->suspend(pSuspend); + + connModel->refresh(); +} + void ConnectionWindow::saveBusSettings() { int selIdx = ui->tableConnections->currentIndex().row(); diff --git a/connections/connectionwindow.h b/connections/connectionwindow.h index bf6bd77..1af482f 100644 --- a/connections/connectionwindow.h +++ b/connections/connectionwindow.h @@ -37,6 +37,8 @@ signals: public slots: void getDebugText(QString debugText); + void setSuspendAll(bool pSuspend); + private slots: void currentRowChanged(const QModelIndex ¤t, const QModelIndex &previous); From 2e5de7a37d8added83aa0ca9c13cbe00c7f08afe Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Sun, 17 Mar 2019 18:29:44 -0400 Subject: [PATCH 23/33] Reformat timestamps to look a bit nicer --- canframemodel.cpp | 15 ++++++++++++++- frameviewdelegate.cpp | 6 ++++++ frameviewdelegate.h | 11 +++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 frameviewdelegate.cpp create mode 100644 frameviewdelegate.h diff --git a/canframemodel.cpp b/canframemodel.cpp index e82238f..4221e4f 100644 --- a/canframemodel.cpp +++ b/canframemodel.cpp @@ -134,25 +134,33 @@ void CANFrameModel::setTimeFormat(QString format) endResetModel(); } +/* + * Scan all frames for the smallest timestamp and offset all timestamps so that smallest one is at 0 +*/ void CANFrameModel::normalizeTiming() { mutex.lock(); if (frames.count() == 0) return; timeOffset = frames[0].timestamp; + + //find the absolute lowest timestamp in the whole time. Needed because maybe timestamp was reset in the middle. for (int j = 0; j < frames.count(); j++) { if (frames[j].timestamp < timeOffset) timeOffset = frames[j].timestamp; } + for (int i = 0; i < frames.count(); i++) { frames[i].timestamp -= timeOffset; } + this->beginResetModel(); for (int i = 0; i < filteredFrames.count(); i++) { filteredFrames[i].timestamp -= timeOffset; } this->endResetModel(); + mutex.unlock(); } @@ -228,6 +236,7 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const QString tempString; CANFrame thisFrame; static bool rowFlip = false; + QVariant ts; if (!index.isValid()) return QVariant(); @@ -274,7 +283,11 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const switch (Column(index.column())) { case Column::TimeStamp: - return Utility::formatTimestamp(thisFrame.timestamp); + //Reformatting the output a bit with custom code + ts = Utility::formatTimestamp(thisFrame.timestamp); + if (ts.type() == QVariant::Double) return QString::number(ts.toDouble(), 'f', 5); //never scientific notation, 5 decimal places + if (ts.type() == QVariant::LongLong) return QString::number(ts.toLongLong()); //never scientific notion, all digits shown + if (ts.type() == QVariant::DateTime) return ts.toDateTime().toString(timeFormat); //custom set format for dates and times case Column::FrameId: return Utility::formatCANID(thisFrame.ID, thisFrame.extended); case Column::Extended: diff --git a/frameviewdelegate.cpp b/frameviewdelegate.cpp new file mode 100644 index 0000000..e6c87b2 --- /dev/null +++ b/frameviewdelegate.cpp @@ -0,0 +1,6 @@ +#include "frameviewdelegate.h" + +FrameViewDelegate::FrameViewDelegate() +{ + +} diff --git a/frameviewdelegate.h b/frameviewdelegate.h new file mode 100644 index 0000000..0075264 --- /dev/null +++ b/frameviewdelegate.h @@ -0,0 +1,11 @@ +#ifndef FRAMEVIEWDELEGATE_H +#define FRAMEVIEWDELEGATE_H + + +class FrameViewDelegate +{ +public: + FrameViewDelegate(); +}; + +#endif // FRAMEVIEWDELEGATE_H \ No newline at end of file From 6a9bd48442e9be1d828e54078fa117fae0cfe9f3 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Sun, 17 Mar 2019 18:30:10 -0400 Subject: [PATCH 24/33] Change formatting of CANAnalyzer ASC saving to hopefully better match the "Real" program's output --- framefileio.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/framefileio.cpp b/framefileio.cpp index 0e35579..f287c2f 100644 --- a/framefileio.cpp +++ b/framefileio.cpp @@ -708,6 +708,11 @@ bool FrameFileIO::saveCanalyzerASC(QString filename, const QVector* fr { QFile *outFile = new QFile(filename); int lineCounter = 0; + uint64_t offsetTime = frames->at(0).timestamp; + for (int c = 0; c < frames->count(); c++) + { + if (frames->at(c).timestamp < offsetTime) offsetTime = frames->at(c).timestamp; + } if (!outFile->open(QIODevice::WriteOnly | QIODevice::Text)) { @@ -717,7 +722,12 @@ bool FrameFileIO::saveCanalyzerASC(QString filename, const QVector* fr QDateTime now; now = QDateTime::currentDateTime(); - outFile->write("date " + now.toString("MMM-dd HH:mm:ss.zzz").toUtf8()); + if (offsetTime > 10000000000) //chances are the input file had times as system time so load it + { + now.setMSecsSinceEpoch(offsetTime / 1000); //offsetTime was in microseconds + } + outFile->write("date " + now.toString("ddd MMM dd h:mm:ss.zzz a yyyy").toUtf8()); + outFile->write("\nbase hex timestamps absolute\n"); outFile->write("no internal event logging\n"); outFile->write("// version 11.0.0\n"); @@ -731,7 +741,7 @@ bool FrameFileIO::saveCanalyzerASC(QString filename, const QVector* fr lineCounter = 0; } - outFile->write(QString::number(frames->at(c).timestamp / 1000000.0, 'f', 6).toUtf8()); + outFile->write(QString::number((frames->at(c).timestamp - offsetTime) / 1000000.0, 'f', 5).toUtf8()); outFile->putChar(' '); outFile->write(QString::number(frames->at(c).bus).toUtf8()); outFile->write(" "); From 23426bc43070ebe21aabfc7290de63ff504c56bf Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Sun, 17 Mar 2019 18:31:32 -0400 Subject: [PATCH 25/33] Update version number --- config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.h b/config.h index 4ff12bb..96affcd 100644 --- a/config.h +++ b/config.h @@ -1,7 +1,7 @@ #ifndef CONFIG #define CONFIG -#define VERSION 194 +#define VERSION 195 //try to keep this in sync. //SavvyCAN will complain if you connect a GVRET board with a revision From 56691b368096781791bdb870d18cff8d55d0ccdb Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Mon, 18 Mar 2019 20:38:31 -0400 Subject: [PATCH 26/33] Fixes to file loading --- blfhandler.cpp | 3 ++- framefileio.cpp | 14 +++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/blfhandler.cpp b/blfhandler.cpp index 439c2ef..49e9694 100644 --- a/blfhandler.cpp +++ b/blfhandler.cpp @@ -94,7 +94,8 @@ bool BLFHandler::loadBLF(QString filename, QVector* frames) frame.remote = false; for (int i = 0; i < 8; i++) frame.data[i] = canObject.data[i]; } - frame.timestamp = obj.header.uncompSize / 1000000.0; //uncompsize field also used for timestamp oddly enough + //Should we divide by a thousand or a million? Unsure here. It appears some logs are stamped in microseconds and some in milliseconds? + frame.timestamp = obj.header.uncompSize / 1000.0; //uncompsize field also used for timestamp oddly enough frames->append(frame); } else diff --git a/framefileio.cpp b/framefileio.cpp index f287c2f..ed6deb2 100644 --- a/framefileio.cpp +++ b/framefileio.cpp @@ -649,6 +649,7 @@ bool FrameFileIO::loadCanalyzerASC(QString filename, QVector* frames) bool foundErrors = false; bool inHeader = true; thisFrame.remote = false; + QList tokens; if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text)) { @@ -664,16 +665,19 @@ bool FrameFileIO::loadCanalyzerASC(QString filename, QVector* frames) lineCounter = 0; } line = inFile->readLine(); - if (line.startsWith("//")) + if (inHeader) { - inHeader = false; - continue; + if (line.startsWith("//") || lineCounter > 4) + { + inHeader = false; + continue; + } } if (inHeader) continue; if (line.length() > 2) { - QList tokens = line.simplified().split(' '); - if (tokens.length() > 4) + tokens = line.simplified().split(' '); + if (tokens.length() > 5) { thisFrame.timestamp = (uint64_t)(tokens[0].toDouble() * (double)1000000.0); thisFrame.ID = tokens[2].toUInt(NULL, 16); From 734ed8cd5bbf4df827c6a9e2e465ef95eaddeaa2 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Mon, 18 Mar 2019 20:40:05 -0400 Subject: [PATCH 27/33] Some formatting changes in comparator window, plus status update changes. --- re/filecomparatorwindow.cpp | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/re/filecomparatorwindow.cpp b/re/filecomparatorwindow.cpp index ac20406..3102142 100644 --- a/re/filecomparatorwindow.cpp +++ b/re/filecomparatorwindow.cpp @@ -81,18 +81,25 @@ void FileComparatorWindow::loadInterestedFile() { interestedFrames.clear(); QString resultingFileName; + + qApp->processEvents(); + if (FrameFileIO::loadFrameFile(resultingFileName, &interestedFrames)) { ui->lblFirstFile->setText(resultingFileName); interestedFilename = resultingFileName; if (interestedFrames.count() > 0 && referenceFrames.count() > 0) calculateDetails(); } + } void FileComparatorWindow::loadReferenceFile() { //secondFileFrames.clear(); QString resultingFileName; + + qApp->processEvents(); + if (FrameFileIO::loadFrameFile(resultingFileName, &referenceFrames)) { ui->lblRefFrames->setText("Loaded frames: " + QString::number(referenceFrames.length())); @@ -104,6 +111,7 @@ void FileComparatorWindow::clearReference() { referenceFrames.clear(); ui->treeDetails->clear(); + ui->lblRefFrames->setText("Loaded frames: " + QString::number(referenceFrames.length())); } void FileComparatorWindow::calculateDetails() @@ -116,6 +124,16 @@ void FileComparatorWindow::calculateDetails() bool uniqueInterested = ui->ckUniqueToInterested->isChecked(); + QProgressDialog progress(this); + progress.setWindowModality(Qt::WindowModal); + progress.setLabelText("Calculating differences"); + progress.setCancelButton(0); + progress.setRange(0,0); + progress.setMinimumDuration(0); + progress.show(); + + qApp->processEvents(); + ui->treeDetails->clear(); interestedOnlyBase = new QTreeWidgetItem(); @@ -171,6 +189,8 @@ void FileComparatorWindow::calculateDetails() } } + qApp->processEvents(); + for (int x = 0; x < referenceFrames.count(); x++) { CANFrame frame = referenceFrames.at(x); @@ -211,17 +231,27 @@ void FileComparatorWindow::calculateDetails() } } + qApp->processEvents(); + //now we iterate through the IDs within both files and see which are unique to one file and which //are shared bool interestedHadUnique = false; QMap::iterator i; + int framesCounter = 0; for (i = interestedIDs.begin(); i != interestedIDs.end(); ++i) { + framesCounter++; + if (framesCounter > 10000) + { + framesCounter = 0; + qApp->processEvents(); + } + int keyone = i.key(); if (!referenceIDs.contains(keyone)) { valuesBase = new QTreeWidgetItem(); - valuesBase->setText(0, QString::number(keyone, 16)); + valuesBase->setText(0, Utility::formatHexNum(keyone)); interestedOnlyBase->addChild(valuesBase); } else //ID was in both files @@ -300,6 +330,8 @@ void FileComparatorWindow::calculateDetails() } } + qApp->processEvents(); + if (!uniqueInterested) { QMap::iterator itwo; @@ -327,6 +359,8 @@ void FileComparatorWindow::calculateDetails() { ui->treeDetails->expandAll(); } + + progress.cancel(); } void FileComparatorWindow::saveDetails() From 39d8786d4bd591be0aa1461ddd9acacc4d59dd88 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Mon, 18 Mar 2019 21:49:36 -0400 Subject: [PATCH 28/33] Fixes to make native GVRET file loading more robust. --- framefileio.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/framefileio.cpp b/framefileio.cpp index ed6deb2..edd32f5 100644 --- a/framefileio.cpp +++ b/framefileio.cpp @@ -786,6 +786,8 @@ bool FrameFileIO::loadCanalyzerBLF(QString filename, QVector *frames) } //The "native" file format for this program +//Time Stamp,ID,Extended,Dir,Bus,LEN,D1,D2,D3,D4,D5,D6,D7,D8 +//39747828,000005EB,false,Rx,0,8,E8,45,85,4B,4A,28,36,69, bool FrameFileIO::loadNativeCSVFile(QString filename, QVector* frames) { QFile *inFile = new QFile(filename); @@ -842,7 +844,9 @@ bool FrameFileIO::loadNativeCSVFile(QString filename, QVector* frames) thisFrame.isReceived = true; thisFrame.bus = tokens[3].toInt(); thisFrame.len = tokens[4].toUInt(); + if (thisFrame.len > 8) thisFrame.len = 8; for (int c = 0; c < 8; c++) thisFrame.data[c] = 0; + if (thisFrame.len + 5 > (unsigned int) tokens.length()) thisFrame.len = tokens.length() - 5; for (unsigned int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = tokens[5 + d].toInt(NULL, 16); } @@ -852,6 +856,7 @@ bool FrameFileIO::loadNativeCSVFile(QString filename, QVector* frames) else thisFrame.isReceived = false; thisFrame.bus = tokens[4].toInt(); thisFrame.len = tokens[5].toUInt(); + if (thisFrame.len > 8) thisFrame.len = 8; if (thisFrame.len + 6 > (unsigned int) tokens.length()) thisFrame.len = tokens.length() - 6; for (int c = 0; c < 8; c++) thisFrame.data[c] = 0; for (unsigned int d = 0; d < thisFrame.len; d++) From 11b10b72200885f9dfea3edfe589a66c467713c5 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Tue, 19 Mar 2019 19:56:48 -0400 Subject: [PATCH 29/33] Add CANOpen Magic file format for loading --- framefileio.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ framefileio.h | 1 + 2 files changed, 67 insertions(+) diff --git a/framefileio.cpp b/framefileio.cpp index edd32f5..1755c48 100644 --- a/framefileio.cpp +++ b/framefileio.cpp @@ -156,6 +156,7 @@ bool FrameFileIO::loadFrameFile(QString &fileName, QVector* frameCache filters.append(QString(tr("CANalyzer Binary Log Files (*.blf *.BLF)"))); filters.append(QString(tr("CANHacker Trace Files (*.trc *.TRC)"))); filters.append(QString(tr("Cabana Log (*.csv *.CSV)"))); + filters.append(QString(tr("CANOpen Magic (*.csv *.CSV)"))); dialog.setFileMode(QFileDialog::ExistingFile); dialog.setNameFilters(filters); @@ -192,6 +193,7 @@ bool FrameFileIO::loadFrameFile(QString &fileName, QVector* frameCache if (dialog.selectedNameFilter() == filters[14]) result = loadCanalyzerBLF(filename, frameCache); if (dialog.selectedNameFilter() == filters[15]) result = loadCANHackerFile(filename, frameCache); if (dialog.selectedNameFilter() == filters[16]) result = loadCabanaFile(filename, frameCache); + if (dialog.selectedNameFilter() == filters[17]) result = loadCANOpenFile(filename, frameCache); progress.cancel(); @@ -457,6 +459,70 @@ bool FrameFileIO::loadCANHackerFile(QString filename, QVector* frames) return !foundErrors; } + +//"Message Number","Time (ms)","Time","Excel Time","Count","ID","Flags","Message Type","Node","Details","Process Data","Data (Hex)","Data (Text)","Data (Decimal)","Length","Raw Message" +//"0","0.000","8:09:42:48.7953090'",43447.7100146116,"","0x2E1","","Default: PDO","","Default: TPDO 2 of Node 0x61 (97)","","10 21 04 00 00 00 00 00 ",". ! . . . . . . ","U:0 S:0","8","10 21 04 00 00 00 00 00" +bool FrameFileIO::loadCANOpenFile(QString filename, QVector* frames) +{ + QFile *inFile = new QFile(filename); + CANFrame thisFrame; + QByteArray line; + int lineCounter = 0; + bool foundErrors = false; + + if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text)) + { + delete inFile; + qDebug() << "Could not open the file!"; + return false; + } + + line = inFile->readLine(); //read out the header first and discard it. + line = inFile->readLine(); + line = inFile->readLine(); + line = inFile->readLine(); + line = inFile->readLine(); + + while (!inFile->atEnd()) { + lineCounter++; + if (lineCounter > 100) + { + qApp->processEvents(); + lineCounter = 0; + } + + line = inFile->readLine().replace('\"', ' ').simplified(); + if (line.length() > 2) + { + QList tokens = line.split(','); + if (tokens.length() > 11) + { + thisFrame.timestamp = (int64_t)(tokens[1].simplified().toDouble() * 1000.0); + thisFrame.ID = Utility::ParseStringToNum(tokens[5].simplified()); + thisFrame.extended = (thisFrame.ID > 0x7FF); + thisFrame.isReceived = true; + thisFrame.remote = false; + thisFrame.bus = 0; + QList dataTok = tokens[11].simplified().split(' '); + thisFrame.len = dataTok.length(); + for (unsigned int d = 0; d < thisFrame.len; d++) + { + if (dataTok[d] != "") + { + thisFrame.data[d] = dataTok[d].simplified().toInt(NULL, 16); + } + else thisFrame.data[d] = 0; + } + frames->append(thisFrame); + } + else foundErrors = true; + } + } + inFile->close(); + delete inFile; + return !foundErrors; +} + bool FrameFileIO::saveCRTDFile(QString filename, const QVector* frames) { QFile *outFile = new QFile(filename); diff --git a/framefileio.h b/framefileio.h index 2eea45b..820426c 100644 --- a/framefileio.h +++ b/framefileio.h @@ -46,6 +46,7 @@ public: static bool loadCanalyzerBLF(QString, QVector*); static bool loadCANHackerFile(QString filename, QVector* frames); static bool loadCabanaFile(QString filename, QVector* frames); + static bool loadCANOpenFile(QString filename, QVector* frames); static bool saveCRTDFile(QString, const QVector*); static bool saveNativeCSVFile(QString, const QVector*); static bool saveGenericCSVFile(QString, const QVector*); From ba94db77bf2dba10692320a632016e26d4a6bc0e Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Tue, 19 Mar 2019 20:43:36 -0400 Subject: [PATCH 30/33] Update version number, small fix to graphing window --- config.h | 2 +- frameviewdelegate.cpp | 6 ------ frameviewdelegate.h | 11 ----------- re/graphingwindow.cpp | 6 +++--- 4 files changed, 4 insertions(+), 21 deletions(-) delete mode 100644 frameviewdelegate.cpp delete mode 100644 frameviewdelegate.h diff --git a/config.h b/config.h index 96affcd..b072063 100644 --- a/config.h +++ b/config.h @@ -1,7 +1,7 @@ #ifndef CONFIG #define CONFIG -#define VERSION 195 +#define VERSION 196 //try to keep this in sync. //SavvyCAN will complain if you connect a GVRET board with a revision diff --git a/frameviewdelegate.cpp b/frameviewdelegate.cpp deleted file mode 100644 index e6c87b2..0000000 --- a/frameviewdelegate.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "frameviewdelegate.h" - -FrameViewDelegate::FrameViewDelegate() -{ - -} diff --git a/frameviewdelegate.h b/frameviewdelegate.h deleted file mode 100644 index 0075264..0000000 --- a/frameviewdelegate.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef FRAMEVIEWDELEGATE_H -#define FRAMEVIEWDELEGATE_H - - -class FrameViewDelegate -{ -public: - FrameViewDelegate(); -}; - -#endif // FRAMEVIEWDELEGATE_H \ No newline at end of file diff --git a/re/graphingwindow.cpp b/re/graphingwindow.cpp index 0cc5121..b311623 100644 --- a/re/graphingwindow.cpp +++ b/re/graphingwindow.cpp @@ -458,7 +458,7 @@ bool GraphingWindow::eventFilter(QObject *obj, QEvent *event) void GraphingWindow::resetView() { double yminval=10000000.0, ymaxval = -1000000.0; - double xminval=10000000000.0, xmaxval = -10000000000.0; + double xminval=100000000000, xmaxval = -10000000000.0; for (int i = 0; i < graphParams.count(); i++) { for (int j = 0; j < graphParams[i].x.count(); j++) @@ -1076,8 +1076,8 @@ void GraphingWindow::appendToGraph(GraphParams ¶ms, CANFrame &frame, QVector void GraphingWindow::createGraph(GraphParams ¶ms, bool createGraphParam) { int64_t tempVal; //64 bit temp value. - float yminval=10000000.0, ymaxval = -1000000.0; - float xminval=10000000000.0, xmaxval = -10000000000.0; + double yminval=10000000.0, ymaxval = -1000000.0; + double xminval=10000000000.0, xmaxval = -10000000000.0; GraphParams *refParam = ¶ms; int sBit, bits; bool intelFormat, isSigned; From 15460f70e39cb37e3a5fb933e1ee2ec9e040033d Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Tue, 19 Mar 2019 21:02:35 -0400 Subject: [PATCH 31/33] Fix inappropriate default color that made DBC messages default to a bad color scheme for dark themes --- dbc/dbchandler.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dbc/dbchandler.cpp b/dbc/dbchandler.cpp index dbd33ac..b1353c2 100644 --- a/dbc/dbchandler.cpp +++ b/dbc/dbchandler.cpp @@ -809,7 +809,7 @@ void DBCFile::loadFile(QString fileName) if (parseAttribute(line.right(line.length() - 12), attr)) { - qDebug() << "Success"; + //qDebug() << "Success"; attr.attrType = SIG; dbc_attributes.append(attr); } @@ -831,7 +831,7 @@ void DBCFile::loadFile(QString fileName) if (parseAttribute(line.right(line.length() - 12), attr)) { - qDebug() << "Success"; + //qDebug() << "Success"; attr.attrType = NODE; dbc_attributes.append(attr); } @@ -855,7 +855,7 @@ void DBCFile::loadFile(QString fileName) if (!bgAttr) { attr.attrType = MESSAGE; - attr.defaultValue = QColor(Qt::white).name(); + attr.defaultValue = QApplication::palette().color(QPalette::Base).name(); attr.enumVals.clear(); attr.lower = 0; attr.upper = 0; @@ -1366,7 +1366,7 @@ int DBCHandler::createBlankFile() //add our custom attributes to the new file so that we know they're already there. attr.attrType = MESSAGE; - attr.defaultValue = QColor(Qt::white).name(); + attr.defaultValue = QApplication::palette().color(QPalette::Base).name(); attr.enumVals.clear(); attr.lower = 0; attr.upper = 0; From e013b91af3beb4883fd5885721d18ec25754203f Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Wed, 20 Mar 2019 19:55:54 -0400 Subject: [PATCH 32/33] Fixes to CANAlyzer ASC format when saving. Hopefully perfectly matches now --- framefileio.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/framefileio.cpp b/framefileio.cpp index 1755c48..fd6d01b 100644 --- a/framefileio.cpp +++ b/framefileio.cpp @@ -811,9 +811,15 @@ bool FrameFileIO::saveCanalyzerASC(QString filename, const QVector* fr lineCounter = 0; } - outFile->write(QString::number((frames->at(c).timestamp - offsetTime) / 1000000.0, 'f', 5).toUtf8()); + uint64_t timeStamp = (frames->at(c).timestamp - offsetTime) / 1000000ull; + int tsLen = QString::number(timeStamp).length(); + int precision = 6; + //vector seems to keep 10 bytes at the start of the line for the timestamp. It should never exceed this + //and there should never be a precision over 6 digits after the decimal + if (tsLen > 3) precision = 9 - tsLen; + outFile->write(QString::number((frames->at(c).timestamp - offsetTime) / 1000000.0, 'f', precision).rightJustified(10, ' ').toUtf8()); outFile->putChar(' '); - outFile->write(QString::number(frames->at(c).bus).toUtf8()); + outFile->write(QString::number(frames->at(c).bus + 1).toUtf8()); outFile->write(" "); if (frames->at(c).extended) outFile->write(QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8()); @@ -822,18 +828,18 @@ bool FrameFileIO::saveCanalyzerASC(QString filename, const QVector* fr outFile->write(QString::number(frames->at(c).ID, 16).toUpper().rightJustified(3, '0').toUtf8()); outFile->write(" "); } - outFile->write(" "); + outFile->write(" "); - if (frames->at(c).isReceived) outFile->write("Rx d "); - else outFile->write("Tx d "); + if (frames->at(c).isReceived) outFile->write("Rx D "); + else outFile->write("Tx D "); outFile->write(QString::number(frames->at(c).len).toUtf8()); - outFile->putChar(' '); + outFile->write(" "); for (unsigned int temp = 0; temp < frames->at(c).len; temp++) { outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8()); - outFile->putChar(' '); + outFile->write(" "); } outFile->write("\n"); From 44287793b4a6e5aabd8c09ddbb5c34a56a8ac606 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Sat, 30 Mar 2019 23:46:09 -0700 Subject: [PATCH 33/33] Revert change in timestamp formatting as the new code would sometimes malfunction on Windows. --- canframemodel.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/canframemodel.cpp b/canframemodel.cpp index 4221e4f..199a196 100644 --- a/canframemodel.cpp +++ b/canframemodel.cpp @@ -283,11 +283,7 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const switch (Column(index.column())) { case Column::TimeStamp: - //Reformatting the output a bit with custom code - ts = Utility::formatTimestamp(thisFrame.timestamp); - if (ts.type() == QVariant::Double) return QString::number(ts.toDouble(), 'f', 5); //never scientific notation, 5 decimal places - if (ts.type() == QVariant::LongLong) return QString::number(ts.toLongLong()); //never scientific notion, all digits shown - if (ts.type() == QVariant::DateTime) return ts.toDateTime().toString(timeFormat); //custom set format for dates and times + return Utility::formatTimestamp(thisFrame.timestamp); case Column::FrameId: return Utility::formatCANID(thisFrame.ID, thisFrame.extended); case Column::Extended: