Matthias Jung, Janik Schlemminger and Robert Gernhardt were used as authors for all files wihout an author/header. Also, removed headers from files that already had a license statement: dram.vp.system/analyzer/analyzer/thirdParty/*
592 lines
19 KiB
C++
592 lines
19 KiB
C++
/*
|
|
* Copyright (c) 2015, University of Kaiserslautern
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* 3. Neither the name of the copyright holder nor the names of its
|
|
* contributors may be used to endorse or promote products derived from
|
|
* this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
|
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
* Authors:
|
|
* Janik Schlemminger
|
|
* Robert Gernhardt
|
|
* Matthias Jung
|
|
*/
|
|
|
|
#include <qwt_plot_grid.h>
|
|
#include <QWheelEvent>
|
|
#include <QMessageBox>
|
|
#include <QMouseEvent>
|
|
#include <iostream>
|
|
#include <QMenu>
|
|
#include <cmath>
|
|
#include <QInputDialog>
|
|
#include <QKeySequence>
|
|
#include <QFileInfo>
|
|
#include <qfiledialog.h>
|
|
#include <iostream>
|
|
#include <qwt_plot_renderer.h>
|
|
|
|
#include "tracePlotMouseLabel.h"
|
|
#include "traceplot.h"
|
|
#include "gototimedialog.h"
|
|
#include "tracedrawing.h"
|
|
#include "util/engineeringScaleDraw.h"
|
|
#include "util/clkgrid.h"
|
|
#include "util/customlabelscaledraw.h"
|
|
|
|
using namespace std;
|
|
|
|
|
|
TracePlot::TracePlot(QWidget *parent):
|
|
QwtPlot(parent),isInitialized(false)
|
|
{
|
|
canvas()->setCursor(Qt::ArrowCursor);
|
|
setUpActions();
|
|
}
|
|
|
|
void TracePlot::setUpActions()
|
|
{
|
|
insertComment = new QAction("Insert comment",this);
|
|
QObject::connect(insertComment, SIGNAL(triggered()), this, SLOT(on_insertComment()));
|
|
|
|
goToTime = new QAction("Go to time",this);
|
|
QObject::connect(goToTime, SIGNAL(triggered()), this, SLOT(on_goToTime()));
|
|
|
|
goToTransaction = new QAction("Go to transaction", this);
|
|
QObject::connect(goToTransaction, SIGNAL(triggered()), this, SLOT(on_goToTransaction()));
|
|
|
|
deselectAll = new QAction("Deselect all",this);
|
|
QObject::connect(deselectAll, SIGNAL(triggered()), this, SLOT(on_deselectAll()));
|
|
|
|
goToPhase = new QAction("Go to phase", this);
|
|
QObject::connect(goToPhase, SIGNAL(triggered()), this, SLOT(on_goToPhase()));
|
|
|
|
showQueryEditor = new QAction("Execute query",this);
|
|
showQueryEditor->setShortcut(QKeySequence("ctrl+e"));
|
|
addAction(showQueryEditor);
|
|
QObject::connect(showQueryEditor,SIGNAL(triggered()),this,SLOT(on_executeQuery()));
|
|
|
|
selectNextRefresh = new QAction("Select next refresh",this);
|
|
selectNextRefresh->setShortcut(QKeySequence("alt+r"));
|
|
addAction(selectNextRefresh);
|
|
QObject::connect(selectNextRefresh, SIGNAL(triggered()), this, SLOT(on_selectNextRefresh()));
|
|
|
|
selectNextActivate = new QAction("Select next activate",this);
|
|
selectNextActivate->setShortcut(QKeySequence("alt+a"));
|
|
addAction(selectNextActivate);
|
|
QObject::connect(selectNextActivate, SIGNAL(triggered()), this, SLOT(on_selectNextActivate()));
|
|
|
|
selectNextPrecharge = new QAction("Select next precharge",this);
|
|
selectNextPrecharge->setShortcut(QKeySequence("alt+p"));
|
|
addAction(selectNextPrecharge);
|
|
QObject::connect(selectNextPrecharge, SIGNAL(triggered()), this, SLOT(on_selectNextPrecharge()));
|
|
|
|
setColorGroupingPhase = new QAction("Group by Phase",this);
|
|
addAction(setColorGroupingPhase);
|
|
QObject::connect(setColorGroupingPhase, SIGNAL(triggered()), this, SLOT(on_colorGroupingPhase()));
|
|
|
|
setColorGroupingTransaction = new QAction("Group by Transaction",this);
|
|
addAction(setColorGroupingTransaction);
|
|
QObject::connect(setColorGroupingTransaction, SIGNAL(triggered()), this, SLOT(on_colorGroupingTransaction()));
|
|
|
|
setColorGroupingThread = new QAction("Group by Thread",this);
|
|
addAction(setColorGroupingThread);
|
|
QObject::connect(setColorGroupingThread, SIGNAL(triggered()), this, SLOT(on_colorGroupingThread()));
|
|
|
|
exportToPdf = new QAction("Export to SVG", this);
|
|
addAction(exportToPdf);
|
|
QObject::connect(exportToPdf, SIGNAL(triggered()), this, SLOT(on_exportToPDF()));
|
|
|
|
setUpContextMenu();
|
|
}
|
|
|
|
void TracePlot::setUpContextMenu()
|
|
{
|
|
contextMenu = new QMenu(this);
|
|
contextMenu->addActions({deselectAll});
|
|
|
|
QMenu* colorGroupingSubMenu = new QMenu("Group by",contextMenu);
|
|
colorGroupingSubMenu->addActions({setColorGroupingTransaction, setColorGroupingPhase, setColorGroupingThread});
|
|
contextMenu->addMenu(colorGroupingSubMenu);
|
|
|
|
QMenu* goToSubMenu = new QMenu("Go to",contextMenu);
|
|
goToSubMenu->addActions({goToPhase,goToTransaction,goToTime});
|
|
contextMenu->addMenu(goToSubMenu);
|
|
|
|
QMenu* selectSubMenu = new QMenu("Select",contextMenu);
|
|
selectSubMenu->addActions({selectNextRefresh, selectNextActivate,selectNextPrecharge});
|
|
contextMenu->addMenu(selectSubMenu);
|
|
|
|
contextMenu->addActions({showQueryEditor, insertComment,exportToPdf});
|
|
}
|
|
|
|
void TracePlot::init(TraceNavigator* navigator)
|
|
{
|
|
Q_ASSERT(isInitialized == false);
|
|
isInitialized = true;
|
|
|
|
this->navigator = navigator;
|
|
connectNavigatorQ_SIGNALS();
|
|
setUpDrawingProperties();
|
|
setUpAxis();
|
|
setUpGrid();
|
|
setUpTracePlotItem();
|
|
setUpZoom();
|
|
setUpQueryEditor();
|
|
mouseLabel = new TracePlotMouseLabel(this,navigator->GeneralTraceInfo().clkPeriod,this->mouseDownData.zoomSpan);
|
|
getAndDrawComments();
|
|
setZoomLevel(1000);
|
|
replot();
|
|
}
|
|
|
|
|
|
void TracePlot::connectNavigatorQ_SIGNALS()
|
|
{
|
|
QObject::connect(navigator,SIGNAL(currentTraceTimeChanged()),this,SLOT(currentTraceTimeChanged()));
|
|
QObject::connect(navigator,SIGNAL(selectedTransactionsChanged()),this,SLOT(selectedTransactionsChanged()));
|
|
QObject::connect(navigator,SIGNAL(commentsChanged()),this,SLOT(commentsChanged()));
|
|
}
|
|
|
|
void TracePlot::setUpDrawingProperties()
|
|
{
|
|
unsigned int numberOfBanks = navigator -> GeneralTraceInfo().numberOfBanks;
|
|
drawingProperties.numberOfBanks = numberOfBanks;
|
|
drawingProperties.yValResponse = numberOfBanks;
|
|
drawingProperties.yValRequest = numberOfBanks + 1;
|
|
drawingProperties.yValCommandBus = -3;
|
|
drawingProperties.yValDataBus = -4;
|
|
}
|
|
|
|
|
|
void TracePlot::setUpQueryEditor()
|
|
{
|
|
queryEditor = new QueryEditor(this);
|
|
queryEditor->setWindowFlags(Qt::Window);
|
|
queryEditor->setWindowTitle("Query " + QFileInfo(navigator->TraceFile().getPathToDB()).baseName());
|
|
queryEditor->init(navigator);
|
|
}
|
|
|
|
void TracePlot::setUpTracePlotItem()
|
|
{
|
|
tracePlotItem = new TracePlotItem(transactions,*navigator,drawingProperties);
|
|
tracePlotItem->setZ(1);
|
|
tracePlotItem->attach(this);
|
|
}
|
|
|
|
void TracePlot::setUpGrid()
|
|
{
|
|
unsigned int clk = navigator->GeneralTraceInfo().clkPeriod;
|
|
QwtPlotGrid *grid = new ClkGrid(clk, GridVisiblityClks*clk);
|
|
grid->setZ(0);
|
|
grid->attach(this);
|
|
}
|
|
|
|
void TracePlot::setUpZoom()
|
|
{
|
|
minZoomLevel = minZoomClks * navigator->GeneralTraceInfo().clkPeriod;
|
|
maxZoomLevel = maxZoomClks * navigator->GeneralTraceInfo().clkPeriod;
|
|
textVisibilityZoomLevel = textVisibilityClks * navigator->GeneralTraceInfo().clkPeriod;
|
|
zoomZone = new QwtPlotZoneItem();
|
|
zoomZone->setZ(2);
|
|
zoomZone->attach(this);
|
|
zoomZone->setVisible(false);
|
|
}
|
|
|
|
void TracePlot::setUpAxis()
|
|
{
|
|
int numberOfBanks = navigator -> GeneralTraceInfo().numberOfBanks;
|
|
|
|
setAxisScale(yLeft, -5, numberOfBanks + 2, 1.0);
|
|
setAxisScaleDraw(yLeft,new CustomLabelScaleDraw(drawingProperties.getLabels()));
|
|
|
|
setAxisTitle(xBottom, "Time in ns");
|
|
setAxisScaleDraw(xBottom, new EngineeringScaleDraw);
|
|
}
|
|
|
|
Timespan TracePlot::GetCurrentTimespan()
|
|
{
|
|
Timespan span(navigator->CurrentTraceTime() - zoomLevel / 2, navigator->CurrentTraceTime() + zoomLevel / 2);
|
|
if(span.Begin() < 0)
|
|
span.shift(-span.Begin());
|
|
else if(span.End() > navigator->GeneralTraceInfo().span.End())
|
|
span.shift(navigator->GeneralTraceInfo().span.End() - span.End());
|
|
return span;
|
|
}
|
|
|
|
void TracePlot::getAndDrawComments()
|
|
{
|
|
for(const auto &pair: navigator->getComments())
|
|
{
|
|
const Comment &comment = pair.second;
|
|
QwtPlotMarker *maker = new QwtPlotMarker();
|
|
maker->setLabel(comment.Text());
|
|
maker->setLabelOrientation(Qt::Vertical);
|
|
maker->setLabelAlignment(Qt::AlignLeft | Qt::AlignBottom);
|
|
maker->setXValue(static_cast<double>(comment.Time()));
|
|
maker->setLineStyle(QwtPlotMarker::LineStyle::VLine);
|
|
maker->setLinePen(QColor(Qt::blue),2);
|
|
maker->attach(this);
|
|
}
|
|
}
|
|
|
|
void TracePlot::enterZoomMode()
|
|
{
|
|
mouseDownData.mouseIsDownForZooming = true;
|
|
mouseLabel->setMode(MouseLabelMode::Timedifference);
|
|
zoomZone->setVisible(true);
|
|
zoomZone->setInterval(mouseDownData.zoomSpan.Begin(),mouseDownData.zoomSpan.End());
|
|
}
|
|
|
|
void TracePlot::exitZoomMode()
|
|
{
|
|
mouseDownData.mouseIsDownForZooming = false;
|
|
mouseLabel->setMode(MouseLabelMode::AbsoluteTime);
|
|
zoomZone->setVisible(false);
|
|
}
|
|
void TracePlot::zoomIn(traceTime zoomCenter)
|
|
{
|
|
setZoomLevel(zoomLevel * zoomFactor);
|
|
traceTime time = zoomCenter + (GetCurrentTimespan().Middle() - zoomCenter) * zoomFactor;
|
|
Q_EMIT tracePlotZoomChanged();
|
|
navigator->navigateToTime(time);
|
|
}
|
|
|
|
void TracePlot::zoomOut(traceTime zoomCenter)
|
|
{
|
|
setZoomLevel(zoomLevel / zoomFactor);
|
|
Q_EMIT tracePlotZoomChanged();
|
|
navigator->navigateToTime(static_cast<traceTime>(zoomCenter + (GetCurrentTimespan().Middle() - zoomCenter) / zoomFactor));
|
|
}
|
|
|
|
void TracePlot::setZoomLevel(traceTime newZoomLevel)
|
|
{
|
|
zoomLevel = newZoomLevel;
|
|
if(zoomLevel < minZoomLevel)
|
|
zoomLevel = minZoomLevel;
|
|
if(zoomLevel > navigator->GeneralTraceInfo().span.timeCovered())
|
|
zoomLevel = navigator->GeneralTraceInfo().span.timeCovered();
|
|
if(zoomLevel > maxZoomLevel)
|
|
zoomLevel = maxZoomLevel;
|
|
|
|
if(zoomLevel < textVisibilityZoomLevel)
|
|
drawingProperties.drawText = true;
|
|
|
|
if(zoomLevel > textVisibilityZoomLevel)
|
|
drawingProperties.drawText = false;
|
|
}
|
|
|
|
|
|
/* Q_SLOTS
|
|
*
|
|
*
|
|
*/
|
|
|
|
void TracePlot::currentTraceTimeChanged()
|
|
{
|
|
transactions = navigator->TraceFile().getTransactionsInTimespan(GetCurrentTimespan());
|
|
setAxisScale(xBottom,GetCurrentTimespan().Begin(),GetCurrentTimespan().End());
|
|
replot();
|
|
}
|
|
|
|
void TracePlot::selectedTransactionsChanged()
|
|
{
|
|
replot();
|
|
}
|
|
|
|
void TracePlot::commentsChanged()
|
|
{
|
|
detachItems(QwtPlotItem::Rtti_PlotMarker);
|
|
getAndDrawComments();
|
|
replot();
|
|
}
|
|
|
|
void TracePlot::on_executeQuery()
|
|
{
|
|
queryEditor->show();
|
|
}
|
|
|
|
void TracePlot::on_selectNextRefresh()
|
|
{
|
|
navigator->selectNextRefresh();
|
|
}
|
|
|
|
void TracePlot::on_selectNextActivate()
|
|
{
|
|
navigator->selectNextActivate();
|
|
}
|
|
|
|
void TracePlot::on_selectNextPrecharge()
|
|
{
|
|
navigator->selectNextPrecharge();
|
|
}
|
|
|
|
void TracePlot::on_colorGroupingPhase()
|
|
{
|
|
drawingProperties.colorGrouping = ColorGrouping::PhaseType;
|
|
Q_EMIT(colorGroupingChanged(ColorGrouping::PhaseType));
|
|
replot();
|
|
}
|
|
|
|
void TracePlot::on_colorGroupingTransaction()
|
|
{
|
|
drawingProperties.colorGrouping = ColorGrouping::Transaction;
|
|
Q_EMIT(colorGroupingChanged(ColorGrouping::Transaction));
|
|
replot();
|
|
}
|
|
|
|
void TracePlot::on_colorGroupingThread()
|
|
{
|
|
drawingProperties.colorGrouping = ColorGrouping::Thread;
|
|
Q_EMIT(colorGroupingChanged(ColorGrouping::Thread));
|
|
replot();
|
|
}
|
|
|
|
void TracePlot::on_goToTransaction()
|
|
{
|
|
bool ok;
|
|
int maxID = navigator->GeneralTraceInfo().numberOfTransactions;
|
|
int transactionID = QInputDialog::getInt(this,"Go to transaction","Enter transaction ID (0 - " + QString::number(maxID) + ")",0,0,maxID,1,&ok);
|
|
if(ok)
|
|
{
|
|
navigator->clearSelectedTransactions();
|
|
navigator->selectTransaction(transactionID);
|
|
}
|
|
}
|
|
|
|
void TracePlot::on_goToPhase()
|
|
{
|
|
bool ok;
|
|
int maxID = navigator->GeneralTraceInfo().numberOfPhases;
|
|
int phaseID = QInputDialog::getInt(this,"Go to phase","Enter phase ID (0 - " + QString::number(maxID) + ")",0,0,maxID,1,&ok);
|
|
|
|
if(ok)
|
|
{
|
|
navigator->clearSelectedTransactions();
|
|
navigator->selectTransaction(navigator->TraceFile().getTransactionIDFromPhaseID(phaseID));
|
|
}
|
|
}
|
|
|
|
void TracePlot::on_deselectAll()
|
|
{
|
|
navigator->clearSelectedTransactions();
|
|
}
|
|
|
|
void TracePlot::on_insertComment()
|
|
{
|
|
traceTime time = invTransform(xBottom, contextMenuMouseDown.x());
|
|
bool ok;
|
|
QString text = QInputDialog::getText(this,QString("Insert comment"),QString("Insert comment at ") + prettyFormatTime(time),QLineEdit::Normal,QString(),&ok);
|
|
if(ok)
|
|
{
|
|
navigator->insertComment(Comment(time,text));
|
|
}
|
|
}
|
|
|
|
void TracePlot::on_goToTime()
|
|
{
|
|
double goToTime;
|
|
GoToTimeDialog dialog(&goToTime,this);
|
|
int dialogCode = dialog.exec();
|
|
if(dialogCode == QDialog::Accepted)
|
|
{
|
|
traceTime time = static_cast<traceTime>(goToTime)*1000;
|
|
navigator->navigateToTime(time);
|
|
}
|
|
}
|
|
|
|
void TracePlot::on_exportToPDF()
|
|
{
|
|
QwtPlotRenderer renderer;
|
|
QString filename = QFileDialog::getSaveFileName(this, "Export to SVG", "", "Portable Document Format(*.svg)");
|
|
if(filename != "")
|
|
{
|
|
QBrush saved = this->canvasBackground();
|
|
this->setCanvasBackground(QBrush(Qt::white));
|
|
renderer.renderDocument(this, filename,"svg", QSizeF(this->widthMM(),this->heightMM()));
|
|
this->setCanvasBackground(QBrush(saved));
|
|
}
|
|
}
|
|
|
|
/* Keyboard and mouse events
|
|
*
|
|
*
|
|
*/
|
|
|
|
void TracePlot::keyPressEvent(QKeyEvent *keyPressedEvent)
|
|
{
|
|
int key = keyPressedEvent->key();
|
|
if(Qt::Key_Control == key)
|
|
keyPressData.ctrlPressed = true;
|
|
else if(Qt::Key_Shift == key)
|
|
keyPressData.shiftPressed = true;
|
|
else if(Qt::Key_Right == key)
|
|
navigator->selectNextTransaction();
|
|
else if(Qt::Key_Left == key)
|
|
navigator->selectPreviousTransaction();
|
|
else if(Qt::Key_Minus == key)
|
|
{
|
|
zoomOut(GetCurrentTimespan().Middle());
|
|
}
|
|
else if(Qt::Key_Plus == key)
|
|
{
|
|
zoomIn(GetCurrentTimespan().Middle());
|
|
}
|
|
}
|
|
|
|
void TracePlot::keyReleaseEvent(QKeyEvent *keyReleasedEvent)
|
|
{
|
|
int key = keyReleasedEvent->key();
|
|
|
|
if(Qt::Key_Control == key)
|
|
keyPressData.ctrlPressed = false;
|
|
else if(Qt::Key_Shift == key)
|
|
{
|
|
keyPressData.shiftPressed = false;
|
|
exitZoomMode();
|
|
replot();
|
|
}
|
|
}
|
|
|
|
|
|
bool TracePlot::eventFilter(QObject *object, QEvent *event)
|
|
{
|
|
if(object == canvas())
|
|
{
|
|
switch(event->type())
|
|
{
|
|
case QEvent::Wheel :
|
|
{
|
|
QWheelEvent *wheelEvent = static_cast<QWheelEvent *>(event);
|
|
traceTime zoomCenter = static_cast<traceTime>(this->invTransform(xBottom, wheelEvent->x()));
|
|
|
|
(wheelEvent->delta() > 0) ? zoomIn(zoomCenter) : zoomOut(zoomCenter);
|
|
|
|
return true;
|
|
}
|
|
case QEvent::MouseButtonPress:
|
|
{
|
|
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
|
|
|
|
if(mouseEvent->button() == Qt::LeftButton)
|
|
{
|
|
if(keyPressData.shiftPressed)
|
|
{
|
|
mouseDownData.zoomSpan.setBegin(alignToClk(invTransform(xBottom, mouseEvent->x()),navigator->GeneralTraceInfo().clkPeriod));
|
|
mouseDownData.zoomSpan.setEnd(alignToClk(invTransform(xBottom, mouseEvent->x()),navigator->GeneralTraceInfo().clkPeriod));
|
|
enterZoomMode();
|
|
}
|
|
else
|
|
{
|
|
mouseDownData.mouseDownX = mouseEvent->x();
|
|
mouseDownData.mouseDownTime = GetCurrentTimespan().Middle();
|
|
mouseDownData.mouseIsDownForDragging = true;
|
|
canvas()->setCursor(Qt::ClosedHandCursor);
|
|
SelectTransaction(mouseEvent->x(), mouseEvent->y());
|
|
}
|
|
return true;
|
|
}
|
|
else if(mouseEvent->button() == Qt::RightButton)
|
|
{
|
|
openContextMenu(this->canvas()->mapToGlobal(mouseEvent->pos()),mouseEvent->pos());
|
|
return true;
|
|
}
|
|
break;
|
|
}
|
|
case QEvent::MouseButtonRelease:
|
|
{
|
|
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
|
|
|
|
if(mouseEvent->button() == Qt::LeftButton)
|
|
{
|
|
if(mouseDownData.mouseIsDownForDragging)
|
|
{
|
|
mouseDownData.mouseIsDownForDragging = false;
|
|
canvas()->setCursor(Qt::ArrowCursor);
|
|
return true;
|
|
}
|
|
else if(mouseDownData.mouseIsDownForZooming)
|
|
{
|
|
exitZoomMode();
|
|
traceTime newCenter = mouseDownData.zoomSpan.Middle();
|
|
setZoomLevel(mouseDownData.zoomSpan.timeCovered());
|
|
navigator->navigateToTime(newCenter);
|
|
replot();
|
|
return true;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case QEvent::MouseMove:
|
|
{
|
|
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
|
|
|
|
if(mouseDownData.mouseIsDownForDragging)
|
|
{
|
|
traceTime deltaTime = invTransform(xBottom, mouseDownData.mouseDownX) - invTransform(xBottom, mouseEvent->x());
|
|
navigator->navigateToTime(mouseDownData.mouseDownTime + deltaTime);
|
|
return true;
|
|
}
|
|
else if(mouseDownData.mouseIsDownForZooming)
|
|
{
|
|
mouseDownData.zoomSpan.setEnd(alignToClk(invTransform(xBottom, mouseEvent->x()),navigator->GeneralTraceInfo().clkPeriod));
|
|
if(mouseDownData.zoomSpan.Begin() < mouseDownData.zoomSpan.End())
|
|
zoomZone->setInterval(mouseDownData.zoomSpan.Begin(),mouseDownData.zoomSpan.End());
|
|
else
|
|
zoomZone->setInterval(mouseDownData.zoomSpan.End(),mouseDownData.zoomSpan.Begin());
|
|
|
|
replot();
|
|
}
|
|
break;
|
|
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void TracePlot::SelectTransaction(int x, int y)
|
|
{
|
|
double yVal = invTransform(yLeft, y);
|
|
traceTime time = invTransform(xBottom, x);
|
|
vector<shared_ptr<Transaction>> selectedTransactions = tracePlotItem->getSelectedTransactions(time,yVal);
|
|
if(selectedTransactions.size() > 0)
|
|
{
|
|
if(!keyPressData.ctrlPressed)
|
|
navigator->clearSelectedTransactions();
|
|
navigator->addSelectedTransactions(selectedTransactions);
|
|
}
|
|
}
|
|
|
|
void TracePlot::openContextMenu(const QPoint& pos,const QPoint& mouseDown)
|
|
{
|
|
contextMenuMouseDown = mouseDown;
|
|
contextMenu->exec(pos);
|
|
}
|
|
|
|
|