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.
This commit is contained in:
+12
-4
@@ -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
|
||||
|
||||
@@ -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<CANFrame>* CANFrameModel::getListReference()
|
||||
{
|
||||
return &frames;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ public:
|
||||
void sendRefresh();
|
||||
void sendRefresh(int);
|
||||
void clearFrames();
|
||||
QList<CANFrame> *getListReference();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
#include "frameinfowindow.h"
|
||||
#include "ui_frameinfowindow.h"
|
||||
|
||||
FrameInfoWindow::FrameInfoWindow(QList<CANFrame> *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();
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef FRAMEINFOWINDOW_H
|
||||
#define FRAMEINFOWINDOW_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "can_structs.h"
|
||||
|
||||
namespace Ui {
|
||||
class FrameInfoWindow;
|
||||
}
|
||||
|
||||
class FrameInfoWindow : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FrameInfoWindow(QList<CANFrame> *frames, QWidget *parent = 0);
|
||||
~FrameInfoWindow();
|
||||
|
||||
private slots:
|
||||
void updateDetailsWindow(int frameIdx);
|
||||
|
||||
private:
|
||||
Ui::FrameInfoWindow *ui;
|
||||
|
||||
QList<int> foundID;
|
||||
QList<CANFrame> frameCache;
|
||||
QList<CANFrame> *modelFrames;
|
||||
|
||||
void refreshIDList();
|
||||
};
|
||||
|
||||
#endif // FRAMEINFOWINDOW_H
|
||||
@@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>FrameInfoWindow</class>
|
||||
<widget class="QDialog" name="FrameInfoWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>794</width>
|
||||
<height>494</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Detailed Frame Information</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Frame IDs:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="listFrameID">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Details:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="treeDetails">
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">1</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef GRAPHINGWINDOW_H
|
||||
#define GRAPHINGWINDOW_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class GraphingWindow;
|
||||
}
|
||||
|
||||
class GraphingWindow : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GraphingWindow(QWidget *parent = 0);
|
||||
~GraphingWindow();
|
||||
|
||||
private:
|
||||
Ui::GraphingWindow *ui;
|
||||
};
|
||||
|
||||
#endif // GRAPHINGWINDOW_H
|
||||
@@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>GraphingWindow</class>
|
||||
<widget class="QDialog" name="GraphingWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<property name="sizeGripEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QCustomPlot" name="widget" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QCustomPlot</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>qcustomplot.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -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();
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <QSerialPort>
|
||||
#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);
|
||||
|
||||
@@ -104,6 +104,7 @@
|
||||
<addaction name="actionFlow_View"/>
|
||||
<addaction name="actionFuzzy_Scope"/>
|
||||
<addaction name="actionGraph_Dta"/>
|
||||
<addaction name="actionFrame_Data_Analysis"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuSend_Frames">
|
||||
<property name="title">
|
||||
@@ -177,6 +178,11 @@
|
||||
<string>Save Log File</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionFrame_Data_Analysis">
|
||||
<property name="text">
|
||||
<string>Frame Data Analysis</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
@@ -213,9 +219,43 @@
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>actionGraph_Dta</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>MainWindow</receiver>
|
||||
<slot>showGraphingWindow()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>463</x>
|
||||
<y>249</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>actionFrame_Data_Analysis</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>MainWindow</receiver>
|
||||
<slot>showFrameDataAnalysis()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>463</x>
|
||||
<y>249</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<slots>
|
||||
<slot>handleLoadFile()</slot>
|
||||
<slot>connButtonPress()</slot>
|
||||
<slot>showGraphingWindow()</slot>
|
||||
<slot>showFrameDataAnalysis()</slot>
|
||||
</slots>
|
||||
</ui>
|
||||
|
||||
Reference in New Issue
Block a user