The main screen, flowview, and graphing screens are now linked. If you double click a frame on the main window or a graph in flowview or the graphing window the other two windows will update to show that data as well.

This commit is contained in:
Collin Kidder
2015-08-23 15:45:56 -04:00
parent 32c38e2331
commit e1eb1f9ab1
9 changed files with 158 additions and 6 deletions
+15
View File
@@ -398,6 +398,21 @@ void CANFrameModel::insertFrames(const QVector<CANFrame> &newFrames)
if (needFilterRefresh) emit updatedFiltersList(); if (needFilterRefresh) emit updatedFiltersList();
} }
int CANFrameModel::getIndexFromTimeID(int ID, double timestamp)
{
int bestIndex = -1;
uint64_t intTimeStamp = timestamp * 1000000l;
for (int i = 0; i < frames.count(); i++)
{
if ((frames[i].ID == ID))
{
if (frames[i].timestamp <= intTimeStamp) bestIndex = i;
else break; //drop out of loop as soon as we pass the proper timestamp
}
}
return bestIndex;
}
void CANFrameModel::loadFilterFile(QString filename) void CANFrameModel::loadFilterFile(QString filename)
{ {
QFile *inFile = new QFile(filename); QFile *inFile = new QFile(filename);
+1
View File
@@ -41,6 +41,7 @@ public:
void recalcOverwrite(); void recalcOverwrite();
bool needsFilterRefresh(); bool needsFilterRefresh();
void insertFrames(const QVector<CANFrame> &newFrames); void insertFrames(const QVector<CANFrame> &newFrames);
int getIndexFromTimeID(int ID, double timestamp);
const QVector<CANFrame> *getListReference() const; //thou shalt not modify these frames externally! const QVector<CANFrame> *getListReference() const; //thou shalt not modify these frames externally!
const QVector<CANFrame> *getFilteredListReference() const; //Thus saith the Lord, NO. const QVector<CANFrame> *getFilteredListReference() const; //Thus saith the Lord, NO.
const QMap<int, bool> *getFiltersReference() const; //this neither const QMap<int, bool> *getFiltersReference() const; //this neither
+1 -1
View File
@@ -1,7 +1,7 @@
#ifndef CONFIG #ifndef CONFIG
#define CONFIG #define CONFIG
#define VERSION 135 #define VERSION 136
//try to keep this in sync. //try to keep this in sync.
//SavvyCAN will complain if you connect a GVRET board with a revision //SavvyCAN will complain if you connect a GVRET board with a revision
+53
View File
@@ -68,6 +68,7 @@ FlowViewWindow::FlowViewWindow(const QVector<CANFrame> *frames, QWidget *parent)
connect(ui->cbLoopPlayback, SIGNAL(clicked(bool)), this, SLOT(changeLooping(bool))); connect(ui->cbLoopPlayback, SIGNAL(clicked(bool)), this, SLOT(changeLooping(bool)));
connect(ui->listFrameID, SIGNAL(currentTextChanged(QString)), this, SLOT(changeID(QString))); connect(ui->listFrameID, SIGNAL(currentTextChanged(QString)), this, SLOT(changeID(QString)));
connect(playbackTimer, SIGNAL(timeout()), this, SLOT(timerTriggered())); connect(playbackTimer, SIGNAL(timeout()), this, SLOT(timerTriggered()));
connect(ui->graphView, SIGNAL(plottableDoubleClick(QCPAbstractPlottable*,QMouseEvent*)), this, SLOT(plottableDoubleClick(QCPAbstractPlottable*,QMouseEvent*)));
connect(MainWindow::getReference(), SIGNAL(framesUpdated(int)), this, SLOT(updatedFrames(int))); connect(MainWindow::getReference(), SIGNAL(framesUpdated(int)), this, SLOT(updatedFrames(int)));
@@ -143,6 +144,58 @@ void FlowViewWindow::writeSettings()
} }
} }
void FlowViewWindow::plottableDoubleClick(QCPAbstractPlottable* plottable, QMouseEvent* event)
{
int id = 0;
//apply transforms to get the X axis value where we double clicked
double coord = plottable->keyAxis()->pixelToCoord(event->localPos().x());
if (frameCache.count() > 0) id = frameCache[0].ID;
if (secondsMode) emit sendCenterTimeID(id, coord);
else emit sendCenterTimeID(id, coord / 1000000.0);
}
void FlowViewWindow::gotCenterTimeID(int32_t ID, double timestamp)
{
if (secondsMode) timestamp *= 1000000.0; //frames always store timestamp in microseconds
qDebug() << "timestamp: " << timestamp;
changeID(QString::number(ID)); //to be sure we're focused on the proper ID
for (int j = 0; j < ui->listFrameID->count(); j++)
{
int thisNum = Utility::ParseStringToNum(ui->listFrameID->item(j)->text());
if (thisNum == ID)
{
ui->listFrameID->setCurrentRow(j);
break;
}
}
int bestIdx = -1;
for (int i = 0; i < frameCache.count(); i++)
{
if (frameCache[i].timestamp > timestamp)
{
bestIdx = i - 1;
break;
}
}
qDebug() << "Best index " << bestIdx;
if (bestIdx > -1)
{
currentPosition = bestIdx;
if (ui->cbAutoRef->isChecked())
{
memcpy(refBytes, currBytes, 8);
}
memcpy(currBytes, frameCache.at(currentPosition).data, 8);
updateDataView();
}
}
void FlowViewWindow::contextMenuRequestFlow(QPoint pos) void FlowViewWindow::contextMenuRequestFlow(QPoint pos)
{ {
QMenu *menu = new QMenu(this); QMenu *menu = new QMenu(this);
+6
View File
@@ -2,6 +2,7 @@
#define FLOWVIEWWINDOW_H #define FLOWVIEWWINDOW_H
#include <QDialog> #include <QDialog>
#include "qcustomplot.h"
#include "can_structs.h" #include "can_structs.h"
namespace Ui { namespace Ui {
@@ -33,6 +34,11 @@ private slots:
void contextMenuRequestGraph(QPoint pos); void contextMenuRequestGraph(QPoint pos);
void saveFileFlow(); void saveFileFlow();
void saveFileGraph(); void saveFileGraph();
void plottableDoubleClick(QCPAbstractPlottable* plottable, QMouseEvent* event);
void gotCenterTimeID(int32_t ID, double timestamp);
signals:
void sendCenterTimeID(int32_t ID, double timestamp);
private: private:
Ui::FlowViewWindow *ui; Ui::FlowViewWindow *ui;
+32
View File
@@ -45,6 +45,7 @@ GraphingWindow::GraphingWindow(DBCHandler *handler, const QVector<CANFrame> *fra
connect(ui->graphingView, SIGNAL(selectionChangedByUser()), this, SLOT(selectionChanged())); connect(ui->graphingView, SIGNAL(selectionChangedByUser()), this, SLOT(selectionChanged()));
//connect up the mouse controls //connect up the mouse controls
connect(ui->graphingView, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(mousePress())); connect(ui->graphingView, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(mousePress()));
connect(ui->graphingView, SIGNAL(plottableDoubleClick(QCPAbstractPlottable*,QMouseEvent*)), this, SLOT(plottableDoubleClick(QCPAbstractPlottable*,QMouseEvent*)));
connect(ui->graphingView, SIGNAL(mouseWheel(QWheelEvent*)), this, SLOT(mouseWheel())); connect(ui->graphingView, SIGNAL(mouseWheel(QWheelEvent*)), this, SLOT(mouseWheel()));
// make bottom and left axes transfer their ranges to top and right axes: // make bottom and left axes transfer their ranges to top and right axes:
@@ -152,6 +153,32 @@ void GraphingWindow::updatedFrames(int numFrames)
} }
} }
void GraphingWindow::plottableDoubleClick(QCPAbstractPlottable* plottable, QMouseEvent* event)
{
int id = 0;
//apply transforms to get the X axis value where we double clicked
double coord = plottable->keyAxis()->pixelToCoord(event->localPos().x());
id = plottable->property("id").toInt();
if (secondsMode) emit sendCenterTimeID(id, coord);
else emit sendCenterTimeID(id, coord / 1000000.0);
}
void GraphingWindow::gotCenterTimeID(int32_t ID, double timestamp)
{
//its problematic to try to highlight a graph since we get the ID
//and timestamp not the signal in question so there is no real way
//to know which graph. But, if that changes here is a stub
//for (int i = 0; i < graphParams.count(); i++)
//{
//}
QCPRange range = ui->graphingView->xAxis->range();
double offset = range.size() / 2.0;
if (!secondsMode) timestamp *= 1000000.0; //timestamp is always in seconds when being passed so convert if necessary
ui->graphingView->xAxis->setRange(timestamp - offset, timestamp + offset);
ui->graphingView->replot();
}
void GraphingWindow::titleDoubleClick(QMouseEvent* event, QCPPlotTitle* title) void GraphingWindow::titleDoubleClick(QMouseEvent* event, QCPPlotTitle* title)
{ {
Q_UNUSED(event) Q_UNUSED(event)
@@ -802,6 +829,9 @@ void GraphingWindow::createGraph(GraphParams &params, bool createGraphParam)
} }
} }
params.xbias = 0;
/*
for (int ct = 0; ct < params.x.count(); ct++) for (int ct = 0; ct < params.x.count(); ct++)
{ {
params.x[ct] -= xminval; params.x[ct] -= xminval;
@@ -809,6 +839,7 @@ void GraphingWindow::createGraph(GraphParams &params, bool createGraphParam)
params.xbias = xminval; params.xbias = xminval;
xmaxval -= xminval; xmaxval -= xminval;
xminval = 0; xminval = 0;
*/
ui->graphingView->addGraph(); ui->graphingView->addGraph();
params.ref = ui->graphingView->graph(); params.ref = ui->graphingView->graph();
@@ -826,6 +857,7 @@ void GraphingWindow::createGraph(GraphParams &params, bool createGraphParam)
if ((params.endByte != -1) && (params.endByte != params.startByte)) params.graphName += "-" + QString::number(params.endByte); if ((params.endByte != -1) && (params.endByte != params.startByte)) params.graphName += "-" + QString::number(params.endByte);
} }
ui->graphingView->graph()->setName(params.graphName); ui->graphingView->graph()->setName(params.graphName);
ui->graphingView->graph()->setProperty("id", params.ID);
ui->graphingView->graph()->setData(refParam->x,refParam->y); ui->graphingView->graph()->setData(refParam->x,refParam->y);
ui->graphingView->graph()->setLineStyle(QCPGraph::lsLine); //connect points with lines ui->graphingView->graph()->setLineStyle(QCPGraph::lsLine); //connect points with lines
+5
View File
@@ -42,6 +42,7 @@ private slots:
void titleDoubleClick(QMouseEvent *event, QCPPlotTitle *title); void titleDoubleClick(QMouseEvent *event, QCPPlotTitle *title);
void axisLabelDoubleClick(QCPAxis* axis, QCPAxis::SelectablePart part); void axisLabelDoubleClick(QCPAxis* axis, QCPAxis::SelectablePart part);
void legendDoubleClick(QCPLegend* legend, QCPAbstractLegendItem* item); void legendDoubleClick(QCPLegend* legend, QCPAbstractLegendItem* item);
void plottableDoubleClick(QCPAbstractPlottable* plottable,QMouseEvent* event);
void selectionChanged(); void selectionChanged();
void mousePress(); void mousePress();
void mouseWheel(); void mouseWheel();
@@ -57,6 +58,10 @@ private slots:
void appendToGraph(GraphParams &params, CANFrame &frame); void appendToGraph(GraphParams &params, CANFrame &frame);
void editSelectedGraph(); void editSelectedGraph();
void updatedFrames(int); void updatedFrames(int);
void gotCenterTimeID(int32_t ID, double timestamp);
signals:
void sendCenterTimeID(int32_t ID, double timestamp);
private: private:
Ui::GraphingWindow *ui; Ui::GraphingWindow *ui;
+40 -3
View File
@@ -126,6 +126,7 @@ MainWindow::MainWindow(QWidget *parent) :
connect(ui->actionLoad_DBC_File, SIGNAL(triggered(bool)), this, SLOT(handleLoadDBC())); connect(ui->actionLoad_DBC_File, SIGNAL(triggered(bool)), this, SLOT(handleLoadDBC()));
connect(ui->actionSave_DBC_File, SIGNAL(triggered(bool)), this, SLOT(handleSaveDBC())); connect(ui->actionSave_DBC_File, SIGNAL(triggered(bool)), this, SLOT(handleSaveDBC()));
connect(ui->canFramesView, SIGNAL(clicked(QModelIndex)), this, SLOT(gridClicked(QModelIndex))); connect(ui->canFramesView, SIGNAL(clicked(QModelIndex)), this, SLOT(gridClicked(QModelIndex)));
connect(ui->canFramesView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(gridDoubleClicked(QModelIndex)));
connect(ui->cbInterpret, SIGNAL(toggled(bool)), this, SLOT(interpretToggled(bool))); connect(ui->cbInterpret, SIGNAL(toggled(bool)), this, SLOT(interpretToggled(bool)));
connect(ui->cbOverwrite, SIGNAL(toggled(bool)), this, SLOT(overwriteToggled(bool))); connect(ui->cbOverwrite, SIGNAL(toggled(bool)), this, SLOT(overwriteToggled(bool)));
connect(ui->actionEdit_Messages_Signals, SIGNAL(triggered(bool)), this, SLOT(showDBCEditor())); connect(ui->actionEdit_Messages_Signals, SIGNAL(triggered(bool)), this, SLOT(showDBCEditor()));
@@ -263,7 +264,8 @@ void MainWindow::readUpdateableSettings()
useHex = settings.value("Main/UseHex", true).toBool(); useHex = settings.value("Main/UseHex", true).toBool();
model->setHexMode(useHex); model->setHexMode(useHex);
Utility::decimalMode = !useHex; Utility::decimalMode = !useHex;
model->setSecondsMode(settings.value("Main/TimeSeconds", false).toBool()); secondsMode = settings.value("Main/TimeSeconds", false).toBool();
model->setSecondsMode(secondsMode);
useFiltered = settings.value("Main/UseFiltered", false).toBool(); useFiltered = settings.value("Main/UseFiltered", false).toBool();
} }
@@ -289,6 +291,13 @@ void MainWindow::gridClicked(QModelIndex idx)
} }
} }
void MainWindow::gridDoubleClicked(QModelIndex idx)
{
//grab ID and timestamp and send them away
CANFrame frame = model->getListReference()->at(idx.row());
emit sendCenterTimeID(frame.ID, frame.timestamp / 1000000.0);
}
void MainWindow::interpretToggled(bool state) void MainWindow::interpretToggled(bool state)
{ {
model->setInterpetMode(state); model->setInterpetMode(state);
@@ -383,6 +392,17 @@ void MainWindow::addFrameToDisplay(CANFrame &frame, bool autoRefresh = false)
} }
} }
//A sub-window is sending us a center on timestamp and ID signal
//try to find the relevant frame in the list and focus on it.
void MainWindow::gotCenterTimeID(int32_t ID, double timestamp)
{
int idx = model->getIndexFromTimeID(ID, timestamp);
if (idx > -1)
{
ui->canFramesView->selectRow(idx);
}
}
void MainWindow::clearFrames() void MainWindow::clearFrames()
{ {
ui->canFramesView->scrollToTop(); ui->canFramesView->scrollToTop();
@@ -397,6 +417,7 @@ void MainWindow::clearFrames()
void MainWindow::normalizeTiming() void MainWindow::normalizeTiming()
{ {
model->normalizeTiming(); model->normalizeTiming();
emit framesUpdated(-2); //claim an all new set of frames because every frame was updated.
} }
void MainWindow::changeBaudRates() void MainWindow::changeBaudRates()
@@ -900,6 +921,14 @@ void MainWindow::showGraphingWindow()
{ {
if (!graphingWindow) { if (!graphingWindow) {
graphingWindow = new GraphingWindow(dbcHandler, model->getListReference()); graphingWindow = new GraphingWindow(dbcHandler, model->getListReference());
connect(graphingWindow, SIGNAL(sendCenterTimeID(int32_t,double)), this, SLOT(gotCenterTimeID(int32_t,double)));
connect(this, SIGNAL(sendCenterTimeID(int32_t,double)), graphingWindow, SLOT(gotCenterTimeID(int32_t,double)));
}
if (flowViewWindow) //connect the two external windows together
{
connect(graphingWindow, SIGNAL(sendCenterTimeID(int32_t,double)), flowViewWindow, SLOT(gotCenterTimeID(int32_t,double)));
connect(flowViewWindow, SIGNAL(sendCenterTimeID(int32_t,double)), graphingWindow, SLOT(gotCenterTimeID(int32_t,double)));
} }
graphingWindow->show(); graphingWindow->show();
} }
@@ -987,10 +1016,18 @@ void MainWindow::showFlowViewWindow()
flowViewWindow = new FlowViewWindow(model->getListReference()); flowViewWindow = new FlowViewWindow(model->getListReference());
else else
flowViewWindow = new FlowViewWindow(model->getFilteredListReference()); flowViewWindow = new FlowViewWindow(model->getFilteredListReference());
} connect(flowViewWindow, SIGNAL(sendCenterTimeID(int32_t,double)), this, SLOT(gotCenterTimeID(int32_t,double)));
flowViewWindow->show(); connect(this, SIGNAL(sendCenterTimeID(int32_t,double)), flowViewWindow, SLOT(gotCenterTimeID(int32_t,double)));
} }
if (graphingWindow)
{
connect(graphingWindow, SIGNAL(sendCenterTimeID(int32_t,double)), flowViewWindow, SLOT(gotCenterTimeID(int32_t,double)));
connect(flowViewWindow, SIGNAL(sendCenterTimeID(int32_t,double)), graphingWindow, SLOT(gotCenterTimeID(int32_t,double)));
}
flowViewWindow->show();
}
//this one always gets the unfiltered list intentionally. //this one always gets the unfiltered list intentionally.
void MainWindow::showDBCEditor() void MainWindow::showDBCEditor()
+4 -1
View File
@@ -59,6 +59,7 @@ private slots:
void gotDeviceInfo(int, int); void gotDeviceInfo(int, int);
void connectionSucceeded(int, int); void connectionSucceeded(int, int);
void gridClicked(QModelIndex); void gridClicked(QModelIndex);
void gridDoubleClicked(QModelIndex);
void interpretToggled(bool); void interpretToggled(bool);
void overwriteToggled(bool); void overwriteToggled(bool);
void showDBCEditor(); void showDBCEditor();
@@ -72,7 +73,7 @@ private slots:
public slots: public slots:
void gotFrames(int, int); void gotFrames(int, int);
void updateSettings(); void updateSettings();
void gotCenterTimeID(int32_t ID, double timestamp);
signals: signals:
void sendSerialPort(QSerialPortInfo *port); void sendSerialPort(QSerialPortInfo *port);
@@ -85,6 +86,7 @@ signals:
//-1 = frames cleared, -2 = a new file has been loaded (so all frames are different), otherwise # of new frames //-1 = frames cleared, -2 = a new file has been loaded (so all frames are different), otherwise # of new frames
void framesUpdated(int numFrames); //something has updated the frame list void framesUpdated(int numFrames); //something has updated the frame list
void settingsUpdated(); void settingsUpdated();
void sendCenterTimeID(int32_t ID, double timestamp);
private: private:
Ui::MainWindow *ui; Ui::MainWindow *ui;
@@ -100,6 +102,7 @@ private:
bool inhibitFilterUpdate; bool inhibitFilterUpdate;
bool useHex; bool useHex;
bool allowCapture; bool allowCapture;
bool secondsMode;
bool bDirty; //have frames been added or subtracted since the last save/load? bool bDirty; //have frames been added or subtracted since the last save/load?
bool useFiltered; //should sub-windows use the unfiltered or filtered frames list? bool useFiltered; //should sub-windows use the unfiltered or filtered frames list?