implement seeking in playback window and add playback line in graphing view
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
#include "frameplaybackobject.h"
|
#include "frameplaybackobject.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
FramePlaybackObject::FramePlaybackObject()
|
FramePlaybackObject::FramePlaybackObject()
|
||||||
{
|
{
|
||||||
@@ -290,6 +291,47 @@ void FramePlaybackObject::pausePlayback()
|
|||||||
emit statusUpdate(currentPosition);
|
emit statusUpdate(currentPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FramePlaybackObject::seekPlayback(double timestamp)
|
||||||
|
{
|
||||||
|
if (currentSeqItem == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* make sure we execute in mThread context */
|
||||||
|
if (mThread_p && (mThread_p != QThread::currentThread()))
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod(this, "seekPlayback", Qt::BlockingQueuedConnection, timestamp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// playbackTimer->stop();
|
||||||
|
// playbackActive = false;
|
||||||
|
|
||||||
|
timestamp *= 1000000; // convert to us
|
||||||
|
|
||||||
|
size_t lowIdx = 0;
|
||||||
|
size_t highIdx = currentSeqItem->data.count() - 1;
|
||||||
|
|
||||||
|
while (lowIdx < highIdx)
|
||||||
|
{
|
||||||
|
int midIdx = lowIdx + (highIdx - lowIdx) / 2;
|
||||||
|
|
||||||
|
CANFrame midFrame = currentSeqItem->data[midIdx];
|
||||||
|
if (midFrame.timeStamp().seconds() * 1000000 + midFrame.timeStamp().microSeconds() < timestamp)
|
||||||
|
{
|
||||||
|
lowIdx = midIdx + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
highIdx = midIdx - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currentPosition = lowIdx;
|
||||||
|
emit statusUpdate(currentPosition);
|
||||||
|
|
||||||
|
startPlaybackForward();
|
||||||
|
}
|
||||||
|
|
||||||
void FramePlaybackObject::setSequenceObject(SequenceItem *item)
|
void FramePlaybackObject::setSequenceObject(SequenceItem *item)
|
||||||
{
|
{
|
||||||
currentSeqItem = item;
|
currentSeqItem = item;
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ public slots:
|
|||||||
void stepPlaybackBackward();
|
void stepPlaybackBackward();
|
||||||
void stopPlayback();
|
void stopPlayback();
|
||||||
void pausePlayback();
|
void pausePlayback();
|
||||||
|
void seekPlayback(double timestamp);
|
||||||
|
|
||||||
void setSequenceObject(SequenceItem *item);
|
void setSequenceObject(SequenceItem *item);
|
||||||
void setUseOriginalTiming(bool state);
|
void setUseOriginalTiming(bool state);
|
||||||
|
|||||||
@@ -407,10 +407,24 @@ void FramePlaybackWindow::EndOfFrameCache()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FramePlaybackWindow::gotCenterTimeID(uint32_t ID, double timestamp)
|
||||||
|
{
|
||||||
|
Q_UNUSED(ID);
|
||||||
|
|
||||||
|
// isPlaying = false;
|
||||||
|
// wantPlaying = false;
|
||||||
|
// haveIncomingTraffic = false;
|
||||||
|
|
||||||
|
playbackObject.seekPlayback(timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
void FramePlaybackWindow::getStatusUpdate(int frameNum)
|
void FramePlaybackWindow::getStatusUpdate(int frameNum)
|
||||||
{
|
{
|
||||||
currentPosition = frameNum;
|
currentPosition = frameNum;
|
||||||
updateFrameLabel();
|
updateFrameLabel();
|
||||||
|
QCanBusFrame::TimeStamp ts = seqItems[currentSeqNum].data[currentPosition].timeStamp();
|
||||||
|
|
||||||
|
emit sendCurrentTimestamp((double)(ts.seconds()) + ts.microSeconds() / 1000000.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramePlaybackWindow::updateFrameLabel()
|
void FramePlaybackWindow::updateFrameLabel()
|
||||||
@@ -426,15 +440,40 @@ void FramePlaybackWindow::updateFrameLabel()
|
|||||||
{
|
{
|
||||||
ui->lblCurrPlayback->setText("");
|
ui->lblCurrPlayback->setText("");
|
||||||
ui->lblPosition->setText("");
|
ui->lblPosition->setText("");
|
||||||
|
ui->timePosition->setText("");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->lblCurrPlayback->setText(currentSeqItem->filename);
|
ui->lblCurrPlayback->setText(currentSeqItem->filename);
|
||||||
|
|
||||||
|
// convert current and last timestamp to text according to time format
|
||||||
|
QVariant currentTimestamp = Utility::formatTimestamp(seqItems[row].data[currentPosition].timeStamp().microSeconds());
|
||||||
|
QString currentTimestampText;
|
||||||
|
if (currentTimestamp.typeId() == QMetaType::Double)
|
||||||
|
currentTimestampText = QString::number(currentTimestamp.toDouble(), 'f', 5);
|
||||||
|
else if (currentTimestamp.typeId() == QMetaType::LongLong || currentTimestamp.typeId() == QMetaType::ULongLong)
|
||||||
|
currentTimestampText = QString::number(currentTimestamp.toLongLong());
|
||||||
|
else if (currentTimestamp.typeId() == QMetaType::QDateTime)
|
||||||
|
currentTimestampText = currentTimestamp.toDateTime().toString(Utility::timeFormat);
|
||||||
|
else
|
||||||
|
currentTimestampText = currentTimestamp.toString();
|
||||||
|
|
||||||
|
QVariant lastTimestamp = Utility::formatTimestamp(seqItems[row].data.last().timeStamp().microSeconds());
|
||||||
|
QString lastTimestampText;
|
||||||
|
if (lastTimestamp.typeId() == QMetaType::Double)
|
||||||
|
lastTimestampText = QString::number(lastTimestamp.toDouble(), 'f', 5);
|
||||||
|
else if (lastTimestamp.typeId() == QMetaType::LongLong || lastTimestamp.typeId() == QMetaType::ULongLong)
|
||||||
|
lastTimestampText = QString::number(lastTimestamp.toLongLong());
|
||||||
|
else if (lastTimestamp.typeId() == QMetaType::QDateTime)
|
||||||
|
lastTimestampText = lastTimestamp.toDateTime().toString(Utility::timeFormat);
|
||||||
|
else
|
||||||
|
lastTimestampText = lastTimestamp.toString();
|
||||||
|
|
||||||
if (wantPlaying && !isPlaying)
|
if (wantPlaying && !isPlaying)
|
||||||
ui->lblPosition->setText(QString::number(currentPosition) + tr(" of ") + QString::number(seqItems[row].data.count()) + " (WAITING)");
|
ui->lblPosition->setText(QString::number(currentPosition) + tr(" of ") + QString::number(seqItems[row].data.count()) + " (WAITING)");
|
||||||
else
|
else
|
||||||
ui->lblPosition->setText(QString::number(currentPosition) + tr(" of ") + QString::number(seqItems[row].data.count()));
|
ui->lblPosition->setText(QString::number(currentPosition) + tr(" of ") + QString::number(seqItems[row].data.count()));
|
||||||
|
ui->timePosition->setText(currentTimestampText + tr(" of ") + lastTimestampText);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramePlaybackWindow::seqTableCellClicked(int row, int col)
|
void FramePlaybackWindow::seqTableCellClicked(int row, int col)
|
||||||
|
|||||||
@@ -42,10 +42,14 @@ private slots:
|
|||||||
void saveFilters();
|
void saveFilters();
|
||||||
void loadFilters();
|
void loadFilters();
|
||||||
void useOrigTimingClicked();
|
void useOrigTimingClicked();
|
||||||
|
void gotCenterTimeID(uint32_t ID, double timestamp);
|
||||||
void getStatusUpdate(int frameNum);
|
void getStatusUpdate(int frameNum);
|
||||||
void EndOfFrameCache();
|
void EndOfFrameCache();
|
||||||
void updatedFrames(int);
|
void updatedFrames(int);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void sendCurrentTimestamp(double timestamp);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::FramePlaybackWindow *ui;
|
Ui::FramePlaybackWindow *ui;
|
||||||
QList<int> foundID;
|
QList<int> foundID;
|
||||||
|
|||||||
@@ -1684,6 +1684,11 @@ void MainWindow::showGraphingWindow()
|
|||||||
connect(lastGraphingWindow, SIGNAL(sendCenterTimeID(uint32_t,double)), flowViewWindow, SLOT(gotCenterTimeID(uint32_t,double)));
|
connect(lastGraphingWindow, SIGNAL(sendCenterTimeID(uint32_t,double)), flowViewWindow, SLOT(gotCenterTimeID(uint32_t,double)));
|
||||||
connect(flowViewWindow, SIGNAL(sendCenterTimeID(uint32_t,double)), lastGraphingWindow, SLOT(gotCenterTimeID(uint32_t,double)));
|
connect(flowViewWindow, SIGNAL(sendCenterTimeID(uint32_t,double)), lastGraphingWindow, SLOT(gotCenterTimeID(uint32_t,double)));
|
||||||
}
|
}
|
||||||
|
if (playbackWindow)
|
||||||
|
{
|
||||||
|
connect(lastGraphingWindow, SIGNAL(sendCenterTimeID(uint32_t,double)), playbackWindow, SLOT(gotCenterTimeID(uint32_t,double)));
|
||||||
|
connect(playbackWindow, SIGNAL(sendCurrentTimestamp(double)), lastGraphingWindow, SLOT(gotPlaybackTimestamp(double)));
|
||||||
|
}
|
||||||
|
|
||||||
lastGraphingWindow->show();
|
lastGraphingWindow->show();
|
||||||
}
|
}
|
||||||
@@ -1786,6 +1791,13 @@ void MainWindow::showPlaybackWindow()
|
|||||||
playbackWindow = new FramePlaybackWindow(model->getListReference());
|
playbackWindow = new FramePlaybackWindow(model->getListReference());
|
||||||
else
|
else
|
||||||
playbackWindow = new FramePlaybackWindow(model->getFilteredListReference());
|
playbackWindow = new FramePlaybackWindow(model->getFilteredListReference());
|
||||||
|
|
||||||
|
connect(this, SIGNAL(sendCenterTimeID(uint32_t, double)), playbackWindow, SLOT(gotCenterTimeID(uint32_t, double)));
|
||||||
|
for (auto &&graphWindow : graphWindows)
|
||||||
|
{
|
||||||
|
connect(graphWindow, SIGNAL(sendCenterTimeID(uint32_t, double)), playbackWindow, SLOT(gotCenterTimeID(uint32_t, double)));
|
||||||
|
connect(playbackWindow, SIGNAL(sendCurrentTimestamp(double)), graphWindow, SLOT(gotPlaybackTimestamp(double)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
playbackWindow->show();
|
playbackWindow->show();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,6 +69,13 @@ GraphingWindow::GraphingWindow(const QVector<CANFrame> *frames, QWidget *parent)
|
|||||||
itemTracer->setStyle(QCPItemTracer::tsCircle);
|
itemTracer->setStyle(QCPItemTracer::tsCircle);
|
||||||
itemTracer->setSize(20);
|
itemTracer->setSize(20);
|
||||||
|
|
||||||
|
playbackPen.setWidth(1);
|
||||||
|
playbackPen.setColor(Qt::red);
|
||||||
|
playbackLine = new QCPItemStraightLine(ui->graphingView);
|
||||||
|
playbackLine->setSelectable(false);
|
||||||
|
playbackLine->setPen(playbackPen);
|
||||||
|
playbackLine->setVisible(false);
|
||||||
|
|
||||||
// connect slot that ties some axis selections together (especially opposite axes):
|
// connect slot that ties some axis selections together (especially opposite axes):
|
||||||
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
|
||||||
@@ -329,6 +336,28 @@ void GraphingWindow::gotCenterTimeID(uint32_t ID, double timestamp)
|
|||||||
ui->graphingView->replot();
|
ui->graphingView->replot();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GraphingWindow::gotPlaybackTimestamp(double timestamp)
|
||||||
|
{
|
||||||
|
if (timestamp == INFINITY) {
|
||||||
|
playbackLine->setVisible(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
playbackLine->setVisible(true);
|
||||||
|
|
||||||
|
// timestamp is always givin in seconds
|
||||||
|
if (Utility::timeStyle == TS_MICROS)
|
||||||
|
timestamp *= 1000000;
|
||||||
|
else if (Utility::timeStyle == TS_MILLIS)
|
||||||
|
timestamp *= 1000;
|
||||||
|
else if (Utility::timeStyle == TS_CLOCK)
|
||||||
|
timestamp += 3600; // offset of one hour needed
|
||||||
|
|
||||||
|
playbackLine->point1->setCoords(timestamp, 0);
|
||||||
|
playbackLine->point2->setCoords(timestamp, 1);
|
||||||
|
|
||||||
|
ui->graphingView->replot();
|
||||||
|
}
|
||||||
|
|
||||||
void GraphingWindow::titleDoubleClick(QMouseEvent* event, QCPTextElement* title)
|
void GraphingWindow::titleDoubleClick(QMouseEvent* event, QCPTextElement* title)
|
||||||
{
|
{
|
||||||
Q_UNUSED(event)
|
Q_UNUSED(event)
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ private slots:
|
|||||||
void editSelectedGraph();
|
void editSelectedGraph();
|
||||||
void updatedFrames(int);
|
void updatedFrames(int);
|
||||||
void gotCenterTimeID(uint32_t ID, double timestamp);
|
void gotCenterTimeID(uint32_t ID, double timestamp);
|
||||||
|
void gotPlaybackTimestamp(double timestamp);
|
||||||
void resetView();
|
void resetView();
|
||||||
void zoomIn();
|
void zoomIn();
|
||||||
void zoomOut();
|
void zoomOut();
|
||||||
@@ -105,6 +106,8 @@ private:
|
|||||||
QCPSelectionDecorator *selDecorator;
|
QCPSelectionDecorator *selDecorator;
|
||||||
QCPItemText *locationText;
|
QCPItemText *locationText;
|
||||||
QCPItemTracer *itemTracer;
|
QCPItemTracer *itemTracer;
|
||||||
|
QPen playbackPen;
|
||||||
|
QCPItemStraightLine *playbackLine;
|
||||||
bool needScaleSetup; //do we need to set x,y graphing extents?
|
bool needScaleSetup; //do we need to set x,y graphing extents?
|
||||||
bool useOpenGL;
|
bool useOpenGL;
|
||||||
bool followGraphEnd;
|
bool followGraphEnd;
|
||||||
|
|||||||
@@ -227,6 +227,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item alignment="Qt::AlignHCenter">
|
||||||
|
<widget class="QLabel" name="timePosition">
|
||||||
|
<property name="text">
|
||||||
|
<string>x of y</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|||||||
Reference in New Issue
Block a user