From b8181e67fcb5f8dd751ee4d753d652b3483a8761 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Sat, 2 May 2015 11:04:24 -0400 Subject: [PATCH] Added two more forms into the program and hooked them up. There is no graphing yet but the form is there. The details pane that was in the graphing screen in GVRET-PC is now its own form and being fleshed out still. --- SavvyCAN.pro | 16 +++-- canframemodel.cpp | 8 +++ canframemodel.h | 1 + frameinfowindow.cpp | 146 ++++++++++++++++++++++++++++++++++++++++++++ frameinfowindow.h | 32 ++++++++++ frameinfowindow.ui | 68 +++++++++++++++++++++ graphingwindow.cpp | 14 +++++ graphingwindow.h | 22 +++++++ graphingwindow.ui | 51 ++++++++++++++++ mainwindow.cpp | 17 ++++++ mainwindow.h | 6 ++ mainwindow.ui | 40 ++++++++++++ 12 files changed, 417 insertions(+), 4 deletions(-) create mode 100644 frameinfowindow.cpp create mode 100644 frameinfowindow.h create mode 100644 frameinfowindow.ui create mode 100644 graphingwindow.cpp create mode 100644 graphingwindow.h create mode 100644 graphingwindow.ui diff --git a/SavvyCAN.pro b/SavvyCAN.pro index 22465d3..b9863f2 100644 --- a/SavvyCAN.pro +++ b/SavvyCAN.pro @@ -6,7 +6,7 @@ QT += core gui -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets serialport +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets serialport printsupport TARGET = SavvyCAN TEMPLATE = app @@ -15,11 +15,19 @@ TEMPLATE = app SOURCES += main.cpp\ mainwindow.cpp \ canframemodel.cpp \ - utility.cpp + utility.cpp \ + qcustomplot.cpp \ + graphingwindow.cpp \ + frameinfowindow.cpp HEADERS += mainwindow.h \ can_structs.h \ canframemodel.h \ - utility.h + utility.h \ + qcustomplot.h \ + graphingwindow.h \ + frameinfowindow.h -FORMS += mainwindow.ui +FORMS += mainwindow.ui \ + graphingwindow.ui \ + frameinfowindow.ui diff --git a/canframemodel.cpp b/canframemodel.cpp index 5d3086f..684f2ca 100644 --- a/canframemodel.cpp +++ b/canframemodel.cpp @@ -122,3 +122,11 @@ void CANFrameModel::clearFrames() frames.clear(); endRemoveRows(); } + +//Is this safe? Maybe not but if we don't change it then that's OK +//Is it the best C++ practice? Probably not. This breaks the MVC paradigm +//but, it's for a good cause. +QList* CANFrameModel::getListReference() +{ + return &frames; +} diff --git a/canframemodel.h b/canframemodel.h index 66c372b..e1f841d 100644 --- a/canframemodel.h +++ b/canframemodel.h @@ -22,6 +22,7 @@ public: void sendRefresh(); void sendRefresh(int); void clearFrames(); + QList *getListReference(); private: diff --git a/frameinfowindow.cpp b/frameinfowindow.cpp new file mode 100644 index 0000000..4d56411 --- /dev/null +++ b/frameinfowindow.cpp @@ -0,0 +1,146 @@ +#include "frameinfowindow.h" +#include "ui_frameinfowindow.h" + +FrameInfoWindow::FrameInfoWindow(QList *frames, QWidget *parent) : + QDialog(parent), + ui(new Ui::FrameInfoWindow) +{ + ui->setupUi(this); + modelFrames = frames; + refreshIDList(); +} + +FrameInfoWindow::~FrameInfoWindow() +{ + delete ui; +} + +void FrameInfoWindow::updateDetailsWindow(int frameIdx) +{ + int idx, numFrames, targettedID; + int minLen, maxLen, thisLen; + int minData[8]; + int maxData[8]; + int dataHistogram[256][8]; + //TreeNode baseNode, dataBase, histBase, numBase; +/* + if (frameIdx > -1) + { + parseFrameCache(); + targettedID = Utility.ParseStringToNum(listFrameIDs.Items[listFrameIDs.SelectedIndex].ToString()); + idx = getIdxForID(targettedID); + numFrames = frames[idx].Count; + + treeDetails.Nodes.Clear(); + baseNode = treeDetails.Nodes.Add("ID: " + listFrameIDs.Items[listFrameIDs.SelectedIndex].ToString()); + if (frames[idx].ElementAt(0).extended) //if these frames seem to be extended then try for J1939 decoding + { + J1939ID jid = new J1939ID(); + jid.src = targettedID & 0xFF; + jid.priority = targettedID >> 26; + jid.pgn = (targettedID >> 8) & 0x3FFFF; //18 bits + jid.pf = (targettedID >> 16) & 0xFF; + jid.ps = (targettedID >> 8) & 0xFF; + + if (jid.pf > 0xEF) + { + jid.isBroadcast = true; + jid.dest = 0xFFFF; + baseNode.Nodes.Add("Broadcast frame"); + } + else + { + jid.dest = jid.ps; + baseNode.Nodes.Add("Destination ID: 0x" + jid.dest.ToString("X2")); + } + baseNode.Nodes.Add("SRC: 0x" + jid.src.ToString("X2")); + baseNode.Nodes.Add("PGN: " + jid.pgn.ToString()); + baseNode.Nodes.Add("PF: 0x" + jid.pf.ToString("X2")); + baseNode.Nodes.Add("PS: 0x" + jid.ps.ToString("X2")); + } + treeDetails.Nodes.Add("# Of Frames: " + numFrames.ToString()); + minLen = 8; + maxLen = 0; + for (int i = 0; i < 8; i++) + { + minData[i] = 256; + maxData[i] = -1; + for (int k = 0; k < 256; k++) dataHistogram[k, i] = 0; + } + for (int j = 0; j < numFrames; j++) + { + thisLen = frames[idx].ElementAt(j).len; + if (thisLen > maxLen) maxLen = thisLen; + if (thisLen < minLen) minLen = thisLen; + for (int c = 0; c < thisLen; c++) + { + byte dat = frames[idx].ElementAt(j).data[c]; + if (minData[c] > dat) minData[c] = dat; + if (maxData[c] < dat) maxData[c] = dat; + dataHistogram[dat, c]++; //add one to count for this + } + } + if (minLen < maxLen) + baseNode = treeDetails.Nodes.Add("Data Length: " + minLen.ToString() + " to " + maxLen.ToString()); + else + baseNode = treeDetails.Nodes.Add("Data Length: " + minLen.ToString()); + + for (int d = 0; d < numGraphs; d++) + { + Graphs[d].valueCache = null; + Graphs[d].ID = 0; + } + + for (int c = 0; c < maxLen; c++) + { + Graphs[6 + c].bias = 0; + Graphs[6 + c].scale = 1; + Graphs[6 + c].mask = 0xFF; + Graphs[6 + c].B1 = c; + Graphs[6 + c].B2 = c; + Graphs[6 + c].ID = targettedID; + Graphs[6 + c].color = theseColors[c]; + Graphs[6 + c].signed = false; + if (numFrames > 100) + { + Graphs[6 + c].stride = (int)((((float)numFrames) / 100.0f) + 0.5f); + } + else Graphs[6 + c].stride = 1; + + dataBase = baseNode.Nodes.Add("Data Byte " + c.ToString()); + dataBase.Nodes.Add("Range: " + minData[c] + " to " + maxData[c]); + histBase = dataBase.Nodes.Add("Histogram"); + for (int d = 0; d < 256; d++) + { + if (dataHistogram[d, c] > 0) + { + numBase = histBase.Nodes.Add(d.ToString() + "/0x" + d.ToString("X2") + ": " + dataHistogram[d, c]); + } + } + } + + parseFrameCache(); + for (int c = 0; c < maxLen; c++) setupGraph(6 + c); + setupGraphs(); + } + else + { + } +*/ +} + +void FrameInfoWindow::refreshIDList() +{ + int id; + for (int i = 0; i < modelFrames->count(); i++) + { + id = modelFrames->at(i).ID; + if (!foundID.contains(id)) + { + foundID.append(id); + ui->listFrameID->addItem(QString::number(id, 16).toUpper().rightJustified(4,'0')); + } + } + //default is to sort in ascending order + ui->listFrameID->sortItems(); +} diff --git a/frameinfowindow.h b/frameinfowindow.h new file mode 100644 index 0000000..bc94557 --- /dev/null +++ b/frameinfowindow.h @@ -0,0 +1,32 @@ +#ifndef FRAMEINFOWINDOW_H +#define FRAMEINFOWINDOW_H + +#include +#include "can_structs.h" + +namespace Ui { +class FrameInfoWindow; +} + +class FrameInfoWindow : public QDialog +{ + Q_OBJECT + +public: + explicit FrameInfoWindow(QList *frames, QWidget *parent = 0); + ~FrameInfoWindow(); + +private slots: + void updateDetailsWindow(int frameIdx); + +private: + Ui::FrameInfoWindow *ui; + + QList foundID; + QList frameCache; + QList *modelFrames; + + void refreshIDList(); +}; + +#endif // FRAMEINFOWINDOW_H diff --git a/frameinfowindow.ui b/frameinfowindow.ui new file mode 100644 index 0000000..9d8f066 --- /dev/null +++ b/frameinfowindow.ui @@ -0,0 +1,68 @@ + + + FrameInfoWindow + + + + 0 + 0 + 794 + 494 + + + + Detailed Frame Information + + + + + + + + Frame IDs: + + + + + + + + 0 + 0 + + + + + 120 + 0 + + + + + + + + + + + + Details: + + + + + + + + 1 + + + + + + + + + + + diff --git a/graphingwindow.cpp b/graphingwindow.cpp new file mode 100644 index 0000000..38ef927 --- /dev/null +++ b/graphingwindow.cpp @@ -0,0 +1,14 @@ +#include "graphingwindow.h" +#include "ui_graphingwindow.h" + +GraphingWindow::GraphingWindow(QWidget *parent) : + QDialog(parent), + ui(new Ui::GraphingWindow) +{ + ui->setupUi(this); +} + +GraphingWindow::~GraphingWindow() +{ + delete ui; +} diff --git a/graphingwindow.h b/graphingwindow.h new file mode 100644 index 0000000..8e021a9 --- /dev/null +++ b/graphingwindow.h @@ -0,0 +1,22 @@ +#ifndef GRAPHINGWINDOW_H +#define GRAPHINGWINDOW_H + +#include + +namespace Ui { +class GraphingWindow; +} + +class GraphingWindow : public QDialog +{ + Q_OBJECT + +public: + explicit GraphingWindow(QWidget *parent = 0); + ~GraphingWindow(); + +private: + Ui::GraphingWindow *ui; +}; + +#endif // GRAPHINGWINDOW_H diff --git a/graphingwindow.ui b/graphingwindow.ui new file mode 100644 index 0000000..1ef8f42 --- /dev/null +++ b/graphingwindow.ui @@ -0,0 +1,51 @@ + + + GraphingWindow + + + + 0 + 0 + 800 + 600 + + + + + 0 + 0 + + + + + 800 + 600 + + + + Dialog + + + true + + + + + + + + + + + + + + QCustomPlot + QWidget +
qcustomplot.h
+ 1 +
+
+ + +
diff --git a/mainwindow.cpp b/mainwindow.cpp index d59caa6..0edf988 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -36,11 +36,15 @@ MainWindow::MainWindow(QWidget *parent) : rx_state = IDLE; rx_step = 0; + + graphingWindow = NULL; + frameInfoWindow = NULL; } MainWindow::~MainWindow() { delete ui; + if (graphingWindow) delete graphingWindow; } void MainWindow::addFrameToDisplay(CANFrame &frame, bool autoRefresh = false) @@ -239,6 +243,19 @@ void MainWindow::connButtonPress() } } +void MainWindow::showGraphingWindow() +{ + if (!graphingWindow) graphingWindow = new GraphingWindow(); + graphingWindow->show(); +} + +void MainWindow::showFrameDataAnalysis() +{ + //only create an instance of the object if we dont have one. Otherwise just display the existing one. + if (!frameInfoWindow) frameInfoWindow = new FrameInfoWindow(model->getListReference()); + frameInfoWindow->show(); +} + void MainWindow::readSerialData() { QByteArray data = port->readAll(); diff --git a/mainwindow.h b/mainwindow.h index 092ee22..920ca51 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -5,6 +5,8 @@ #include #include "canframemodel.h" #include "can_structs.h" +#include "graphingwindow.h" +#include "frameinfowindow.h" namespace Ui { class MainWindow; @@ -34,6 +36,8 @@ private slots: void handleLoadFile(); void connButtonPress(); void readSerialData(); + void showGraphingWindow(); + void showFrameDataAnalysis(); private: Ui::MainWindow *ui; @@ -43,6 +47,8 @@ private: STATE rx_state; int rx_step; CANFrame buildFrame; + GraphingWindow *graphingWindow; + FrameInfoWindow *frameInfoWindow; void loadCRTDFile(QString); void loadNativeCSVFile(QString); void loadGenericCSVFile(QString); diff --git a/mainwindow.ui b/mainwindow.ui index c065db8..96a3d4e 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -104,6 +104,7 @@ + @@ -177,6 +178,11 @@ Save Log File + + + Frame Data Analysis + + @@ -213,9 +219,43 @@ + + actionGraph_Dta + triggered() + MainWindow + showGraphingWindow() + + + -1 + -1 + + + 463 + 249 + + + + + actionFrame_Data_Analysis + triggered() + MainWindow + showFrameDataAnalysis() + + + -1 + -1 + + + 463 + 249 + + + handleLoadFile() connButtonPress() + showGraphingWindow() + showFrameDataAnalysis()