Merge branch 'work/traceanalyzer_rowmodel' into 'develop'
Introduce a model/view based approach for the TraceSelector See merge request ems/astdm/modeling.dram/dram.sys!324
This commit is contained in:
@@ -305,10 +305,10 @@ void TlmRecorder::prepareSqlStatements()
|
||||
"UPDATE Phases SET PhaseEnd = :end WHERE Transact = :trans AND PhaseName = :name";
|
||||
|
||||
insertGeneralInfoString =
|
||||
"INSERT INTO GeneralInfo VALUES"
|
||||
"(:numberOfTransactions, :end, :numberOfRanks, :numberOfBankGroups, :numberOfBanks, :clk, :unitOfTime, "
|
||||
":mcconfig, :memspec, :traces, :windowSize, :refreshMaxPostponed, :refreshMaxPulledin, :controllerThread, "
|
||||
":maxBufferDepth, :per2BankOffset)";
|
||||
"INSERT INTO GeneralInfo VALUES"
|
||||
"(:numberOfTransactions, :end, :numberOfRanks, :numberOfBankGroups, :numberOfBanks, :clk, :unitOfTime, "
|
||||
":mcconfig, :memspec, :traces, :windowSize, :refreshMaxPostponed, :refreshMaxPulledin, :controllerThread, "
|
||||
":maxBufferDepth, :per2BankOffset, :rowColumnCommandBus)";
|
||||
|
||||
insertCommandLengthsString = "INSERT INTO CommandLengths VALUES"
|
||||
"(:command, :length)";
|
||||
@@ -365,6 +365,16 @@ void TlmRecorder::insertGeneralInfo()
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 15, static_cast<int>(Configuration::getInstance().requestBufferSize));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 16,
|
||||
static_cast<int>(Configuration::getInstance().memSpec->getPer2BankOffset()));
|
||||
|
||||
const auto memoryType = Configuration::getInstance().memSpec->memoryType;
|
||||
bool rowColumnCommandBus = [memoryType]() -> bool {
|
||||
if (memoryType == MemSpec::MemoryType::HBM2)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}();
|
||||
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 17, static_cast<int>(rowColumnCommandBus));
|
||||
executeSqlStatement(insertGeneralInfoStatement);
|
||||
}
|
||||
|
||||
|
||||
@@ -189,7 +189,8 @@ private:
|
||||
" RefreshMaxPulledin INTEGER, \n"
|
||||
" ControllerThread INTEGER, \n"
|
||||
" MaxBufferDepth INTEGER, \n"
|
||||
" Per2BankOffset INTEGER \n"
|
||||
" Per2BankOffset INTEGER, \n"
|
||||
" RowColumnCommandBus BOOL \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE CommandLengths( \n"
|
||||
|
||||
@@ -102,12 +102,10 @@ add_executable(TraceAnalyzer
|
||||
businessObjects/phases/phasedependency.cpp
|
||||
businessObjects/phases/dependencyinfos.cpp
|
||||
presentation/tracedrawingproperties.cpp
|
||||
presentation/util/traceplotline.cpp
|
||||
presentation/util/traceplotlinecache.cpp
|
||||
presentation/util/customlabelscaledraw.cpp
|
||||
presentation/traceselector.cpp
|
||||
businessObjects/configmodels.cpp
|
||||
businessObjects/commentmodel.cpp
|
||||
businessObjects/traceplotlinemodel.cpp
|
||||
simulationdialog.cpp
|
||||
|
||||
selectmetrics.ui
|
||||
|
||||
@@ -278,7 +278,7 @@ QModelIndex MemSpecModel::parent(const QModelIndex &index) const
|
||||
const Node *childNode = static_cast<const Node *>(index.internalPointer());
|
||||
const Node *parentNode = childNode->parent;
|
||||
|
||||
if (!parentNode)
|
||||
if (!parentNode || parentNode == rootNode.get())
|
||||
return QModelIndex();
|
||||
|
||||
return createIndex(parentNode->getRow(), 0, const_cast<Node *>(parentNode));
|
||||
|
||||
@@ -50,7 +50,6 @@ class McConfigModel : public QAbstractTableModel
|
||||
|
||||
public:
|
||||
explicit McConfigModel(const TraceDB &traceFile, QObject *parent = nullptr);
|
||||
~McConfigModel() {}
|
||||
|
||||
protected:
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
@@ -82,7 +81,6 @@ class MemSpecModel : public QAbstractItemModel
|
||||
|
||||
public:
|
||||
explicit MemSpecModel(const TraceDB &traceFile, QObject *parent = nullptr);
|
||||
~MemSpecModel() {}
|
||||
|
||||
protected:
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
@@ -106,7 +104,11 @@ private:
|
||||
{
|
||||
using NodeData = std::pair<QString, QString>;
|
||||
|
||||
Node() {}
|
||||
/**
|
||||
* Constructor only used for the root node that does not contain any data.
|
||||
*/
|
||||
Node() = default;
|
||||
|
||||
Node(NodeData data, const Node *parent) : data(data), parent(parent) {}
|
||||
|
||||
/**
|
||||
|
||||
@@ -62,20 +62,24 @@ struct GeneralInfo
|
||||
uint64_t controllerThread = UINT64_MAX;
|
||||
unsigned int maxBufferDepth = 8;
|
||||
unsigned int per2BankOffset = 1;
|
||||
bool rowColumnCommandBus = false;
|
||||
|
||||
GeneralInfo() = default;
|
||||
GeneralInfo(uint64_t numberOfTransactions, uint64_t numberOfPhases, Timespan span,
|
||||
unsigned int numberOfRanks, unsigned int numberOfBankgroups, unsigned int numberOfBanks,
|
||||
QString description, QString unitOfTime, uint64_t clkPeriod, uint64_t windowSize,
|
||||
unsigned int refreshMaxPostponed, unsigned int refreshMaxPulledin,
|
||||
uint64_t controllerThread, unsigned int maxBufferDepth, unsigned int per2BankOffset) :
|
||||
numberOfTransactions(numberOfTransactions) , numberOfPhases(numberOfPhases), span(span),
|
||||
numberOfRanks(numberOfRanks), numberOfBankGroups(numberOfBankgroups), numberOfBanks(numberOfBanks),
|
||||
banksPerRank(numberOfBanks / numberOfRanks), groupsPerRank(numberOfBankgroups / numberOfRanks),
|
||||
banksPerGroup(numberOfBanks / numberOfBankgroups), description(std::move(description)),
|
||||
unitOfTime(std::move(unitOfTime)), clkPeriod(clkPeriod), windowSize(windowSize),
|
||||
refreshMaxPostponed(refreshMaxPostponed), refreshMaxPulledin(refreshMaxPulledin),
|
||||
controllerThread(controllerThread), maxBufferDepth(maxBufferDepth), per2BankOffset(per2BankOffset) {}
|
||||
GeneralInfo(uint64_t numberOfTransactions, uint64_t numberOfPhases, Timespan span, unsigned int numberOfRanks,
|
||||
unsigned int numberOfBankgroups, unsigned int numberOfBanks, QString description, QString unitOfTime,
|
||||
uint64_t clkPeriod, uint64_t windowSize, unsigned int refreshMaxPostponed,
|
||||
unsigned int refreshMaxPulledin, uint64_t controllerThread, unsigned int maxBufferDepth,
|
||||
unsigned int per2BankOffset, bool rowColumnCommandBus)
|
||||
: numberOfTransactions(numberOfTransactions), numberOfPhases(numberOfPhases), span(span),
|
||||
numberOfRanks(numberOfRanks), numberOfBankGroups(numberOfBankgroups), numberOfBanks(numberOfBanks),
|
||||
banksPerRank(numberOfBanks / numberOfRanks), groupsPerRank(numberOfBankgroups / numberOfRanks),
|
||||
banksPerGroup(numberOfBanks / numberOfBankgroups), description(std::move(description)),
|
||||
unitOfTime(std::move(unitOfTime)), clkPeriod(clkPeriod), windowSize(windowSize),
|
||||
refreshMaxPostponed(refreshMaxPostponed), refreshMaxPulledin(refreshMaxPulledin),
|
||||
controllerThread(controllerThread), maxBufferDepth(maxBufferDepth), per2BankOffset(per2BankOffset),
|
||||
rowColumnCommandBus(rowColumnCommandBus)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif // GENERALINFO_H
|
||||
|
||||
@@ -38,9 +38,10 @@
|
||||
*/
|
||||
|
||||
#include "phase.h"
|
||||
#include "presentation/util/traceplotline.h"
|
||||
#include "presentation/tracedrawing.h"
|
||||
#include "businessObjects/traceplotlinemodel.h"
|
||||
#include "businessObjects/transaction.h"
|
||||
#include "presentation/tracedrawing.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
void Phase::draw(QPainter *painter, const QwtScaleMap &xMap,
|
||||
@@ -64,42 +65,53 @@ void Phase::draw(QPainter *painter, const QwtScaleMap &xMap,
|
||||
painter->setPen(pen);
|
||||
}
|
||||
|
||||
for (auto line : getTracePlotLines(drawingProperties))
|
||||
for (auto yVal : getYVals(drawingProperties))
|
||||
{
|
||||
if (!line->isCollapsed())
|
||||
drawPhaseSymbol(span.Begin(), span.End(), yVal, drawingProperties.drawText, getPhaseSymbol(), painter, xMap,
|
||||
yMap, drawingProperties.textColor);
|
||||
|
||||
if (getGranularity() == Granularity::Bankwise)
|
||||
{
|
||||
drawPhaseSymbol(span.Begin(), span.End(), line->getYVal(),
|
||||
drawingProperties.drawText, getPhaseSymbol(), painter, xMap, yMap, drawingProperties.textColor);
|
||||
|
||||
if (getGranularity() == Granularity::Bankwise)
|
||||
DependencyOptions drawDependenciesOptions = drawingProperties.drawDependenciesOption;
|
||||
if (drawDependenciesOptions.draw == DependencyOption::All ||
|
||||
(drawDependenciesOptions.draw == DependencyOption::Selected && highlight))
|
||||
{
|
||||
|
||||
DependencyOptions drawDependenciesOptions = drawingProperties.drawDependenciesOption;
|
||||
if (drawDependenciesOptions.draw == DependencyOption::All ||
|
||||
(drawDependenciesOptions.draw == DependencyOption::Selected && highlight))
|
||||
{
|
||||
drawPhaseDependencies(span.Begin(), span.End(), line->getYVal(), drawingProperties, painter, xMap,
|
||||
yMap);
|
||||
}
|
||||
drawPhaseDependencies(span.Begin(), span.End(), yVal, drawingProperties, painter, xMap, yMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Timespan span : spansOnCommandBus)
|
||||
{
|
||||
for (auto commandBusLine : drawingProperties.getCommandBusLines())
|
||||
for (const auto &line : drawingProperties.getTracePlotLines())
|
||||
{
|
||||
drawPhaseSymbol(span.Begin(), span.End(), commandBusLine->getYVal(),
|
||||
false, PhaseSymbol::Hexagon, painter, xMap, yMap, drawingProperties.textColor);
|
||||
if (line->data.type == AbstractTracePlotLineModel::RowCommandBusLine)
|
||||
{
|
||||
if (isColumnCommand())
|
||||
continue;
|
||||
}
|
||||
else if (line->data.type == AbstractTracePlotLineModel::ColumnCommandBusLine)
|
||||
{
|
||||
if (!isColumnCommand())
|
||||
continue;
|
||||
}
|
||||
else if (line->data.type != AbstractTracePlotLineModel::CommandBusLine)
|
||||
continue;
|
||||
|
||||
drawPhaseSymbol(span.Begin(), span.End(), line->data.yVal, false, PhaseSymbol::Hexagon, painter, xMap,
|
||||
yMap, drawingProperties.textColor);
|
||||
}
|
||||
}
|
||||
|
||||
if (spanOnDataBus)
|
||||
{
|
||||
for (auto dataBusLine : drawingProperties.getDataBusLines())
|
||||
for (const auto &line : drawingProperties.getTracePlotLines())
|
||||
{
|
||||
drawPhaseSymbol(spanOnDataBus->Begin(), spanOnDataBus->End(), dataBusLine->getYVal(),
|
||||
false, PhaseSymbol::Hexagon, painter, xMap, yMap, drawingProperties.textColor);
|
||||
if (line->data.type != AbstractTracePlotLineModel::DataBusLine)
|
||||
continue;
|
||||
|
||||
drawPhaseSymbol(spanOnDataBus->Begin(), spanOnDataBus->End(), line->data.yVal, false, PhaseSymbol::Hexagon,
|
||||
painter, xMap, yMap, drawingProperties.textColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -175,6 +187,80 @@ void Phase::drawPhaseDependencies(traceTime begin, traceTime end, double y,
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
std::vector<int> Phase::getYVals(const TraceDrawingProperties &drawingProperties) const
|
||||
{
|
||||
std::vector<int> yVals;
|
||||
|
||||
unsigned int transactionRank = transaction.lock()->rank;
|
||||
unsigned int transactionBank = transaction.lock()->bank;
|
||||
|
||||
for (const auto &line : drawingProperties.getTracePlotLines())
|
||||
{
|
||||
if (line->data.type != AbstractTracePlotLineModel::BankLine)
|
||||
continue;
|
||||
|
||||
unsigned int yVal = line->data.yVal;
|
||||
|
||||
unsigned int rank = line->data.rank;
|
||||
unsigned int bank = line->data.bank;
|
||||
|
||||
bool shouldBeDrawn = false;
|
||||
|
||||
switch (getGranularity())
|
||||
{
|
||||
case Granularity::Rankwise:
|
||||
shouldBeDrawn = (transactionRank == rank);
|
||||
break;
|
||||
case Granularity::Groupwise:
|
||||
shouldBeDrawn = (transactionRank == rank) && (transactionBank % drawingProperties.banksPerGroup ==
|
||||
bank % drawingProperties.banksPerGroup);
|
||||
break;
|
||||
case Granularity::Bankwise:
|
||||
shouldBeDrawn = (transactionBank == bank);
|
||||
break;
|
||||
|
||||
case Granularity::TwoBankwise:
|
||||
shouldBeDrawn = (transactionBank == bank) || ((transactionBank + drawingProperties.per2BankOffset) == bank);
|
||||
break;
|
||||
}
|
||||
|
||||
if (shouldBeDrawn)
|
||||
yVals.push_back(yVal);
|
||||
}
|
||||
|
||||
return yVals;
|
||||
}
|
||||
|
||||
std::vector<int> REQ::getYVals(const TraceDrawingProperties &drawingProperties) const
|
||||
{
|
||||
std::vector<int> yVals;
|
||||
|
||||
for (const auto &line : drawingProperties.getTracePlotLines())
|
||||
{
|
||||
if (line->data.type != AbstractTracePlotLineModel::RequestLine)
|
||||
continue;
|
||||
|
||||
yVals.push_back(line->data.yVal);
|
||||
}
|
||||
|
||||
return yVals;
|
||||
}
|
||||
|
||||
std::vector<int> RESP::getYVals(const TraceDrawingProperties &drawingProperties) const
|
||||
{
|
||||
std::vector<int> yVals;
|
||||
|
||||
for (const auto &line : drawingProperties.getTracePlotLines())
|
||||
{
|
||||
if (line->data.type != AbstractTracePlotLineModel::ResponseLine)
|
||||
continue;
|
||||
|
||||
yVals.push_back(line->data.yVal);
|
||||
}
|
||||
|
||||
return yVals;
|
||||
}
|
||||
|
||||
QColor Phase::getColor(const TraceDrawingProperties &drawingProperties) const
|
||||
{
|
||||
switch (drawingProperties.colorGrouping)
|
||||
@@ -199,72 +285,57 @@ bool Phase::isSelected(Timespan timespan, double yVal, const TraceDrawingPropert
|
||||
{
|
||||
if (span.overlaps(timespan))
|
||||
{
|
||||
for (auto line : getTracePlotLines(drawingProperties))
|
||||
{
|
||||
if (!line->isCollapsed() && fabs(yVal - line->getYVal()) <= hexagonHeight / 2)
|
||||
for (auto lineYVal : getYVals(drawingProperties))
|
||||
if (fabs(yVal - lineYVal) <= hexagonHeight / 2)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (spanOnDataBus && spanOnDataBus->overlaps(timespan))
|
||||
{
|
||||
for (auto dataBusLine : drawingProperties.getDataBusLines())
|
||||
{
|
||||
if (fabs(yVal - dataBusLine->getYVal()) <= hexagonHeight)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (const Timespan &span : spansOnCommandBus)
|
||||
for (Timespan span : spansOnCommandBus)
|
||||
{
|
||||
if (span.overlaps(timespan))
|
||||
{
|
||||
for (auto commandBusLine : drawingProperties.getCommandBusLines())
|
||||
for (const auto &line : drawingProperties.getTracePlotLines())
|
||||
{
|
||||
if (fabs(yVal - commandBusLine->getYVal()) <= hexagonHeight)
|
||||
if ((line->data.type != AbstractTracePlotLineModel::CommandBusLine) &&
|
||||
(line->data.type != AbstractTracePlotLineModel::RowCommandBusLine) &&
|
||||
(line->data.type != AbstractTracePlotLineModel::ColumnCommandBusLine))
|
||||
continue;
|
||||
|
||||
if (fabs(yVal - line->data.yVal) <= hexagonHeight / 2)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (spanOnDataBus && spanOnDataBus->overlaps(timespan))
|
||||
{
|
||||
for (const auto &line : drawingProperties.getTracePlotLines())
|
||||
{
|
||||
if (line->data.type != AbstractTracePlotLineModel::DataBusLine)
|
||||
continue;
|
||||
|
||||
if (fabs(yVal - line->data.yVal) <= hexagonHeight / 2)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Phase::isColumnCommand() const
|
||||
{
|
||||
if (dynamic_cast<const RD *>(this) || dynamic_cast<const RDA *>(this) || dynamic_cast<const WR *>(this) ||
|
||||
dynamic_cast<const WRA *>(this))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
Phase::PhaseSymbol Phase::getPhaseSymbol() const
|
||||
{
|
||||
return PhaseSymbol::Hexagon;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<TracePlotLine>> Phase::getTracePlotLines(const TraceDrawingProperties &drawingProperties) const
|
||||
{
|
||||
if (getGranularity() == Granularity::Rankwise)
|
||||
{
|
||||
return drawingProperties.getBankLinesFromRank(transaction.lock()->rank);
|
||||
}
|
||||
else if (getGranularity() == Granularity::Groupwise)
|
||||
{
|
||||
return drawingProperties.getBankLinesGroupwise(transaction.lock()->rank,
|
||||
transaction.lock()->bank % drawingProperties.banksPerGroup);
|
||||
}
|
||||
else if (getGranularity() == Granularity::TwoBankwise)
|
||||
{
|
||||
unsigned int firstGroup = transaction.lock()->bank / drawingProperties.banksPerGroup;
|
||||
unsigned int firstBank = transaction.lock()->bank % drawingProperties.banksPerGroup;
|
||||
unsigned int secondGroup = (transaction.lock()->bank + drawingProperties.per2BankOffset)
|
||||
/ drawingProperties.banksPerGroup;
|
||||
unsigned int secondBank = (transaction.lock()->bank + drawingProperties.per2BankOffset)
|
||||
% drawingProperties.banksPerGroup;
|
||||
return drawingProperties.getBankLinesTwoBankwise(transaction.lock()->rank, firstGroup, firstBank, secondGroup,
|
||||
secondBank);
|
||||
}
|
||||
else // if (getGranularity() == Granularity::Bankwise)
|
||||
{
|
||||
return drawingProperties.getBankLines(transaction.lock()->rank,
|
||||
transaction.lock()->bankgroup % drawingProperties.groupsPerRank,
|
||||
transaction.lock()->bank % drawingProperties.banksPerGroup);
|
||||
}
|
||||
}
|
||||
|
||||
void Phase::addDependency(std::shared_ptr<PhaseDependency> dependency)
|
||||
{
|
||||
mDependencies.push_back(dependency);
|
||||
|
||||
@@ -67,6 +67,7 @@ public:
|
||||
const QRectF &canvasRect, bool highlight,
|
||||
const TraceDrawingProperties &drawingProperties) const;
|
||||
bool isSelected(Timespan timespan, double yVal, const TraceDrawingProperties &drawingproperties) const;
|
||||
bool isColumnCommand() const;
|
||||
const Timespan &Span() const
|
||||
{
|
||||
return span;
|
||||
@@ -97,6 +98,7 @@ protected:
|
||||
virtual QColor getColor(const TraceDrawingProperties &drawingProperties) const;
|
||||
|
||||
virtual QColor getPhaseColor() const = 0;
|
||||
virtual std::vector<int> getYVals(const TraceDrawingProperties &drawingProperties) const;
|
||||
virtual void drawPhaseSymbol(traceTime begin, traceTime end, double y,
|
||||
bool drawtext, PhaseSymbol symbol, QPainter *painter, const QwtScaleMap &xMap,
|
||||
const QwtScaleMap &yMap, QColor textColor) const;
|
||||
@@ -104,8 +106,6 @@ protected:
|
||||
const TraceDrawingProperties &drawingProperties, QPainter *painter,
|
||||
const QwtScaleMap &xMap, const QwtScaleMap &yMap) const;
|
||||
|
||||
virtual std::vector<std::shared_ptr<TracePlotLine>> getTracePlotLines(const TraceDrawingProperties &drawingProperties) const;
|
||||
|
||||
enum class Granularity {Bankwise, TwoBankwise, Groupwise, Rankwise};
|
||||
|
||||
virtual Granularity getGranularity() const
|
||||
@@ -129,11 +129,8 @@ protected:
|
||||
{
|
||||
return "REQ";
|
||||
}
|
||||
std::vector<std::shared_ptr<TracePlotLine>> getTracePlotLines(const TraceDrawingProperties &drawingProperties) const
|
||||
override
|
||||
{
|
||||
return drawingProperties.getRequestLines();
|
||||
}
|
||||
|
||||
std::vector<int> getYVals(const TraceDrawingProperties &drawingProperties) const override;
|
||||
};
|
||||
|
||||
class RESP final : public Phase
|
||||
@@ -149,12 +146,8 @@ protected:
|
||||
{
|
||||
return "RESP";
|
||||
}
|
||||
std::vector<std::shared_ptr<TracePlotLine>> getTracePlotLines(const TraceDrawingProperties &drawingProperties) const
|
||||
override
|
||||
{
|
||||
return drawingProperties.getResponseLines();
|
||||
}
|
||||
|
||||
std::vector<int> getYVals(const TraceDrawingProperties &drawingProperties) const override;
|
||||
};
|
||||
/*
|
||||
class PREB final : public Phase
|
||||
|
||||
@@ -69,13 +69,10 @@ bool PhaseDependency::draw(QPoint &end, const TraceDrawingProperties &drawingPro
|
||||
return false;
|
||||
|
||||
bool drawn = false;
|
||||
for (auto line : mDependency->getTracePlotLines(drawingProperties))
|
||||
for (auto yVal : mDependency->getYVals(drawingProperties))
|
||||
{
|
||||
if (!line->isCollapsed())
|
||||
{
|
||||
mDraw(end, line->getYVal(), drawingProperties, painter, xMap, yMap);
|
||||
drawn = true;
|
||||
}
|
||||
mDraw(end, yVal, drawingProperties, painter, xMap, yMap);
|
||||
drawn = true;
|
||||
}
|
||||
|
||||
return drawn;
|
||||
@@ -129,4 +126,4 @@ void PhaseDependency::mDraw(QPoint &end, double depY, const TraceDrawingProperti
|
||||
|
||||
drawText(painter, mTimeDependency, textPosition, alignment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
633
DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.cpp
Normal file
633
DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.cpp
Normal file
@@ -0,0 +1,633 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Technische Universität 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:
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#include "traceplotlinemodel.h"
|
||||
#include "../presentation/traceplot.h"
|
||||
#include "../presentation/util/customlabelscaledraw.h"
|
||||
|
||||
#include <QItemSelectionModel>
|
||||
#include <QKeyEvent>
|
||||
#include <QMimeData>
|
||||
|
||||
AbstractTracePlotLineModel::AbstractTracePlotLineModel(const GeneralInfo &generalInfo, QObject *parent)
|
||||
: QAbstractItemModel(parent), internalSelectionModel(new QItemSelectionModel(this, this)),
|
||||
rootNode(std::make_shared<Node>()), numberOfRanks(generalInfo.numberOfRanks),
|
||||
groupsPerRank(generalInfo.groupsPerRank), banksPerGroup(generalInfo.banksPerGroup),
|
||||
banksPerRank(generalInfo.banksPerRank), commandBusType(getCommandBusType(generalInfo))
|
||||
{
|
||||
createInitialNodes();
|
||||
}
|
||||
|
||||
AvailableTracePlotLineModel::AvailableTracePlotLineModel(const GeneralInfo &generalInfo, QObject *parent)
|
||||
: AbstractTracePlotLineModel(generalInfo, parent)
|
||||
{
|
||||
}
|
||||
|
||||
SelectedTracePlotLineModel::SelectedTracePlotLineModel(const GeneralInfo &generalInfo, QObject *parent)
|
||||
: AbstractTracePlotLineModel(generalInfo, parent)
|
||||
{
|
||||
}
|
||||
|
||||
void AbstractTracePlotLineModel::addTopLevelNode(std::shared_ptr<Node> &&node)
|
||||
{
|
||||
rootNode->children.push_back(std::move(node));
|
||||
}
|
||||
|
||||
void AbstractTracePlotLineModel::createInitialNodes()
|
||||
{
|
||||
addTopLevelNode(
|
||||
std::unique_ptr<Node>(new Node({LineType::RequestLine, getLabel(LineType::RequestLine)}, rootNode.get())));
|
||||
addTopLevelNode(
|
||||
std::unique_ptr<Node>(new Node({LineType::ResponseLine, getLabel(LineType::ResponseLine)}, rootNode.get())));
|
||||
|
||||
for (unsigned int rank = numberOfRanks; rank--;)
|
||||
addTopLevelNode(createRankGroupNode(rank));
|
||||
|
||||
if (commandBusType == CommandBusType::SingleCommandBus)
|
||||
{
|
||||
addTopLevelNode(std::unique_ptr<Node>(
|
||||
new Node({LineType::CommandBusLine, getLabel(LineType::CommandBusLine)}, rootNode.get())));
|
||||
}
|
||||
else // commandBusType == CommandBusType::RowColumnCommandBus
|
||||
{
|
||||
addTopLevelNode(std::unique_ptr<Node>(
|
||||
new Node({LineType::RowCommandBusLine, getLabel(LineType::RowCommandBusLine)}, rootNode.get())));
|
||||
addTopLevelNode(std::unique_ptr<Node>(
|
||||
new Node({LineType::ColumnCommandBusLine, getLabel(LineType::ColumnCommandBusLine)}, rootNode.get())));
|
||||
}
|
||||
|
||||
addTopLevelNode(
|
||||
std::unique_ptr<Node>(new Node({LineType::DataBusLine, getLabel(LineType::DataBusLine)}, rootNode.get())));
|
||||
}
|
||||
|
||||
std::shared_ptr<AbstractTracePlotLineModel::Node>
|
||||
AbstractTracePlotLineModel::createRankGroupNode(unsigned int rank) const
|
||||
{
|
||||
auto rankGroup = std::unique_ptr<Node>(new Node({LineType::RankGroup, getLabel(rank), rank}, rootNode.get()));
|
||||
|
||||
for (unsigned int group = groupsPerRank; group--;)
|
||||
{
|
||||
for (unsigned int bank = banksPerGroup; bank--;)
|
||||
{
|
||||
unsigned int absoluteRank = rank;
|
||||
unsigned int absoluteGroup = group + rank * groupsPerRank;
|
||||
unsigned int absoluteBank = bank + rank * banksPerRank + group * banksPerGroup;
|
||||
|
||||
auto bankLine = std::unique_ptr<Node>(
|
||||
new Node({LineType::BankLine, getLabel(rank, group, bank), absoluteRank, absoluteGroup, absoluteBank},
|
||||
rankGroup.get()));
|
||||
|
||||
rankGroup->children.push_back(std::move(bankLine));
|
||||
}
|
||||
}
|
||||
|
||||
return rankGroup;
|
||||
}
|
||||
|
||||
int AbstractTracePlotLineModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.column() > 0)
|
||||
return 0;
|
||||
|
||||
const Node *parentNode;
|
||||
|
||||
if (!parent.isValid())
|
||||
parentNode = rootNode.get();
|
||||
else
|
||||
parentNode = static_cast<const Node *>(parent.internalPointer());
|
||||
|
||||
return parentNode->childCount();
|
||||
}
|
||||
|
||||
int AbstractTracePlotLineModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
QVariant AbstractTracePlotLineModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
auto *node = static_cast<const Node *>(index.internalPointer());
|
||||
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
return node->data.label;
|
||||
|
||||
case Role::TypeRole:
|
||||
return QVariant::fromValue(node->data.type);
|
||||
|
||||
case Role::CollapsedRole:
|
||||
return node->data.collapsed;
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool SelectedTracePlotLineModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (!index.isValid())
|
||||
return false;
|
||||
|
||||
auto *node = static_cast<Node *>(index.internalPointer());
|
||||
|
||||
switch (role)
|
||||
{
|
||||
case Role::CollapsedRole:
|
||||
node->data.collapsed = value.toBool();
|
||||
emit dataChanged(index, index, {role});
|
||||
return true;
|
||||
|
||||
case Qt::DisplayRole:
|
||||
case Role::TypeRole:
|
||||
// Not allowed
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QVariant AvailableTracePlotLineModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
if (orientation == Qt::Horizontal && section == 0)
|
||||
return "Available Items";
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant SelectedTracePlotLineModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
if (orientation == Qt::Horizontal && section == 0)
|
||||
{
|
||||
return "Selected Items";
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QModelIndex AbstractTracePlotLineModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
if (!hasIndex(row, column, parent))
|
||||
return QModelIndex();
|
||||
|
||||
const Node *parentNode;
|
||||
|
||||
if (!parent.isValid())
|
||||
parentNode = rootNode.get();
|
||||
else
|
||||
parentNode = static_cast<const Node *>(parent.internalPointer());
|
||||
|
||||
const Node *node = parentNode->children[row].get();
|
||||
|
||||
return createIndex(row, column, const_cast<Node *>(node));
|
||||
}
|
||||
|
||||
QModelIndex AbstractTracePlotLineModel::parent(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
const Node *childNode = static_cast<const Node *>(index.internalPointer());
|
||||
const Node *parentNode = childNode->parent;
|
||||
|
||||
if (!parentNode || parentNode == rootNode.get())
|
||||
return QModelIndex();
|
||||
|
||||
return createIndex(parentNode->getRow(), 0, const_cast<Node *>(parentNode));
|
||||
}
|
||||
|
||||
void SelectedTracePlotLineModel::recreateCollapseButtons(TracePlot *tracePlot,
|
||||
CustomLabelScaleDraw *customLabelScaleDraw)
|
||||
{
|
||||
// Remove old buttons
|
||||
for (auto button : collapseButtons)
|
||||
{
|
||||
button->hide();
|
||||
button->deleteLater();
|
||||
}
|
||||
|
||||
collapseButtons.clear();
|
||||
|
||||
for (const auto &node : rootNode->children)
|
||||
{
|
||||
if (node->data.type != LineType::RankGroup)
|
||||
continue;
|
||||
|
||||
QPushButton *collapseButton = new QPushButton(tracePlot);
|
||||
|
||||
unsigned int yVal = [node]()
|
||||
{
|
||||
if (node->data.collapsed)
|
||||
return node->data.yVal;
|
||||
else
|
||||
return node->children.at(0)->data.yVal;
|
||||
}();
|
||||
bool isCollapsed = node->data.collapsed;
|
||||
QModelIndex nodeIndex = index(node->getRow(), 0);
|
||||
|
||||
auto repositionButton = [=]()
|
||||
{
|
||||
QPointF point = tracePlot->axisScaleDraw(QwtPlot::yLeft)->labelPosition(yVal);
|
||||
collapseButton->setGeometry(point.x(), point.y() - 4, 25, 25);
|
||||
};
|
||||
repositionButton();
|
||||
|
||||
auto updateLabel = [=]() { collapseButton->setText(isCollapsed ? "+" : "-"); };
|
||||
updateLabel();
|
||||
|
||||
auto toggleCollapsed = [=]()
|
||||
{
|
||||
setData(nodeIndex, !isCollapsed, Role::CollapsedRole);
|
||||
|
||||
recreateCollapseButtons(tracePlot, customLabelScaleDraw);
|
||||
};
|
||||
|
||||
// Important: The context of the connection is `collapseButton` as it should be disconnected when the button
|
||||
// ceases to exist.
|
||||
connect(customLabelScaleDraw, &CustomLabelScaleDraw::scaleRedraw, collapseButton, repositionButton);
|
||||
connect(collapseButton, &QPushButton::pressed, this, toggleCollapsed);
|
||||
connect(collapseButton, &QPushButton::pressed, tracePlot, &TracePlot::recreateCollapseButtons);
|
||||
|
||||
collapseButton->show();
|
||||
collapseButtons.push_back(collapseButton);
|
||||
}
|
||||
}
|
||||
|
||||
int AbstractTracePlotLineModel::Node::getRow() const
|
||||
{
|
||||
if (!parent)
|
||||
return 0;
|
||||
|
||||
const auto &siblings = parent->children;
|
||||
const auto siblingsIt = std::find_if(siblings.begin(), siblings.end(),
|
||||
[this](const std::shared_ptr<Node> &node) { return node.get() == this; });
|
||||
|
||||
Q_ASSERT(siblingsIt != siblings.end());
|
||||
|
||||
return std::distance(siblings.begin(), siblingsIt);
|
||||
}
|
||||
|
||||
std::shared_ptr<AbstractTracePlotLineModel::Node> AbstractTracePlotLineModel::Node::cloneNode(const Node *node,
|
||||
const Node *parent)
|
||||
{
|
||||
std::shared_ptr<Node> clonedNode = std::make_shared<Node>(node->data, parent);
|
||||
|
||||
for (const auto &child : node->children)
|
||||
clonedNode->children.push_back(cloneNode(child.get(), clonedNode.get()));
|
||||
|
||||
return clonedNode;
|
||||
}
|
||||
|
||||
QString AbstractTracePlotLineModel::getLabel(LineType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case LineType::RequestLine:
|
||||
return "REQ";
|
||||
case LineType::ResponseLine:
|
||||
return "RESP";
|
||||
case LineType::CommandBusLine:
|
||||
return "Command Bus";
|
||||
case LineType::RowCommandBusLine:
|
||||
return "Command Bus [R]";
|
||||
case LineType::ColumnCommandBusLine:
|
||||
return "Command Bus [C]";
|
||||
case LineType::DataBusLine:
|
||||
return "Data Bus";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
QString AbstractTracePlotLineModel::getLabel(unsigned int rank)
|
||||
{
|
||||
return "RA" + QString::number(rank);
|
||||
}
|
||||
|
||||
QString AbstractTracePlotLineModel::getLabel(unsigned int rank, unsigned int group, unsigned int bank)
|
||||
{
|
||||
return "RA" + QString::number(rank) + " BG" + QString::number(group) + " BA" + QString::number(bank);
|
||||
}
|
||||
|
||||
AbstractTracePlotLineModel::CommandBusType AbstractTracePlotLineModel::getCommandBusType(const GeneralInfo &generalInfo)
|
||||
{
|
||||
if (generalInfo.rowColumnCommandBus)
|
||||
return CommandBusType::RowColumnCommandBus;
|
||||
else
|
||||
return CommandBusType::SingleCommandBus;
|
||||
}
|
||||
|
||||
bool SelectedTracePlotLineModel::removeRows(int row, int count, const QModelIndex &parent)
|
||||
{
|
||||
if (parent != QModelIndex())
|
||||
return false;
|
||||
|
||||
// Note: beginRemoveRows requires [first, last], but erase requires [first, last)
|
||||
beginRemoveRows(QModelIndex(), row, row + count - 1);
|
||||
rootNode->children.erase(rootNode->children.begin() + row, rootNode->children.begin() + row + count);
|
||||
endRemoveRows();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AvailableTracePlotLineModel::itemsDoubleClicked(const QModelIndex &index)
|
||||
{
|
||||
QModelIndexList indexList({index});
|
||||
|
||||
emit returnPressed(indexList);
|
||||
}
|
||||
|
||||
void SelectedTracePlotLineModel::itemsDoubleClicked(const QModelIndex &index)
|
||||
{
|
||||
if (index.parent() != QModelIndex())
|
||||
return;
|
||||
|
||||
removeRow(index.row(), QModelIndex());
|
||||
}
|
||||
|
||||
bool AvailableTracePlotLineModel::eventFilter(QObject *object, QEvent *event)
|
||||
{
|
||||
Q_UNUSED(object)
|
||||
|
||||
if (event->type() == QEvent::KeyPress)
|
||||
{
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
||||
|
||||
if (keyEvent->key() == Qt::Key_Return)
|
||||
{
|
||||
const QModelIndexList indexes = internalSelectionModel->selectedRows();
|
||||
|
||||
emit returnPressed(indexes);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SelectedTracePlotLineModel::eventFilter(QObject *object, QEvent *event)
|
||||
{
|
||||
Q_UNUSED(object)
|
||||
|
||||
if (event->type() == QEvent::KeyPress)
|
||||
{
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
||||
|
||||
if (keyEvent->key() == Qt::Key_Delete)
|
||||
{
|
||||
// Note: This implementation requires the selection to be contiguous
|
||||
|
||||
const QModelIndexList indexes = internalSelectionModel->selectedRows();
|
||||
|
||||
if (indexes.count() == 0)
|
||||
return true;
|
||||
|
||||
for (const auto &index : indexes)
|
||||
{
|
||||
// Only remove toplevel indexes
|
||||
if (index.parent() != QModelIndex())
|
||||
return true;
|
||||
}
|
||||
|
||||
removeRows(indexes.at(0).row(), indexes.size(), QModelIndex());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void SelectedTracePlotLineModel::addIndexesFromAvailableModel(const QModelIndexList &indexes)
|
||||
{
|
||||
for (const auto &index : indexes)
|
||||
{
|
||||
auto node = static_cast<const Node *>(index.internalPointer());
|
||||
auto clonedNode = Node::cloneNode(node, rootNode.get());
|
||||
|
||||
beginInsertRows(QModelIndex(), rootNode->children.size(), rootNode->children.size());
|
||||
addTopLevelNode(std::move(clonedNode));
|
||||
endInsertRows();
|
||||
}
|
||||
}
|
||||
|
||||
QItemSelectionModel *AbstractTracePlotLineModel::selectionModel() const
|
||||
{
|
||||
return internalSelectionModel;
|
||||
}
|
||||
|
||||
QStringList AbstractTracePlotLineModel::mimeTypes() const
|
||||
{
|
||||
QStringList types = QAbstractItemModel::mimeTypes();
|
||||
types << TRACELINE_MIMETYPE;
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
QMimeData *AbstractTracePlotLineModel::mimeData(const QModelIndexList &indexes) const
|
||||
{
|
||||
QByteArray traceLineData;
|
||||
QDataStream dataStream(&traceLineData, QIODevice::WriteOnly);
|
||||
|
||||
for (const auto &index : indexes)
|
||||
{
|
||||
const Node *node = static_cast<const Node *>(index.internalPointer());
|
||||
|
||||
dataStream << node->data.type << node->data.label << node->data.rank << node->data.group << node->data.bank
|
||||
<< node->data.collapsed;
|
||||
}
|
||||
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
mimeData->setData(TRACELINE_MIMETYPE, traceLineData);
|
||||
|
||||
return mimeData;
|
||||
}
|
||||
|
||||
bool AbstractTracePlotLineModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
|
||||
const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(action);
|
||||
Q_UNUSED(row);
|
||||
Q_UNUSED(parent);
|
||||
|
||||
if (!data->hasFormat(TRACELINE_MIMETYPE))
|
||||
return false;
|
||||
|
||||
if (column > 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AbstractTracePlotLineModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
|
||||
const QModelIndex &parent)
|
||||
{
|
||||
if (!canDropMimeData(data, action, row, column, parent))
|
||||
return false;
|
||||
|
||||
if (action == Qt::IgnoreAction)
|
||||
return true;
|
||||
|
||||
bool dropHandled = false;
|
||||
|
||||
int beginRow;
|
||||
|
||||
if (row != -1)
|
||||
beginRow = row;
|
||||
else
|
||||
beginRow = rowCount(QModelIndex());
|
||||
|
||||
if (action == Qt::CopyAction || action == Qt::MoveAction)
|
||||
{
|
||||
dropHandled = true;
|
||||
|
||||
QByteArray traceLineData = data->data(TRACELINE_MIMETYPE);
|
||||
QDataStream dataStream(&traceLineData, QIODevice::ReadOnly);
|
||||
|
||||
std::vector<std::shared_ptr<Node>> droppedNodes;
|
||||
|
||||
while (!dataStream.atEnd())
|
||||
{
|
||||
LineType type;
|
||||
QString label;
|
||||
unsigned int rank, group, bank;
|
||||
bool isCollapsed;
|
||||
|
||||
dataStream >> type >> label >> rank >> group >> bank >> isCollapsed;
|
||||
|
||||
std::shared_ptr<Node> node;
|
||||
|
||||
if (type == LineType::BankLine)
|
||||
node = std::make_shared<Node>(Node::NodeData{type, label, rank, group, bank}, rootNode.get());
|
||||
else if (type == LineType::RankGroup)
|
||||
node = createRankGroupNode(rank);
|
||||
else
|
||||
node = std::make_shared<Node>(Node::NodeData{type, label}, rootNode.get());
|
||||
|
||||
if (node->data.type == RankGroup)
|
||||
node->data.collapsed = isCollapsed;
|
||||
|
||||
droppedNodes.push_back(std::move(node));
|
||||
}
|
||||
|
||||
// Note: beginRemoveRows requires [first, last]
|
||||
beginInsertRows(QModelIndex(), beginRow, beginRow + droppedNodes.size() - 1);
|
||||
rootNode->children.insert(rootNode->children.begin() + beginRow, std::make_move_iterator(droppedNodes.begin()),
|
||||
std::make_move_iterator(droppedNodes.end()));
|
||||
endInsertRows();
|
||||
}
|
||||
else
|
||||
{
|
||||
dropHandled = QAbstractItemModel::dropMimeData(data, action, row, column, parent);
|
||||
}
|
||||
|
||||
return dropHandled;
|
||||
}
|
||||
|
||||
Qt::DropActions AbstractTracePlotLineModel::supportedDropActions() const
|
||||
{
|
||||
return (Qt::MoveAction | Qt::CopyAction);
|
||||
}
|
||||
|
||||
Qt::ItemFlags AbstractTracePlotLineModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
Qt::ItemFlags defaultFlags = QAbstractItemModel::flags(index);
|
||||
|
||||
if (index.isValid())
|
||||
return Qt::ItemIsDragEnabled | defaultFlags;
|
||||
else
|
||||
return Qt::ItemIsDropEnabled | defaultFlags;
|
||||
}
|
||||
|
||||
std::shared_ptr<AbstractTracePlotLineModel::Node> SelectedTracePlotLineModel::getClonedRootNode()
|
||||
{
|
||||
return Node::cloneNode(rootNode.get(), nullptr);
|
||||
}
|
||||
|
||||
void SelectedTracePlotLineModel::setRootNode(std::shared_ptr<AbstractTracePlotLineModel::Node> node)
|
||||
{
|
||||
removeRows(0, rootNode->childCount(), QModelIndex());
|
||||
|
||||
beginInsertRows(QModelIndex(), 0, node->childCount() - 1);
|
||||
rootNode = std::move(node);
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
TracePlotLineDataSource::TracePlotLineDataSource(SelectedTracePlotLineModel *selectedModel, QObject *parent)
|
||||
: selectedModel(selectedModel)
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
|
||||
updateModel();
|
||||
}
|
||||
|
||||
void TracePlotLineDataSource::updateModel()
|
||||
{
|
||||
entries.clear();
|
||||
|
||||
std::function<void(std::shared_ptr<AbstractTracePlotLineModel::Node> & parent)> addNodes;
|
||||
addNodes = [=, &addNodes](std::shared_ptr<AbstractTracePlotLineModel::Node> &parent)
|
||||
{
|
||||
for (auto &childNode : parent->children)
|
||||
{
|
||||
if (childNode->data.type == AbstractTracePlotLineModel::RankGroup && !childNode->data.collapsed)
|
||||
{
|
||||
addNodes(childNode);
|
||||
continue; // Don't add the parent node itself when not collapsed.
|
||||
}
|
||||
entries.push_back(childNode);
|
||||
}
|
||||
};
|
||||
|
||||
addNodes(selectedModel->rootNode);
|
||||
|
||||
emit modelChanged();
|
||||
}
|
||||
270
DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.h
Normal file
270
DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.h
Normal file
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Technische Universität 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:
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#ifndef TRACEPLOTLINEMODEL_H
|
||||
#define TRACEPLOTLINEMODEL_H
|
||||
|
||||
#include "generalinfo.h"
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QPushButton>
|
||||
#include <memory>
|
||||
|
||||
class TracePlot;
|
||||
class CustomLabelScaleDraw;
|
||||
class QItemSelectionModel;
|
||||
|
||||
class AbstractTracePlotLineModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AbstractTracePlotLineModel(const GeneralInfo &generalInfo, QObject *parent = nullptr);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
|
||||
QModelIndex parent(const QModelIndex &index) const override;
|
||||
|
||||
QItemSelectionModel *selectionModel() const;
|
||||
|
||||
enum Role
|
||||
{
|
||||
TypeRole = Qt::UserRole + 1,
|
||||
CollapsedRole
|
||||
};
|
||||
Q_ENUM(Role)
|
||||
|
||||
enum LineType
|
||||
{
|
||||
RequestLine,
|
||||
ResponseLine,
|
||||
CommandBusLine,
|
||||
RowCommandBusLine,
|
||||
ColumnCommandBusLine,
|
||||
DataBusLine,
|
||||
RankGroup,
|
||||
BankLine
|
||||
};
|
||||
Q_ENUM(LineType)
|
||||
|
||||
struct Node
|
||||
{
|
||||
struct NodeData
|
||||
{
|
||||
NodeData() = default;
|
||||
|
||||
NodeData(LineType type, const QString &label) : type(type), label(label)
|
||||
{
|
||||
}
|
||||
|
||||
NodeData(LineType type, const QString &label, unsigned int rank) : type(type), label(label), rank(rank)
|
||||
{
|
||||
}
|
||||
|
||||
NodeData(LineType type, const QString &label, unsigned int rank, unsigned int group, unsigned int bank)
|
||||
: type(type), label(label), rank(rank), group(group), bank(bank)
|
||||
{
|
||||
}
|
||||
|
||||
LineType type;
|
||||
QString label;
|
||||
unsigned int yVal = 0;
|
||||
|
||||
/**
|
||||
* Used to store the collapsed state in the traceplot.
|
||||
* The value has only an effect when the type is Type::RankGroup.
|
||||
*/
|
||||
bool collapsed = true;
|
||||
|
||||
/**
|
||||
* Only used when the type is Type::BankLine.
|
||||
* (Absolute numbering)
|
||||
*/
|
||||
unsigned int rank = 0, group = 0, bank = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor only used for the root node that does not contain any data.
|
||||
*/
|
||||
Node() = default;
|
||||
|
||||
Node(NodeData data, const Node *parent) : data(data), parent(parent)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the row relative to its parent.
|
||||
*/
|
||||
int getRow() const;
|
||||
int childCount() const
|
||||
{
|
||||
return children.size();
|
||||
}
|
||||
|
||||
static std::shared_ptr<Node> cloneNode(const Node *node, const Node *parent);
|
||||
|
||||
NodeData data;
|
||||
|
||||
const Node *parent = nullptr;
|
||||
std::vector<std::shared_ptr<Node>> children;
|
||||
};
|
||||
|
||||
protected:
|
||||
enum class CommandBusType
|
||||
{
|
||||
SingleCommandBus,
|
||||
RowColumnCommandBus
|
||||
};
|
||||
|
||||
QStringList mimeTypes() const override;
|
||||
QMimeData *mimeData(const QModelIndexList &indexes) const override;
|
||||
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
|
||||
const QModelIndex &parent) override;
|
||||
bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
|
||||
const QModelIndex &parent) const override;
|
||||
Qt::DropActions supportedDropActions() const override;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
|
||||
void addTopLevelNode(std::shared_ptr<Node> &&node);
|
||||
void createInitialNodes();
|
||||
std::shared_ptr<Node> createRankGroupNode(unsigned int rank) const;
|
||||
|
||||
static QString getLabel(LineType type);
|
||||
static QString getLabel(unsigned int rank);
|
||||
static QString getLabel(unsigned int rank, unsigned int group, unsigned int bank);
|
||||
|
||||
static CommandBusType getCommandBusType(const GeneralInfo &generalInfo);
|
||||
|
||||
static constexpr auto TRACELINE_MIMETYPE = "application/x-tracelinedata";
|
||||
|
||||
QItemSelectionModel *const internalSelectionModel;
|
||||
|
||||
std::shared_ptr<Node> rootNode;
|
||||
|
||||
const unsigned int numberOfRanks;
|
||||
const unsigned int groupsPerRank;
|
||||
const unsigned int banksPerGroup;
|
||||
const unsigned int banksPerRank;
|
||||
|
||||
const CommandBusType commandBusType;
|
||||
};
|
||||
|
||||
class AvailableTracePlotLineModel : public AbstractTracePlotLineModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AvailableTracePlotLineModel(const GeneralInfo &generalInfo, QObject *parent = nullptr);
|
||||
|
||||
public Q_SLOTS:
|
||||
void itemsDoubleClicked(const QModelIndex &index);
|
||||
|
||||
Q_SIGNALS:
|
||||
void returnPressed(const QModelIndexList &indexes);
|
||||
|
||||
protected:
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
bool eventFilter(QObject *object, QEvent *event) override;
|
||||
};
|
||||
|
||||
class SelectedTracePlotLineModel : public AbstractTracePlotLineModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SelectedTracePlotLineModel(const GeneralInfo &generalInfo, QObject *parent = nullptr);
|
||||
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||
|
||||
void recreateCollapseButtons(TracePlot *tracePlot, CustomLabelScaleDraw *customLabelScaleDraw);
|
||||
|
||||
std::shared_ptr<Node> getClonedRootNode();
|
||||
void setRootNode(std::shared_ptr<Node> node);
|
||||
|
||||
public Q_SLOTS:
|
||||
void itemsDoubleClicked(const QModelIndex &index);
|
||||
|
||||
void addIndexesFromAvailableModel(const QModelIndexList &indexes);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *object, QEvent *event) override;
|
||||
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||
|
||||
private:
|
||||
std::vector<QPushButton *> collapseButtons;
|
||||
|
||||
friend class TracePlotLineDataSource;
|
||||
};
|
||||
|
||||
/*
|
||||
* Simple list that is the true source for the traceplot.
|
||||
*/
|
||||
class TracePlotLineDataSource : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using TracePlotLine = AbstractTracePlotLineModel::Node;
|
||||
|
||||
explicit TracePlotLineDataSource(SelectedTracePlotLineModel *selectedModel, QObject *parent = nullptr);
|
||||
|
||||
SelectedTracePlotLineModel *getSelectedModel() const
|
||||
{
|
||||
return selectedModel;
|
||||
};
|
||||
std::vector<std::shared_ptr<TracePlotLine>> &getTracePlotLines()
|
||||
{
|
||||
return entries;
|
||||
}
|
||||
|
||||
public Q_SLOTS:
|
||||
void updateModel();
|
||||
|
||||
Q_SIGNALS:
|
||||
void modelChanged();
|
||||
|
||||
private:
|
||||
SelectedTracePlotLineModel *selectedModel;
|
||||
|
||||
std::vector<std::shared_ptr<TracePlotLine>> entries;
|
||||
};
|
||||
|
||||
#endif // TRACEPLOTLINEMODEL_H
|
||||
@@ -316,6 +316,8 @@ GeneralInfo TraceDB::getGeneralInfoFromDB()
|
||||
unsigned maxBufferDepth = parameter.isValid() ? parameter.toUInt() : 8;
|
||||
parameter = getParameterFromTable("Per2BankOffset", "GeneralInfo");
|
||||
unsigned per2BankOffset = parameter.isValid() ? parameter.toUInt() : 1;
|
||||
parameter = getParameterFromTable("RowColumnCommandBus", "GeneralInfo");
|
||||
bool rowColumnCommandBus = parameter.isValid() ? parameter.toBool() : false;
|
||||
|
||||
uint64_t numberOfPhases = getNumberOfPhases();
|
||||
|
||||
@@ -327,9 +329,12 @@ GeneralInfo TraceDB::getGeneralInfoFromDB()
|
||||
description += "Length of trace: " + prettyFormatTime(traceEnd) + "\n";
|
||||
description += "Window size: " + QString::number(windowSize) + "\n";
|
||||
|
||||
return {numberOfTransactions, numberOfPhases, Timespan(0, traceEnd), numberOfRanks,
|
||||
numberOfBankGroups, numberOfBanks, description, unitOfTime, clkPeriod, windowSize,
|
||||
refreshMaxPostponed, refreshMaxPulledin, controllerThread, maxBufferDepth, per2BankOffset};
|
||||
return {numberOfTransactions, numberOfPhases, Timespan(0, traceEnd),
|
||||
numberOfRanks, numberOfBankGroups, numberOfBanks,
|
||||
description, unitOfTime, clkPeriod,
|
||||
windowSize, refreshMaxPostponed, refreshMaxPulledin,
|
||||
controllerThread, maxBufferDepth, per2BankOffset,
|
||||
rowColumnCommandBus};
|
||||
}
|
||||
|
||||
CommandLengths TraceDB::getCommandLengthsFromDB()
|
||||
|
||||
@@ -33,10 +33,14 @@
|
||||
* Janik Schlemminger
|
||||
* Robert Gernhardt
|
||||
* Matthias Jung
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#ifndef MARKERPLOTITEM_H
|
||||
#define MARKERPLOTITEM_H
|
||||
|
||||
#include "businessObjects/tracetime.h"
|
||||
|
||||
#include <QColor>
|
||||
#include <qwt_plot_item.h>
|
||||
|
||||
|
||||
@@ -35,11 +35,8 @@
|
||||
*/
|
||||
|
||||
#include "tracedrawingproperties.h"
|
||||
#include "../businessObjects/traceplotlinemodel.h"
|
||||
#include "util/customlabelscaledraw.h"
|
||||
#include "traceplot.h"
|
||||
#include "util/traceplotline.h"
|
||||
#include "util/traceplotlinecache.h"
|
||||
#include "traceselector.h"
|
||||
|
||||
TraceDrawingProperties::TraceDrawingProperties(bool drawText, bool drawBorder, DependencyOptions drawDependenciesOption,
|
||||
ColorGrouping colorGrouping)
|
||||
@@ -48,85 +45,11 @@ TraceDrawingProperties::TraceDrawingProperties(bool drawText, bool drawBorder, D
|
||||
{
|
||||
}
|
||||
|
||||
TraceDrawingProperties::~TraceDrawingProperties()
|
||||
void TraceDrawingProperties::init(TracePlotLineDataSource *tracePlotLineDataSource)
|
||||
{
|
||||
tracePlotLines->clear();
|
||||
tracePlotLineCache->clearCache();
|
||||
}
|
||||
|
||||
void TraceDrawingProperties::init(std::shared_ptr<TracePlotLineVector> tracePlotLines,
|
||||
std::shared_ptr<TracePlotLineCache> tracePlotLineCache)
|
||||
{
|
||||
this->tracePlotLines = tracePlotLines;
|
||||
this->tracePlotLineCache = tracePlotLineCache;
|
||||
}
|
||||
|
||||
void TraceDrawingProperties::init(std::shared_ptr<TracePlotLineVector> tracePlotLines,
|
||||
std::shared_ptr<TracePlotLineCache> tracePlotLineCache,
|
||||
TracePlot *tracePlot)
|
||||
{
|
||||
this->tracePlotLines = tracePlotLines;
|
||||
this->tracePlotLineCache = tracePlotLineCache;
|
||||
this->tracePlot = tracePlot;
|
||||
}
|
||||
|
||||
void TraceDrawingProperties::updateTracePlotLines(QTreeWidget *treeWidget)
|
||||
{
|
||||
tracePlotLines->clear();
|
||||
tracePlot->getCustomLabelScaleDraw()->clearCache();
|
||||
clearCache();
|
||||
|
||||
for (int i = 0; i < treeWidget->topLevelItemCount(); i++)
|
||||
{
|
||||
auto currentTreeItem = static_cast<TraceSelectorTreeItem *>(treeWidget->topLevelItem(i));
|
||||
|
||||
if (currentTreeItem->type == TraceSelectorTreeItem::Type::RequestLineItem)
|
||||
tracePlotLines->push_back(std::make_shared<TracePlotRequestLine>());
|
||||
else if (currentTreeItem->type == TraceSelectorTreeItem::Type::ResponseLineItem)
|
||||
tracePlotLines->push_back(std::make_shared<TracePlotResponseLine>());
|
||||
else if (currentTreeItem->type == TraceSelectorTreeItem::Type::CommandBusLineItem)
|
||||
tracePlotLines->push_back(std::make_shared<TracePlotCommandBusLine>());
|
||||
else if (currentTreeItem->type == TraceSelectorTreeItem::Type::DataBusLineItem)
|
||||
tracePlotLines->push_back(std::make_shared<TracePlotDataBusLine>());
|
||||
else if (currentTreeItem->type == TraceSelectorTreeItem::Type::BankLineItem)
|
||||
tracePlotLines->push_back(std::make_shared<TracePlotBankLine>(currentTreeItem->rank, currentTreeItem->bankgroup, currentTreeItem->bank));
|
||||
else if (currentTreeItem->type == TraceSelectorTreeItem::Type::RankGroupItem)
|
||||
addRankGroup(currentTreeItem->rank);
|
||||
}
|
||||
this->tracePlotLineDataSource = tracePlotLineDataSource;
|
||||
|
||||
updateLabels();
|
||||
tracePlot->updateScrollbar();
|
||||
|
||||
// This call is needed, otherwise the labels of the axis will not update properly.
|
||||
tracePlot->update();
|
||||
}
|
||||
|
||||
void TraceDrawingProperties::addRankGroup(unsigned int rank)
|
||||
{
|
||||
if (rank >= numberOfRanks)
|
||||
return;
|
||||
|
||||
std::shared_ptr<TracePlotFirstRankLine> firstRankLine;
|
||||
|
||||
for (unsigned int group = groupsPerRank; group--;)
|
||||
{
|
||||
for (unsigned int bank = banksPerGroup; bank--;)
|
||||
{
|
||||
std::shared_ptr<TracePlotBankLine> line;
|
||||
|
||||
if (bank == banksPerGroup - 1 && group == groupsPerRank - 1)
|
||||
{
|
||||
firstRankLine = createFirstRankLine(rank, group, bank);
|
||||
line = firstRankLine;
|
||||
}
|
||||
else
|
||||
{
|
||||
line = std::make_shared<TracePlotBankLine>(rank, group, bank, firstRankLine);
|
||||
}
|
||||
|
||||
tracePlotLines->push_back(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TraceDrawingProperties::updateLabels()
|
||||
@@ -135,61 +58,22 @@ void TraceDrawingProperties::updateLabels()
|
||||
labels->clear();
|
||||
|
||||
// The lowest line starts at the y value of 0.
|
||||
int i = 0;
|
||||
int yVal = 0;
|
||||
|
||||
for (auto it = tracePlotLines->rbegin(); it != tracePlotLines->rend(); it++)
|
||||
auto selectedModel = tracePlotLineDataSource->getSelectedModel();
|
||||
|
||||
for (auto it = tracePlotLineDataSource->getTracePlotLines().rbegin();
|
||||
it != tracePlotLineDataSource->getTracePlotLines().rend(); ++it)
|
||||
{
|
||||
// Don't add collapsed ranks, but always add the first rank line.
|
||||
auto bankLine = std::dynamic_pointer_cast<TracePlotBankLine>(*it);
|
||||
auto firstRankLine = std::dynamic_pointer_cast<TracePlotFirstRankLine>(*it);
|
||||
if (!firstRankLine && bankLine && bankLine->isCollapsed())
|
||||
continue;
|
||||
auto line = *it;
|
||||
|
||||
(*labels)[i] = (*it)->getLabel();
|
||||
labels->operator[](yVal) = line->data.label;
|
||||
line->data.yVal = yVal;
|
||||
|
||||
(*it)->setYVal(i);
|
||||
|
||||
i++;
|
||||
yVal++;
|
||||
}
|
||||
|
||||
Q_EMIT tracePlot->tracePlotLinesChanged();
|
||||
}
|
||||
|
||||
std::shared_ptr<TracePlotFirstRankLine> TraceDrawingProperties::createFirstRankLine(unsigned int rank, unsigned int group,
|
||||
unsigned int bank) const
|
||||
{
|
||||
auto firstRankLine = std::make_shared<TracePlotFirstRankLine>(rank, group, bank, tracePlot);
|
||||
|
||||
QObject::connect(firstRankLine.get(), &TracePlotFirstRankLine::collapsedStateChanged,
|
||||
this, &TraceDrawingProperties::updateLabels);
|
||||
|
||||
QObject::connect(firstRankLine.get(), &TracePlotFirstRankLine::collapsedStateChanged,
|
||||
tracePlot, &TracePlot::updateScrollbar);
|
||||
|
||||
QObject::connect(firstRankLine.get(), &TracePlotFirstRankLine::collapsedStateChanged,
|
||||
tracePlot, &TracePlot::updateToggleCollapsedAction);
|
||||
|
||||
QObject::connect(tracePlot->getCustomLabelScaleDraw(), &CustomLabelScaleDraw::scaleRedraw,
|
||||
firstRankLine.get(), &TracePlotFirstRankLine::updateButtonPosition);
|
||||
|
||||
return firstRankLine;
|
||||
}
|
||||
|
||||
void TraceDrawingProperties::collapseOrExpandAllRanks(ToggleCollapsedAction::CollapseAction collapseAction)
|
||||
{
|
||||
using CollapseAction = ToggleCollapsedAction::CollapseAction;
|
||||
|
||||
for (auto &line : *tracePlotLines)
|
||||
{
|
||||
if (auto firstRankLine = std::dynamic_pointer_cast<TracePlotFirstRankLine>(line))
|
||||
{
|
||||
if ((!firstRankLine->isCollapsed() && collapseAction == CollapseAction::CollapseAllRanks)
|
||||
|| (firstRankLine->isCollapsed() && collapseAction == CollapseAction::ExpandAllRanks))
|
||||
{
|
||||
Q_EMIT firstRankLine->collapseRequested();
|
||||
}
|
||||
}
|
||||
}
|
||||
emit labelsUpdated();
|
||||
}
|
||||
|
||||
std::shared_ptr<QHash<int, QString>> TraceDrawingProperties::getLabels() const
|
||||
@@ -199,104 +83,5 @@ std::shared_ptr<QHash<int, QString>> TraceDrawingProperties::getLabels() const
|
||||
|
||||
unsigned int TraceDrawingProperties::getNumberOfDisplayedLines() const
|
||||
{
|
||||
if (!tracePlotLines)
|
||||
return 0;
|
||||
|
||||
unsigned int max = 0;
|
||||
|
||||
for (auto line : *tracePlotLines)
|
||||
{
|
||||
if (!line->isCollapsed() && max < line->getYVal())
|
||||
max = line->getYVal();
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
unsigned int TraceDrawingProperties::getNumberOfCollapsedRanks() const
|
||||
{
|
||||
if (!tracePlotLines)
|
||||
return 0;
|
||||
|
||||
unsigned int numberOfCollapsedRanks = 0;
|
||||
|
||||
for (auto line : *tracePlotLines)
|
||||
{
|
||||
if (auto firstRankLine = std::dynamic_pointer_cast<TracePlotFirstRankLine>(line))
|
||||
{
|
||||
if (firstRankLine->isCollapsed())
|
||||
numberOfCollapsedRanks++;
|
||||
}
|
||||
}
|
||||
|
||||
return numberOfCollapsedRanks;
|
||||
}
|
||||
|
||||
void TraceDrawingProperties::clearCache() const
|
||||
{
|
||||
tracePlotLineCache->clearCache();
|
||||
}
|
||||
|
||||
TracePlotLineVector TraceDrawingProperties::getRequestLines() const
|
||||
{
|
||||
return tracePlotLineCache->getRequestLines();
|
||||
}
|
||||
|
||||
TracePlotLineVector TraceDrawingProperties::getResponseLines() const
|
||||
{
|
||||
return tracePlotLineCache->getResponseLines();
|
||||
}
|
||||
|
||||
TracePlotLineVector TraceDrawingProperties::getCommandBusLines() const
|
||||
{
|
||||
return tracePlotLineCache->getCommandBusLines();
|
||||
}
|
||||
|
||||
TracePlotLineVector TraceDrawingProperties::getDataBusLines() const
|
||||
{
|
||||
return tracePlotLineCache->getDataBusLines();
|
||||
}
|
||||
|
||||
TracePlotLineVector TraceDrawingProperties::getFirstRankLines(unsigned int rank) const
|
||||
{
|
||||
return tracePlotLineCache->getFirstRankLines(rank);
|
||||
}
|
||||
|
||||
TracePlotLineVector TraceDrawingProperties::getBankLines(unsigned int rank, unsigned int group, unsigned int bank) const
|
||||
{
|
||||
return tracePlotLineCache->getBankLines(rank, group, bank);
|
||||
}
|
||||
|
||||
TracePlotLineVector TraceDrawingProperties::getBankLinesFromGroup(unsigned int rank, unsigned int group) const
|
||||
{
|
||||
return tracePlotLineCache->getBankLinesFromGroup(rank, group);
|
||||
}
|
||||
|
||||
TracePlotLineVector TraceDrawingProperties::getBankLinesGroupwise(unsigned int rank,
|
||||
unsigned int bank) const
|
||||
{
|
||||
auto rankLines = tracePlotLineCache->getBankLinesFromRank(rank);
|
||||
TracePlotLineVector groupwiseLines;
|
||||
|
||||
std::copy_if(rankLines.begin(), rankLines.end(), std::back_inserter(groupwiseLines),
|
||||
[bank](std::shared_ptr<TracePlotLine> line)
|
||||
{ return std::static_pointer_cast<TracePlotBankLine>(line)->bank == bank; });
|
||||
|
||||
return groupwiseLines;
|
||||
}
|
||||
|
||||
TracePlotLineVector TraceDrawingProperties::getBankLinesFromRank(unsigned int rank) const
|
||||
{
|
||||
return tracePlotLineCache->getBankLinesFromRank(rank);
|
||||
}
|
||||
|
||||
TracePlotLineVector TraceDrawingProperties::getBankLinesTwoBankwise(unsigned int rank, unsigned int firstGroup,
|
||||
unsigned int firstBank, unsigned int secondGroup,
|
||||
unsigned int secondBank) const
|
||||
{
|
||||
TracePlotLineVector firstBankLines = tracePlotLineCache->getBankLines(rank, firstGroup, firstBank);
|
||||
TracePlotLineVector secondBankLines = tracePlotLineCache->getBankLines(rank, secondGroup, secondBank);
|
||||
firstBankLines.insert(firstBankLines.end(), secondBankLines.begin(), secondBankLines.end());
|
||||
|
||||
return firstBankLines;
|
||||
return tracePlotLineDataSource->getTracePlotLines().size();
|
||||
}
|
||||
|
||||
@@ -40,17 +40,13 @@
|
||||
#ifndef TRACECOLLECTIONDRAWINGPROPERTIES_H
|
||||
#define TRACECOLLECTIONDRAWINGPROPERTIES_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QColor>
|
||||
#include <map>
|
||||
#include <QHash>
|
||||
#include <QTreeWidget>
|
||||
#include <tuple>
|
||||
#include "businessObjects/traceplotlinemodel.h"
|
||||
#include "tracedrawing.h"
|
||||
#include "util/traceplotline.h"
|
||||
#include "util/togglecollapsedaction.h"
|
||||
#include "traceselector.h"
|
||||
#include <QAbstractProxyModel>
|
||||
#include <QColor>
|
||||
#include <QHash>
|
||||
#include <QString>
|
||||
#include <map>
|
||||
|
||||
enum class ColorGrouping
|
||||
{
|
||||
@@ -60,10 +56,7 @@ enum class ColorGrouping
|
||||
AlphaTransaction
|
||||
};
|
||||
|
||||
class TracePlot;
|
||||
class TracePlotLineCache;
|
||||
|
||||
using TracePlotLineVector = std::vector<std::shared_ptr<TracePlotLine>>;
|
||||
class TracePlotLineDataSource;
|
||||
|
||||
enum class DependencyOption
|
||||
{
|
||||
@@ -71,6 +64,7 @@ enum class DependencyOption
|
||||
Selected,
|
||||
All
|
||||
};
|
||||
|
||||
enum class DependencyTextOption
|
||||
{
|
||||
Enabled,
|
||||
@@ -106,48 +100,26 @@ public:
|
||||
DependencyOptions drawDependenciesOption = {DependencyOption::Disabled,
|
||||
DependencyTextOption::Enabled},
|
||||
ColorGrouping colorGrouping = ColorGrouping::PhaseType);
|
||||
~TraceDrawingProperties();
|
||||
|
||||
void init(std::shared_ptr<TracePlotLineVector> tracePlotLines,
|
||||
std::shared_ptr<TracePlotLineCache> tracePlotLineCache);
|
||||
|
||||
void init(std::shared_ptr<TracePlotLineVector> tracePlotLines,
|
||||
std::shared_ptr<TracePlotLineCache> tracePlotLineCache, TracePlot *tracePlot);
|
||||
void init(TracePlotLineDataSource *tracePlotLineDataSource);
|
||||
void updateLabels();
|
||||
|
||||
unsigned int getNumberOfDisplayedLines() const;
|
||||
unsigned int getNumberOfCollapsedRanks() const;
|
||||
|
||||
TracePlotLineVector getRequestLines() const;
|
||||
TracePlotLineVector getResponseLines() const;
|
||||
TracePlotLineVector getCommandBusLines() const;
|
||||
TracePlotLineVector getDataBusLines() const;
|
||||
TracePlotLineVector getFirstRankLines(unsigned int rank) const;
|
||||
TracePlotLineVector getBankLines(unsigned int rank, unsigned int group, unsigned int bank) const;
|
||||
TracePlotLineVector getBankLinesFromGroup(unsigned int rank, unsigned int group) const;
|
||||
TracePlotLineVector getBankLinesGroupwise(unsigned int rank, unsigned int bank) const;
|
||||
TracePlotLineVector getBankLinesTwoBankwise(unsigned int rank, unsigned int firstGroup,
|
||||
unsigned int firstBank, unsigned int secondGroup,
|
||||
unsigned int secondBank) const;
|
||||
TracePlotLineVector getBankLinesFromRank(unsigned int rank) const;
|
||||
const std::vector<std::shared_ptr<TracePlotLineDataSource::TracePlotLine>> &getTracePlotLines() const
|
||||
{
|
||||
return tracePlotLineDataSource->getTracePlotLines();
|
||||
}
|
||||
|
||||
std::shared_ptr<QHash<int, QString>> getLabels() const;
|
||||
|
||||
void updateTracePlotLines(QTreeWidget *treeWidget);
|
||||
void collapseOrExpandAllRanks(ToggleCollapsedAction::CollapseAction collapseAction);
|
||||
Q_SIGNALS:
|
||||
void labelsUpdated();
|
||||
|
||||
private:
|
||||
void updateLabels();
|
||||
void clearCache() const;
|
||||
void addRankGroup(unsigned int rank);
|
||||
std::shared_ptr<TracePlotFirstRankLine> createFirstRankLine(unsigned int rank, unsigned int group,
|
||||
unsigned int bank) const;
|
||||
|
||||
std::shared_ptr<QHash<int, QString>> labels = std::make_shared<QHash<int, QString>>();
|
||||
|
||||
std::shared_ptr<TracePlotLineVector> tracePlotLines;
|
||||
std::shared_ptr<TracePlotLineCache> tracePlotLineCache;
|
||||
|
||||
TracePlot *tracePlot = nullptr;
|
||||
TracePlotLineDataSource *tracePlotLineDataSource;
|
||||
};
|
||||
|
||||
#endif // TRACECOLLECTIONDRAWINGPROPERTIES_H
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
*/
|
||||
|
||||
#include "tracenavigator.h"
|
||||
#include "util/traceplotlinecache.h"
|
||||
#include "vector"
|
||||
#include "businessObjects/commentmodel.h"
|
||||
#include <QInputDialog>
|
||||
@@ -59,16 +58,8 @@ TraceNavigator::TraceNavigator(QString path, CommentModel *commentModel, QObject
|
||||
QObject::connect(commentModel, &CommentModel::rowsRemoved, this, &TraceNavigator::traceFileModified);
|
||||
|
||||
Transaction::setNumTransactions(GeneralTraceInfo().numberOfTransactions);
|
||||
|
||||
tracePlotLineCache =
|
||||
std::make_shared<TracePlotLineCache>(getTracePlotLines(), GeneralTraceInfo().numberOfRanks,
|
||||
GeneralTraceInfo().groupsPerRank, GeneralTraceInfo().banksPerGroup);
|
||||
}
|
||||
|
||||
TraceNavigator::~TraceNavigator()
|
||||
{
|
||||
tracePlotLines->clear();
|
||||
}
|
||||
|
||||
/* Navigation
|
||||
*
|
||||
@@ -309,16 +300,6 @@ Timespan TraceNavigator::getSpanCoveredBySelectedTransaction()
|
||||
return Timespan(begin, end);
|
||||
}
|
||||
|
||||
std::shared_ptr<TracePlotLineVector> TraceNavigator::getTracePlotLines()
|
||||
{
|
||||
return tracePlotLines;
|
||||
}
|
||||
|
||||
std::shared_ptr<TracePlotLineCache> TraceNavigator::getTracePlotLineCache()
|
||||
{
|
||||
return tracePlotLineCache;
|
||||
}
|
||||
|
||||
const CommentModel *TraceNavigator::getCommentModel() const
|
||||
{
|
||||
return commentModel;
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
#include "businessObjects/transaction.h"
|
||||
#include "memory"
|
||||
|
||||
class TracePlotLineCache;
|
||||
class CommentModel;
|
||||
|
||||
/* Class to navigate through a tracefile
|
||||
@@ -59,7 +58,6 @@ class TraceNavigator : public QObject
|
||||
|
||||
public:
|
||||
TraceNavigator(QString path, CommentModel *commentModel, QObject *parent = 0);
|
||||
~TraceNavigator();
|
||||
|
||||
traceTime CurrentTraceTime() const
|
||||
{
|
||||
@@ -113,9 +111,6 @@ public:
|
||||
void commitChangesToDB();
|
||||
void refreshData();
|
||||
|
||||
std::shared_ptr<TracePlotLineVector> getTracePlotLines();
|
||||
std::shared_ptr<TracePlotLineCache> getTracePlotLineCache();
|
||||
|
||||
const CommentModel *getCommentModel() const;
|
||||
|
||||
bool existChangesToCommit() const;
|
||||
@@ -139,9 +134,6 @@ private:
|
||||
|
||||
void getCommentsFromDB();
|
||||
bool changesToCommitExist;
|
||||
|
||||
std::shared_ptr<TracePlotLineVector> tracePlotLines = std::make_shared<TracePlotLineVector>();
|
||||
std::shared_ptr<TracePlotLineCache> tracePlotLineCache;
|
||||
};
|
||||
|
||||
#endif // TRACENAVIGATOR_H
|
||||
|
||||
@@ -37,33 +37,30 @@
|
||||
* Iron Prando da Silva
|
||||
*/
|
||||
|
||||
#include <qwt_plot_grid.h>
|
||||
#include <QWheelEvent>
|
||||
#include <QMessageBox>
|
||||
#include <QMouseEvent>
|
||||
#include <iostream>
|
||||
#include <QMenu>
|
||||
#include <cmath>
|
||||
#include <QInputDialog>
|
||||
#include <QKeySequence>
|
||||
#include <QFileInfo>
|
||||
#include <QPushButton>
|
||||
#include <qfiledialog.h>
|
||||
#include <iostream>
|
||||
#include <qwt_plot_renderer.h>
|
||||
|
||||
#include "tracePlotMouseLabel.h"
|
||||
#include "traceplot.h"
|
||||
#include "gototimedialog.h"
|
||||
#include "tracedrawing.h"
|
||||
#include "businessObjects/commentmodel.h"
|
||||
#include "util/engineeringScaleDraw.h"
|
||||
#include "businessObjects/traceplotlinemodel.h"
|
||||
#include "gototimedialog.h"
|
||||
#include "tracePlotMouseLabel.h"
|
||||
#include "tracedrawing.h"
|
||||
#include "util/clkgrid.h"
|
||||
#include "util/customlabelscaledraw.h"
|
||||
#include "util/togglecollapsedaction.h"
|
||||
|
||||
using namespace std;
|
||||
#include "util/engineeringScaleDraw.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QInputDialog>
|
||||
#include <QItemSelectionModel>
|
||||
#include <QKeySequence>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QMouseEvent>
|
||||
#include <QPushButton>
|
||||
#include <QWheelEvent>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <qfiledialog.h>
|
||||
#include <qwt_plot_grid.h>
|
||||
#include <qwt_plot_renderer.h>
|
||||
|
||||
TracePlot::TracePlot(QWidget *parent):
|
||||
QwtPlot(parent), isInitialized(false),
|
||||
@@ -73,6 +70,49 @@ TracePlot::TracePlot(QWidget *parent):
|
||||
setUpActions();
|
||||
}
|
||||
|
||||
void TracePlot::init(TraceNavigator *navigator, QScrollBar *scrollBar, TracePlotLineDataSource *tracePlotLineDataSource,
|
||||
CommentModel *commentModel)
|
||||
{
|
||||
Q_ASSERT(isInitialized == false);
|
||||
isInitialized = true;
|
||||
|
||||
this->navigator = navigator;
|
||||
this->scrollBar = scrollBar;
|
||||
this->commentModel = commentModel;
|
||||
this->tracePlotLineDataSource = tracePlotLineDataSource;
|
||||
|
||||
installEventFilter(commentModel);
|
||||
|
||||
QObject::connect(commentModel, &CommentModel::dataChanged, this, &TracePlot::commentsChanged);
|
||||
|
||||
QObject::connect(commentModel, &CommentModel::rowsRemoved, this, &TracePlot::commentsChanged);
|
||||
|
||||
QObject::connect(commentModel->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||
&TracePlot::commentsChanged);
|
||||
|
||||
auto selectedTracePlotLineModel = tracePlotLineDataSource->getSelectedModel();
|
||||
QObject::connect(selectedTracePlotLineModel, &QAbstractItemModel::rowsInserted, this,
|
||||
&TracePlot::recreateCollapseButtons);
|
||||
QObject::connect(selectedTracePlotLineModel, &QAbstractItemModel::rowsRemoved, this,
|
||||
&TracePlot::recreateCollapseButtons);
|
||||
|
||||
connectNavigatorQ_SIGNALS();
|
||||
setUpDrawingProperties();
|
||||
setUpAxis();
|
||||
setUpGrid();
|
||||
setUpTracePlotItem();
|
||||
setUpZoom();
|
||||
setUpQueryEditor();
|
||||
mouseLabel = new TracePlotMouseLabel(this, navigator->GeneralTraceInfo().clkPeriod, this->mouseDownData.zoomSpan);
|
||||
getAndDrawComments();
|
||||
setZoomLevel(1000);
|
||||
|
||||
updateScrollbar();
|
||||
recreateCollapseButtons();
|
||||
dependenciesSubMenu->setEnabled(navigator->TraceFile().checkDependencyTableExists());
|
||||
replot();
|
||||
}
|
||||
|
||||
void TracePlot::setUpActions()
|
||||
{
|
||||
insertComment = new QAction("Insert comment", this);
|
||||
@@ -250,46 +290,6 @@ void TracePlot::setUpContextMenu()
|
||||
contextMenu->addActions({showQueryEditor, insertComment, exportToPdf, toggleCollapsedState});
|
||||
}
|
||||
|
||||
void TracePlot::init(TraceNavigator *navigator, QScrollBar *scrollBar, CommentModel *commentModel)
|
||||
{
|
||||
Q_ASSERT(isInitialized == false);
|
||||
isInitialized = true;
|
||||
|
||||
this->scrollBar = scrollBar;
|
||||
this->commentModel = commentModel;
|
||||
|
||||
installEventFilter(commentModel);
|
||||
|
||||
QObject::connect(commentModel, &CommentModel::dataChanged,
|
||||
this, &TracePlot::commentsChanged);
|
||||
|
||||
QObject::connect(commentModel, &CommentModel::rowsRemoved,
|
||||
this, &TracePlot::commentsChanged);
|
||||
|
||||
QObject::connect(commentModel->selectionModel(), &QItemSelectionModel::selectionChanged,
|
||||
this, &TracePlot::commentsChanged);
|
||||
|
||||
this->navigator = navigator;
|
||||
connectNavigatorQ_SIGNALS();
|
||||
setUpDrawingProperties();
|
||||
setUpAxis();
|
||||
setUpGrid();
|
||||
setUpTracePlotItem();
|
||||
setUpZoom();
|
||||
setUpQueryEditor();
|
||||
mouseLabel = new TracePlotMouseLabel(this,
|
||||
navigator->GeneralTraceInfo().clkPeriod, this->mouseDownData.zoomSpan);
|
||||
getAndDrawComments();
|
||||
setZoomLevel(1000);
|
||||
|
||||
updateScrollbar();
|
||||
|
||||
dependenciesSubMenu->setEnabled(navigator->TraceFile().checkDependencyTableExists());
|
||||
|
||||
replot();
|
||||
}
|
||||
|
||||
|
||||
void TracePlot::connectNavigatorQ_SIGNALS()
|
||||
{
|
||||
QObject::connect(navigator, SIGNAL(currentTraceTimeChanged()), this,
|
||||
@@ -300,7 +300,10 @@ void TracePlot::connectNavigatorQ_SIGNALS()
|
||||
|
||||
void TracePlot::setUpDrawingProperties()
|
||||
{
|
||||
drawingProperties.init(navigator->getTracePlotLines(), navigator->getTracePlotLineCache(), this);
|
||||
connect(this, &TracePlot::tracePlotLinesChanged, &drawingProperties, &TraceDrawingProperties::updateLabels);
|
||||
connect(&drawingProperties, &TraceDrawingProperties::labelsUpdated, this, &TracePlot::updateScrollbar);
|
||||
|
||||
drawingProperties.init(tracePlotLineDataSource);
|
||||
|
||||
drawingProperties.textColor = palette().text().color();
|
||||
drawingProperties.numberOfRanks = navigator->GeneralTraceInfo().numberOfRanks;
|
||||
@@ -353,7 +356,7 @@ void TracePlot::updateScrollbar()
|
||||
// The maximum number of displayed lines determined by the pageStep of the scroll bar.
|
||||
const unsigned int maxDisplayedLines = scrollBar->pageStep();
|
||||
|
||||
const int maximum = drawingProperties.getNumberOfDisplayedLines() - maxDisplayedLines;
|
||||
const int maximum = drawingProperties.getNumberOfDisplayedLines() - maxDisplayedLines - 1;
|
||||
|
||||
if (maximum >= 0)
|
||||
{
|
||||
@@ -368,7 +371,7 @@ void TracePlot::updateScrollbar()
|
||||
|
||||
void TracePlot::verticalScrollbarChanged(int value)
|
||||
{
|
||||
const int yMax = drawingProperties.getNumberOfDisplayedLines();
|
||||
const int yMax = drawingProperties.getNumberOfDisplayedLines() - 1;
|
||||
|
||||
if (scrollBar->isHidden())
|
||||
{
|
||||
@@ -393,21 +396,10 @@ void TracePlot::setUpAxis()
|
||||
setAxisScaleDraw(xBottom, new EngineeringScaleDraw);
|
||||
}
|
||||
|
||||
void TracePlot::updateTracePlotLines(QTreeWidget *treeWidget)
|
||||
{
|
||||
drawingProperties.updateTracePlotLines(treeWidget);
|
||||
}
|
||||
|
||||
void TracePlot::updateToggleCollapsedAction()
|
||||
{
|
||||
unsigned int numberOfCollapsedRanks = drawingProperties.getNumberOfCollapsedRanks();
|
||||
|
||||
if (numberOfCollapsedRanks == drawingProperties.numberOfRanks)
|
||||
toggleCollapsedState->updateCollapsedState(ToggleCollapsedAction::CollapsedState::Collapsed);
|
||||
else if (numberOfCollapsedRanks == 0)
|
||||
toggleCollapsedState->updateCollapsedState(ToggleCollapsedAction::CollapsedState::Expanded);
|
||||
else
|
||||
toggleCollapsedState->updateCollapsedState(ToggleCollapsedAction::CollapsedState::Mixed);
|
||||
ToggleCollapsedAction::CollapsedState state = getCollapsedState();
|
||||
toggleCollapsedState->updateCollapsedState(state);
|
||||
}
|
||||
|
||||
Timespan TracePlot::GetCurrentTimespan()
|
||||
@@ -421,6 +413,71 @@ Timespan TracePlot::GetCurrentTimespan()
|
||||
return span;
|
||||
}
|
||||
|
||||
ToggleCollapsedAction::CollapsedState TracePlot::getCollapsedState() const
|
||||
{
|
||||
using CollapsedState = ToggleCollapsedAction::CollapsedState;
|
||||
|
||||
CollapsedState state = CollapsedState::Collapsed;
|
||||
|
||||
unsigned int notCollapsedCount = 0;
|
||||
unsigned int rankCount = 0;
|
||||
|
||||
auto selectedModel = tracePlotLineDataSource->getSelectedModel();
|
||||
|
||||
for (unsigned int i = 0; i < selectedModel->rowCount(); i++)
|
||||
{
|
||||
QModelIndex index = selectedModel->index(i, 0);
|
||||
auto type = static_cast<AbstractTracePlotLineModel::LineType>(
|
||||
selectedModel->data(index, AbstractTracePlotLineModel::TypeRole).toInt());
|
||||
|
||||
if (type != AbstractTracePlotLineModel::RankGroup)
|
||||
continue;
|
||||
|
||||
bool isCollapsed = selectedModel->data(index, AbstractTracePlotLineModel::CollapsedRole).toBool();
|
||||
if (!isCollapsed)
|
||||
{
|
||||
notCollapsedCount++;
|
||||
state = CollapsedState::Mixed;
|
||||
}
|
||||
|
||||
rankCount++;
|
||||
}
|
||||
|
||||
if (notCollapsedCount == rankCount)
|
||||
state = CollapsedState::Expanded;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void TracePlot::collapseOrExpandAllRanks(ToggleCollapsedAction::CollapseAction collapseAction)
|
||||
{
|
||||
using CollapseAction = ToggleCollapsedAction::CollapseAction;
|
||||
auto selectedModel = tracePlotLineDataSource->getSelectedModel();
|
||||
|
||||
for (unsigned int i = 0; i < selectedModel->rowCount(); i++)
|
||||
{
|
||||
QModelIndex index = selectedModel->index(i, 0);
|
||||
auto type = static_cast<AbstractTracePlotLineModel::LineType>(
|
||||
selectedModel->data(index, AbstractTracePlotLineModel::TypeRole).toInt());
|
||||
|
||||
if (type != AbstractTracePlotLineModel::RankGroup)
|
||||
continue;
|
||||
|
||||
switch (collapseAction)
|
||||
{
|
||||
case CollapseAction::CollapseAllRanks:
|
||||
selectedModel->setData(index, true, AbstractTracePlotLineModel::CollapsedRole);
|
||||
break;
|
||||
|
||||
case CollapseAction::ExpandAllRanks:
|
||||
selectedModel->setData(index, false, AbstractTracePlotLineModel::CollapsedRole);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
recreateCollapseButtons();
|
||||
}
|
||||
|
||||
void TracePlot::getAndDrawComments()
|
||||
{
|
||||
QList<QModelIndex> selectedRows = commentModel->selectionModel()->selectedRows();
|
||||
@@ -507,12 +564,19 @@ void TracePlot::setZoomLevel(traceTime newZoomLevel)
|
||||
drawingProperties.drawText = false;
|
||||
}
|
||||
|
||||
|
||||
/* Q_SLOTS
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
void TracePlot::recreateCollapseButtons()
|
||||
{
|
||||
drawingProperties.updateLabels();
|
||||
|
||||
auto selectedModel = tracePlotLineDataSource->getSelectedModel();
|
||||
selectedModel->recreateCollapseButtons(this, customLabelScaleDraw);
|
||||
}
|
||||
|
||||
void TracePlot::currentTraceTimeChanged()
|
||||
{
|
||||
bool drawDependencies = getDrawingProperties().drawDependenciesOption.draw != DependencyOption::Disabled;
|
||||
@@ -676,7 +740,8 @@ void TracePlot::on_exportToPDF()
|
||||
|
||||
void TracePlot::on_toggleCollapsedState()
|
||||
{
|
||||
drawingProperties.collapseOrExpandAllRanks(toggleCollapsedState->getCollapseAction());
|
||||
collapseOrExpandAllRanks(toggleCollapsedState->getCollapseAction());
|
||||
updateToggleCollapsedAction();
|
||||
}
|
||||
|
||||
/* Keyboard and mouse events
|
||||
@@ -853,5 +918,8 @@ void TracePlot::openContextMenu(const QPoint &pos, const QPoint &mouseDown)
|
||||
if (commentModel->hoveredComment(timespan).isValid())
|
||||
commentModel->openContextMenu();
|
||||
else
|
||||
{
|
||||
updateToggleCollapsedAction();
|
||||
contextMenu->exec(pos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,13 @@
|
||||
|
||||
#ifndef TRACEPLOT_H
|
||||
#define TRACEPLOT_H
|
||||
|
||||
#include "markerplotitem.h"
|
||||
#include "queryeditor.h"
|
||||
#include "tracenavigator.h"
|
||||
#include "traceplotitem.h"
|
||||
#include "util/togglecollapsedaction.h"
|
||||
|
||||
#include <qwt_plot.h>
|
||||
#include <QString>
|
||||
#include <QColor>
|
||||
@@ -49,31 +56,25 @@
|
||||
#include <QScrollBar>
|
||||
#include <QPushButton>
|
||||
#include <qwt_plot_zoneitem.h>
|
||||
#include "traceplotitem.h"
|
||||
#include "tracenavigator.h"
|
||||
#include "queryeditor.h"
|
||||
|
||||
class TracePlotMouseLabel;
|
||||
class CustomLabelScaleDraw;
|
||||
class CommentModel;
|
||||
class TracePlotLineDataSource;
|
||||
|
||||
#include "markerplotitem.h"
|
||||
/* A plot that plots all phases and transactions of a trace file
|
||||
* Y Axis : Bank0,...,Bank7,Trans,CC
|
||||
* X Axis : Time
|
||||
*
|
||||
*/
|
||||
|
||||
class TracePlotMouseLabel;
|
||||
class CustomLabelScaleDraw;
|
||||
class ToggleCollapsedAction;
|
||||
class CommentModel;
|
||||
|
||||
class TracePlot : public QwtPlot
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TracePlot(QWidget *parent = NULL);
|
||||
void init(TraceNavigator *navigator, QScrollBar *scrollBar, CommentModel *commentModel);
|
||||
void init(TraceNavigator *navigator, QScrollBar *scrollBar, TracePlotLineDataSource *tracePlotLineDataSource,
|
||||
CommentModel *commentModel);
|
||||
Timespan GetCurrentTimespan();
|
||||
|
||||
traceTime ZoomLevel() const;
|
||||
@@ -88,7 +89,7 @@ public Q_SLOTS:
|
||||
void commentsChanged();
|
||||
void verticalScrollbarChanged(int value);
|
||||
void updateScrollbar();
|
||||
void updateTracePlotLines(QTreeWidget *treeWidget);
|
||||
void recreateCollapseButtons();
|
||||
void updateToggleCollapsedAction();
|
||||
|
||||
Q_SIGNALS:
|
||||
@@ -128,8 +129,11 @@ private:
|
||||
QMenu *contextMenu;
|
||||
QScrollBar *scrollBar;
|
||||
CustomLabelScaleDraw *customLabelScaleDraw;
|
||||
|
||||
CommentModel *commentModel;
|
||||
|
||||
TracePlotLineDataSource *tracePlotLineDataSource;
|
||||
|
||||
void setUpTracePlotItem();
|
||||
void setUpDrawingProperties();
|
||||
void setUpGrid();
|
||||
@@ -142,6 +146,8 @@ private:
|
||||
void connectNavigatorQ_SIGNALS();
|
||||
|
||||
void getAndDrawComments();
|
||||
ToggleCollapsedAction::CollapsedState getCollapsedState() const;
|
||||
void collapseOrExpandAllRanks(ToggleCollapsedAction::CollapseAction collapseAction);
|
||||
|
||||
/* zooming
|
||||
*
|
||||
|
||||
@@ -36,12 +36,13 @@
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#include <qwt_plot_zoneitem.h>
|
||||
#include <QWheelEvent>
|
||||
#include <QMouseEvent>
|
||||
#include "tracescroller.h"
|
||||
#include "traceplotitem.h"
|
||||
#include "util/engineeringScaleDraw.h"
|
||||
#include <QItemSelectionModel>
|
||||
#include <QMouseEvent>
|
||||
#include <QWheelEvent>
|
||||
#include <qwt_plot_zoneitem.h>
|
||||
|
||||
TraceScroller::TraceScroller(QWidget *parent)
|
||||
: QwtPlot(parent), isInitialized(false),
|
||||
@@ -55,11 +56,14 @@ TraceScroller::TraceScroller(QWidget *parent)
|
||||
canvasClip->attach(this);
|
||||
}
|
||||
|
||||
void TraceScroller::init(TraceNavigator *navigator, TracePlot *tracePlot)
|
||||
void TraceScroller::init(TraceNavigator *navigator, TracePlot *tracePlot,
|
||||
TracePlotLineDataSource *tracePlotLineDataSource)
|
||||
{
|
||||
Q_ASSERT(isInitialized == false);
|
||||
isInitialized = true;
|
||||
|
||||
this->tracePlotLineDataSource = tracePlotLineDataSource;
|
||||
|
||||
this -> navigator = navigator;
|
||||
connectNavigatorQ_SIGNALS();
|
||||
|
||||
@@ -74,6 +78,8 @@ void TraceScroller::init(TraceNavigator *navigator, TracePlot *tracePlot)
|
||||
QObject::connect(commentModel->selectionModel(), &QItemSelectionModel::selectionChanged,
|
||||
this, &TraceScroller::commentsChanged);
|
||||
|
||||
QObject::connect(tracePlotLineDataSource, &TracePlotLineDataSource::modelChanged, this, &TraceScroller::updateAxis);
|
||||
|
||||
setUpDrawingProperties();
|
||||
setUpAxis();
|
||||
setUpTracePlotItem();
|
||||
@@ -104,7 +110,7 @@ void TraceScroller::setUpTracePlotItem()
|
||||
|
||||
void TraceScroller::setUpDrawingProperties()
|
||||
{
|
||||
drawingProperties.init(navigator->getTracePlotLines(), navigator->getTracePlotLineCache());
|
||||
drawingProperties.init(tracePlotLineDataSource);
|
||||
|
||||
drawingProperties.textColor = palette().text().color();
|
||||
drawingProperties.numberOfRanks = navigator->GeneralTraceInfo().numberOfRanks;
|
||||
@@ -125,7 +131,7 @@ void TraceScroller::setUpAxis()
|
||||
|
||||
void TraceScroller::updateAxis()
|
||||
{
|
||||
setAxisScale(yLeft, -1, drawingProperties.getNumberOfDisplayedLines() + 1, 1.0);
|
||||
setAxisScale(yLeft, -1, drawingProperties.getNumberOfDisplayedLines(), 1.0);
|
||||
replot();
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "presentation/tracenavigator.h"
|
||||
#include "traceplot.h"
|
||||
|
||||
class TracePlotLineDataSource;
|
||||
|
||||
class TraceScroller : public QwtPlot
|
||||
{
|
||||
@@ -55,6 +56,7 @@ private:
|
||||
bool isInitialized;
|
||||
TraceNavigator *navigator;
|
||||
TracePlot *tracePlot;
|
||||
TracePlotLineDataSource *tracePlotLineDataSource;
|
||||
constexpr static int tracePlotEnlargementFactor = 4;
|
||||
void setUpTracePlotItem();
|
||||
void setUpDrawingProperties();
|
||||
@@ -69,7 +71,7 @@ private:
|
||||
|
||||
public:
|
||||
TraceScroller(QWidget *parent = NULL);
|
||||
void init(TraceNavigator *navigator, TracePlot *tracePlot);
|
||||
void init(TraceNavigator *navigator, TracePlot *tracePlot, TracePlotLineDataSource *tracePlotLineDataSource);
|
||||
Timespan GetCurrentTimespan();
|
||||
|
||||
public Q_SLOTS:
|
||||
|
||||
@@ -1,460 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Technische Universität 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:
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#include "traceselector.h"
|
||||
#include "traceplot.h"
|
||||
|
||||
#include <QTreeWidget>
|
||||
#include <QTreeWidgetItem>
|
||||
#include <QTreeView>
|
||||
#include <QVBoxLayout>
|
||||
#include <QDropEvent>
|
||||
#include <QLabel>
|
||||
#include <QMimeData>
|
||||
|
||||
QMimeData *TraceAvailableTree::mimeData(const QList<QTreeWidgetItem *> items) const
|
||||
{
|
||||
QByteArray traceLineData;
|
||||
QDataStream dataStream(&traceLineData, QIODevice::WriteOnly);
|
||||
|
||||
for (QTreeWidgetItem *item : items)
|
||||
{
|
||||
TraceSelectorTreeItem *treeSelectorItem = static_cast<TraceSelectorTreeItem *>(item);
|
||||
|
||||
dataStream << static_cast<int>(treeSelectorItem->type)
|
||||
<< treeSelectorItem->rank
|
||||
<< treeSelectorItem->bankgroup
|
||||
<< treeSelectorItem->bank;
|
||||
}
|
||||
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
mimeData->setData("application/x-tracelinedata", traceLineData);
|
||||
|
||||
return mimeData;
|
||||
}
|
||||
|
||||
QStringList TraceAvailableTree::mimeTypes() const
|
||||
{
|
||||
QStringList types = QTreeWidget::mimeTypes();
|
||||
types << "application/x-tracelinedata";
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
void TraceAvailableTree::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
if(event->key() == Qt::Key_Return)
|
||||
{
|
||||
for (unsigned int i = 0; i < topLevelItemCount(); i++)
|
||||
{
|
||||
auto currentItem = static_cast<TraceSelectorTreeItem *>(topLevelItem(i));
|
||||
|
||||
if (currentItem->isSelected())
|
||||
{
|
||||
auto clonedItem = new TraceSelectorTreeItem(*currentItem);
|
||||
|
||||
for (int i = 0; i < currentItem->childCount(); i++)
|
||||
{
|
||||
auto child = static_cast<TraceSelectorTreeItem *>(currentItem->child(i));
|
||||
clonedItem->addChild(new TraceSelectorTreeItem(*child));
|
||||
}
|
||||
|
||||
selectedTree->addTopLevelItem(clonedItem);
|
||||
}
|
||||
|
||||
// Also add child items that could be selected.
|
||||
for (unsigned int i = 0; i < currentItem->childCount(); i++)
|
||||
{
|
||||
auto currentChildItem = static_cast<TraceSelectorTreeItem *>(currentItem->child(i));
|
||||
|
||||
if (currentChildItem->isSelected())
|
||||
{
|
||||
auto clonedItem = new TraceSelectorTreeItem(*currentChildItem);
|
||||
selectedTree->addTopLevelItem(clonedItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Q_EMIT selectedTree->itemsChanged();
|
||||
}
|
||||
|
||||
QTreeWidget::keyPressEvent(event);
|
||||
}
|
||||
|
||||
TraceSelectedTree::TraceSelectedTree(QWidget *parent) :
|
||||
QTreeWidget(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void TraceSelectedTree::init(unsigned int groupsPerRank, unsigned int banksPerGroup)
|
||||
{
|
||||
this->groupsPerRank = groupsPerRank;
|
||||
this->banksPerGroup = banksPerGroup;
|
||||
}
|
||||
|
||||
std::vector<QTreeWidgetItem *> TraceSelectedTree::clonedItems() const
|
||||
{
|
||||
std::vector<QTreeWidgetItem *> clonedTopLevelItems;
|
||||
|
||||
for (unsigned int i = 0; i < topLevelItemCount(); i++)
|
||||
{
|
||||
clonedTopLevelItems.push_back(topLevelItem(i)->clone());
|
||||
}
|
||||
|
||||
return clonedTopLevelItems;
|
||||
}
|
||||
|
||||
void TraceSelectedTree::setItems(const std::vector<QTreeWidgetItem *> &items)
|
||||
{
|
||||
for (unsigned int i = topLevelItemCount(); i--;)
|
||||
takeTopLevelItem(i);
|
||||
|
||||
for (auto item : items)
|
||||
addTopLevelItem(item);
|
||||
|
||||
emit itemsChanged();
|
||||
}
|
||||
|
||||
QMimeData *TraceSelectedTree::mimeData(const QList<QTreeWidgetItem *> items) const
|
||||
{
|
||||
QByteArray traceLineData;
|
||||
QDataStream dataStream(&traceLineData, QIODevice::WriteOnly);
|
||||
|
||||
for (QTreeWidgetItem *item : items)
|
||||
{
|
||||
TraceSelectorTreeItem *treeSelectorItem = static_cast<TraceSelectorTreeItem *>(item);
|
||||
|
||||
dataStream << static_cast<int>(treeSelectorItem->type)
|
||||
<< treeSelectorItem->rank
|
||||
<< treeSelectorItem->bankgroup
|
||||
<< treeSelectorItem->bank;
|
||||
}
|
||||
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
mimeData->setData("application/x-tracelinedata", traceLineData);
|
||||
|
||||
return mimeData;
|
||||
}
|
||||
|
||||
QStringList TraceSelectedTree::mimeTypes() const
|
||||
{
|
||||
QStringList types = QTreeWidget::mimeTypes();
|
||||
types << "application/x-tracelinedata";
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
Qt::DropActions TraceSelectedTree::supportedDropActions() const
|
||||
{
|
||||
return (Qt::MoveAction | Qt::CopyAction);
|
||||
}
|
||||
|
||||
bool TraceSelectedTree::dropMimeData(QTreeWidgetItem *parent, int index, const QMimeData *data, Qt::DropAction action)
|
||||
{
|
||||
bool dropHandled = false;
|
||||
|
||||
if (action == Qt::CopyAction && data->hasFormat("application/x-tracelinedata"))
|
||||
{
|
||||
dropHandled = true;
|
||||
|
||||
QByteArray traceLineData = data->data("application/x-tracelinedata");
|
||||
QDataStream dataStream(&traceLineData, QIODevice::ReadOnly);
|
||||
|
||||
QList<QTreeWidgetItem *> droppedItems;
|
||||
|
||||
while (!dataStream.atEnd())
|
||||
{
|
||||
TraceSelectorTreeItem::Type currentType;
|
||||
int currentTypeNum;
|
||||
unsigned int currentRank, currentBankGroup, currentBank;
|
||||
|
||||
dataStream >> currentTypeNum
|
||||
>> currentRank
|
||||
>> currentBankGroup
|
||||
>> currentBank;
|
||||
|
||||
currentType = static_cast<TraceSelectorTreeItem::Type>(currentTypeNum);
|
||||
|
||||
QTreeWidgetItem *droppedItem;
|
||||
|
||||
switch (currentType)
|
||||
{
|
||||
case TraceSelectorTreeItem::Type::RequestLineItem:
|
||||
case TraceSelectorTreeItem::Type::ResponseLineItem:
|
||||
case TraceSelectorTreeItem::Type::CommandBusLineItem:
|
||||
case TraceSelectorTreeItem::Type::DataBusLineItem:
|
||||
droppedItem = new TraceSelectorTreeItem(currentType);
|
||||
break;
|
||||
|
||||
case TraceSelectorTreeItem::Type::BankLineItem:
|
||||
droppedItem = new TraceSelectorTreeItem(currentType, currentRank, currentBankGroup, currentBank);
|
||||
break;
|
||||
|
||||
case TraceSelectorTreeItem::Type::RankGroupItem:
|
||||
droppedItem = TraceSelectorTreeItem::createRankParentItem(currentRank, groupsPerRank, banksPerGroup);
|
||||
break;
|
||||
}
|
||||
|
||||
droppedItems.append(droppedItem);
|
||||
}
|
||||
|
||||
insertTopLevelItems(index, droppedItems);
|
||||
}
|
||||
else
|
||||
dropHandled = QTreeWidget::dropMimeData(parent, index, data, action);
|
||||
|
||||
return dropHandled;
|
||||
}
|
||||
|
||||
void TraceSelectedTree::dropEvent(QDropEvent *event)
|
||||
{
|
||||
if (event->source() == this)
|
||||
event->setDropAction(Qt::MoveAction);
|
||||
else
|
||||
event->setDropAction(Qt::CopyAction);
|
||||
|
||||
QTreeWidget::dropEvent(event);
|
||||
|
||||
Q_EMIT itemsChanged();
|
||||
}
|
||||
|
||||
void TraceSelectedTree::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
if(event->key() == Qt::Key_Delete)
|
||||
{
|
||||
for (unsigned int i = topLevelItemCount(); i--;)
|
||||
{
|
||||
if (topLevelItem(i)->isSelected())
|
||||
takeTopLevelItem(i);
|
||||
}
|
||||
|
||||
Q_EMIT itemsChanged();
|
||||
}
|
||||
|
||||
QTreeWidget::keyPressEvent(event);
|
||||
}
|
||||
|
||||
TraceSelector::TraceSelector(QWidget *parent) :
|
||||
QWidget(parent), layout(new QVBoxLayout(this)),
|
||||
selectedTree(new TraceSelectedTree(this)),
|
||||
availableTree(new TraceAvailableTree(selectedTree, this))
|
||||
{
|
||||
QLabel *descriptionLabel = new QLabel();
|
||||
descriptionLabel->setText(
|
||||
"To customize the displayed rows double click or "
|
||||
"drag and drop items from the upper list to the lower list."
|
||||
);
|
||||
descriptionLabel->setWordWrap(true);
|
||||
descriptionLabel->setAlignment(Qt::AlignCenter);
|
||||
|
||||
layout->addWidget(descriptionLabel);
|
||||
layout->addWidget(availableTree);
|
||||
layout->addWidget(selectedTree);
|
||||
|
||||
availableTree->setHeaderLabel("Available Items");
|
||||
availableTree->setDragEnabled(true);
|
||||
availableTree->setExpandsOnDoubleClick(false);
|
||||
availableTree->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
|
||||
selectedTree->setHeaderLabel("Selected Items");
|
||||
selectedTree->setDragEnabled(true);
|
||||
selectedTree->setAcceptDrops(true);
|
||||
selectedTree->setDropIndicatorShown(true);
|
||||
selectedTree->setExpandsOnDoubleClick(false);
|
||||
selectedTree->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
|
||||
connect(selectedTree, &TraceSelectedTree::itemsChanged, this, [=](){
|
||||
Q_EMIT selectedTreeChanged(selectedTree);
|
||||
});
|
||||
|
||||
connect(availableTree, &QTreeWidget::itemDoubleClicked, this, [=](QTreeWidgetItem *item, int column) {
|
||||
Q_UNUSED(column)
|
||||
|
||||
auto traceSelectorItem = static_cast<TraceSelectorTreeItem *>(item);
|
||||
auto clonedItem = new TraceSelectorTreeItem(*traceSelectorItem);
|
||||
|
||||
for (int i = 0; i < traceSelectorItem->childCount(); i++)
|
||||
{
|
||||
auto child = static_cast<TraceSelectorTreeItem *>(traceSelectorItem->child(i));
|
||||
clonedItem->addChild(new TraceSelectorTreeItem(*child));
|
||||
}
|
||||
|
||||
selectedTree->addTopLevelItem(clonedItem);
|
||||
|
||||
Q_EMIT selectedTreeChanged(selectedTree);
|
||||
});
|
||||
|
||||
connect(selectedTree, &QTreeWidget::itemDoubleClicked, this, [=](QTreeWidgetItem *item, int column) {
|
||||
Q_UNUSED(column)
|
||||
|
||||
int index = selectedTree->indexOfTopLevelItem(item);
|
||||
selectedTree->takeTopLevelItem(index);
|
||||
|
||||
Q_EMIT selectedTreeChanged(selectedTree);
|
||||
});
|
||||
}
|
||||
|
||||
void TraceSelector::init(TracePlot *traceplot)
|
||||
{
|
||||
this->traceplot = traceplot;
|
||||
numberOfRanks = traceplot->getDrawingProperties().numberOfRanks;
|
||||
groupsPerRank = traceplot->getDrawingProperties().groupsPerRank;
|
||||
banksPerGroup = traceplot->getDrawingProperties().banksPerGroup;
|
||||
selectedTree->init(groupsPerRank, banksPerGroup);
|
||||
|
||||
setUpTreeWidget(availableTree);
|
||||
|
||||
// By default, all available items will also be in the selectedTree.
|
||||
setUpTreeWidget(selectedTree);
|
||||
|
||||
Q_EMIT selectedTreeChanged(selectedTree);
|
||||
}
|
||||
|
||||
void TraceSelector::setUpTreeWidget(QTreeWidget *treeWidget)
|
||||
{
|
||||
treeWidget->addTopLevelItem(
|
||||
new TraceSelectorTreeItem(TraceSelectorTreeItem::Type::RequestLineItem)
|
||||
);
|
||||
|
||||
treeWidget->addTopLevelItem(
|
||||
new TraceSelectorTreeItem(TraceSelectorTreeItem::Type::ResponseLineItem)
|
||||
);
|
||||
|
||||
for (unsigned int rank = numberOfRanks; rank--;)
|
||||
{
|
||||
TraceSelectorTreeItem *rankItem =
|
||||
TraceSelectorTreeItem::createRankParentItem(rank, groupsPerRank, banksPerGroup);
|
||||
|
||||
treeWidget->addTopLevelItem(rankItem);
|
||||
}
|
||||
|
||||
treeWidget->addTopLevelItem(
|
||||
new TraceSelectorTreeItem(TraceSelectorTreeItem::Type::CommandBusLineItem)
|
||||
);
|
||||
|
||||
treeWidget->addTopLevelItem(
|
||||
new TraceSelectorTreeItem(TraceSelectorTreeItem::Type::DataBusLineItem)
|
||||
);
|
||||
}
|
||||
|
||||
std::vector<QTreeWidgetItem *> TraceSelector::getTraceSelectorState() const
|
||||
{
|
||||
return selectedTree->clonedItems();
|
||||
}
|
||||
|
||||
void TraceSelector::restoreTraceSelectorState(const std::vector<QTreeWidgetItem *> &items)
|
||||
{
|
||||
selectedTree->setItems(items);
|
||||
}
|
||||
|
||||
TraceSelectorTreeItem *TraceSelectorTreeItem::createRankParentItem(unsigned int rank,unsigned int groupsPerRank,
|
||||
unsigned int banksPerGroup)
|
||||
{
|
||||
TraceSelectorTreeItem *rankItem = new TraceSelectorTreeItem(TraceSelectorTreeItem::Type::RankGroupItem, rank);
|
||||
|
||||
for (unsigned int group = groupsPerRank; group--;)
|
||||
{
|
||||
for (unsigned int bank = banksPerGroup; bank--;)
|
||||
{
|
||||
rankItem->addChild(
|
||||
new TraceSelectorTreeItem(TraceSelectorTreeItem::Type::BankLineItem, rank, group, bank)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return rankItem;
|
||||
}
|
||||
|
||||
TraceSelectorTreeItem::TraceSelectorTreeItem(TraceSelectorTreeItem::Type type) :
|
||||
QTreeWidgetItem({getLabel(type)}), type(type)
|
||||
{
|
||||
setFlags(flags() & ~Qt::ItemIsDropEnabled);
|
||||
}
|
||||
|
||||
TraceSelectorTreeItem::TraceSelectorTreeItem(TraceSelectorTreeItem::Type type,
|
||||
unsigned int rank) :
|
||||
QTreeWidgetItem({getLabel(rank)}), type(type), rank(rank)
|
||||
{
|
||||
setFlags(flags() & ~Qt::ItemIsDropEnabled);
|
||||
}
|
||||
|
||||
TraceSelectorTreeItem::TraceSelectorTreeItem(TraceSelectorTreeItem::Type type,
|
||||
unsigned int rank, unsigned int bankgroup, unsigned int bank) :
|
||||
QTreeWidgetItem({getLabel(rank, bankgroup, bank)}), type(type), rank(rank), bankgroup(bankgroup), bank(bank)
|
||||
{
|
||||
setFlags(flags() & ~Qt::ItemIsDropEnabled);
|
||||
}
|
||||
|
||||
QString TraceSelectorTreeItem::getLabel(Type type)
|
||||
{
|
||||
switch (type) {
|
||||
case Type::RequestLineItem:
|
||||
return "REQ";
|
||||
case Type::ResponseLineItem:
|
||||
return "RESP";
|
||||
case Type::CommandBusLineItem:
|
||||
return "Command Bus";
|
||||
case Type::DataBusLineItem:
|
||||
return "Data Bus";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
QString TraceSelectorTreeItem::getLabel(unsigned int rank)
|
||||
{
|
||||
return "RA" + QString::number(rank);
|
||||
}
|
||||
|
||||
QString TraceSelectorTreeItem::getLabel(unsigned int rank, unsigned int bankgroup, unsigned int bank)
|
||||
{
|
||||
return "RA" + QString::number(rank) + " BG" + QString::number(bankgroup) + " BA" + QString::number(bank);
|
||||
}
|
||||
|
||||
QTreeWidgetItem *TraceSelectorTreeItem::clone() const
|
||||
{
|
||||
TraceSelectorTreeItem *cloned = new TraceSelectorTreeItem(*this);
|
||||
|
||||
std::vector<TraceSelectorTreeItem *> clonedChildren;
|
||||
for (unsigned int i = 0; i < childCount(); i++)
|
||||
{
|
||||
clonedChildren.push_back(static_cast<TraceSelectorTreeItem *>(child(i)->clone()));
|
||||
}
|
||||
|
||||
for (auto child : clonedChildren)
|
||||
cloned->addChild(child);
|
||||
|
||||
return cloned;
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Technische Universität 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:
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#ifndef TRACESELECTOR_H
|
||||
#define TRACESELECTOR_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QAbstractItemModel>
|
||||
#include <QTreeWidget>
|
||||
#include <memory>
|
||||
|
||||
class TracePlot;
|
||||
class TracePlotLine;
|
||||
class TraceSelectedTree;
|
||||
class QVBoxLayout;
|
||||
|
||||
class TraceAvailableTree : public QTreeWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TraceAvailableTree(TraceSelectedTree* selectedTree, QWidget *parent = nullptr) :
|
||||
QTreeWidget(parent), selectedTree(selectedTree) {}
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
|
||||
QMimeData *mimeData(const QList<QTreeWidgetItem *> items) const override;
|
||||
QStringList mimeTypes() const override;
|
||||
|
||||
private:
|
||||
TraceSelectedTree *selectedTree;
|
||||
};
|
||||
|
||||
class TraceSelectedTree : public QTreeWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TraceSelectedTree(QWidget *parent = nullptr);
|
||||
void init(unsigned int groupsPerRank, unsigned int banksPerGroup);
|
||||
|
||||
std::vector<QTreeWidgetItem *> clonedItems() const;
|
||||
void setItems(const std::vector<QTreeWidgetItem *> &items);
|
||||
|
||||
Q_SIGNALS:
|
||||
void itemsChanged();
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
|
||||
void dropEvent(QDropEvent *event) override;
|
||||
bool dropMimeData(QTreeWidgetItem *parent, int index, const QMimeData *data, Qt::DropAction action) override;
|
||||
Qt::DropActions supportedDropActions() const override;
|
||||
QMimeData *mimeData(const QList<QTreeWidgetItem *> items) const override;
|
||||
QStringList mimeTypes() const override;
|
||||
|
||||
private:
|
||||
unsigned int groupsPerRank;
|
||||
unsigned int banksPerGroup;
|
||||
};
|
||||
|
||||
class TraceSelectorTreeItem : public QTreeWidgetItem
|
||||
{
|
||||
public:
|
||||
enum class Type {
|
||||
RequestLineItem, ResponseLineItem,
|
||||
CommandBusLineItem, DataBusLineItem,
|
||||
RankGroupItem, BankLineItem
|
||||
} const type;
|
||||
|
||||
TraceSelectorTreeItem(Type type);
|
||||
TraceSelectorTreeItem(Type type, unsigned int rank);
|
||||
TraceSelectorTreeItem(Type type, unsigned int rank, unsigned int bankgroup, unsigned int bank);
|
||||
|
||||
static TraceSelectorTreeItem *createRankParentItem(unsigned int rank, unsigned int groupsPerRank,
|
||||
unsigned int banksPerGroup);
|
||||
|
||||
static QString getLabel(Type type);
|
||||
static QString getLabel(unsigned int rank);
|
||||
static QString getLabel(unsigned int rank, unsigned int bankgroup, unsigned int bank);
|
||||
|
||||
const unsigned int rank = 0, bankgroup = 0, bank = 0;
|
||||
|
||||
protected:
|
||||
QTreeWidgetItem *clone() const override;
|
||||
};
|
||||
|
||||
class TraceSelector : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TraceSelector(QWidget *parent = nullptr);
|
||||
void init(TracePlot *traceplot);
|
||||
|
||||
std::vector<QTreeWidgetItem *> getTraceSelectorState() const;
|
||||
void restoreTraceSelectorState(const std::vector<QTreeWidgetItem *> &items);
|
||||
|
||||
signals:
|
||||
void selectedTreeChanged(QTreeWidget *treeWidget);
|
||||
|
||||
private:
|
||||
void setUpTreeWidget(QTreeWidget *treeWidget);
|
||||
|
||||
unsigned int numberOfRanks;
|
||||
unsigned int groupsPerRank;
|
||||
unsigned int banksPerGroup;
|
||||
|
||||
TracePlot *traceplot;
|
||||
QVBoxLayout *layout;
|
||||
TraceSelectedTree *selectedTree;
|
||||
TraceAvailableTree *availableTree;
|
||||
};
|
||||
|
||||
#endif //TRACESELECTOR_H
|
||||
@@ -1,148 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Technische Universität 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.
|
||||
*
|
||||
* Author:
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#include "traceplotline.h"
|
||||
#include "../traceplot.h"
|
||||
|
||||
#include <QPushButton>
|
||||
#include <qwt_plot.h>
|
||||
|
||||
TracePlotLine::TracePlotLine(QString label) :
|
||||
label(label)
|
||||
{
|
||||
}
|
||||
|
||||
TracePlotLine::TracePlotLine()
|
||||
{
|
||||
}
|
||||
|
||||
TracePlotLine::~TracePlotLine() {}
|
||||
|
||||
QString TracePlotLine::getLabel() const
|
||||
{
|
||||
return label;
|
||||
}
|
||||
|
||||
bool TracePlotLine::isCollapsed() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void TracePlotLine::setYVal (int yVal)
|
||||
{
|
||||
this->yVal = yVal;
|
||||
}
|
||||
|
||||
int TracePlotLine::getYVal() const
|
||||
{
|
||||
return yVal;
|
||||
}
|
||||
|
||||
|
||||
TracePlotBankLine::TracePlotBankLine(unsigned int rank, unsigned int group, unsigned int bank,
|
||||
std::shared_ptr<TracePlotFirstRankLine> firstRankLine) :
|
||||
TracePlotBankLine(rank, group, bank)
|
||||
{
|
||||
this->firstRankLine = firstRankLine;
|
||||
}
|
||||
|
||||
TracePlotBankLine::TracePlotBankLine(unsigned int rank, unsigned int group, unsigned int bank) :
|
||||
rank(rank), group(group), bank(bank)
|
||||
{
|
||||
QString rankLabel = QString("RA") + QString::number(rank);
|
||||
QString bankGroupLabel = QString("BG") + QString::number(group);
|
||||
QString bankLabel = QString("BA") + QString::number(bank);
|
||||
|
||||
label = rankLabel + QString(" ") + bankGroupLabel + QString(" ") + bankLabel;
|
||||
}
|
||||
|
||||
bool TracePlotBankLine::isCollapsed() const
|
||||
{
|
||||
if (!firstRankLine.lock())
|
||||
return false;
|
||||
|
||||
return firstRankLine.lock()->isCollapsed();
|
||||
}
|
||||
|
||||
|
||||
TracePlotFirstRankLine::TracePlotFirstRankLine(unsigned int rank, unsigned int group, unsigned int bank,
|
||||
TracePlot *tracePlot) :
|
||||
TracePlotBankLine(rank, group, bank),
|
||||
collapseButton(new QPushButton(tracePlot)), tracePlot(tracePlot)
|
||||
{
|
||||
collapsedLabel = QString("RA") + QString::number(rank);
|
||||
|
||||
collapseButton->setText(collapsed ? "+" : "-");
|
||||
collapseButton->show();
|
||||
|
||||
QObject::connect(collapseButton, &QPushButton::pressed, this, [=](){
|
||||
collapsed = !collapsed;
|
||||
collapseButton->setText(collapsed ? "+" : "-");
|
||||
Q_EMIT collapsedStateChanged();
|
||||
});
|
||||
|
||||
QObject::connect(this, &TracePlotFirstRankLine::collapseRequested,
|
||||
collapseButton, &QPushButton::pressed);
|
||||
}
|
||||
|
||||
TracePlotFirstRankLine::~TracePlotFirstRankLine()
|
||||
{
|
||||
// Delete the collapseButton because its parent will still exist.
|
||||
collapseButton->deleteLater();
|
||||
}
|
||||
|
||||
void TracePlotFirstRankLine::updateButtonPosition()
|
||||
{
|
||||
QPointF point = tracePlot->axisScaleDraw(QwtPlot::yLeft)->labelPosition(getYVal());
|
||||
collapseButton->setGeometry(point.x(), point.y() - 4, 25, 25);
|
||||
}
|
||||
|
||||
bool TracePlotFirstRankLine::isCollapsed() const
|
||||
{
|
||||
return collapsed;
|
||||
}
|
||||
|
||||
QString TracePlotFirstRankLine::getLabel() const
|
||||
{
|
||||
if (collapsed)
|
||||
return collapsedLabel;
|
||||
else
|
||||
return TracePlotLine::getLabel();
|
||||
}
|
||||
|
||||
QString TracePlotFirstRankLine::getFullLabel() const
|
||||
{
|
||||
return TracePlotLine::getLabel();
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Technische Universität 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.
|
||||
*
|
||||
* Author:
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#ifndef TRACELOTLINE_H
|
||||
#define TRACELOTLINE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QHash>
|
||||
#include <memory>
|
||||
|
||||
class QPushButton;
|
||||
class TracePlot;
|
||||
class TracePlotFirstRankLine;
|
||||
|
||||
class TracePlotLine : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TracePlotLine(QString label);
|
||||
virtual ~TracePlotLine() = 0;
|
||||
|
||||
virtual QString getLabel() const;
|
||||
virtual bool isCollapsed() const;
|
||||
|
||||
void setYVal(int yVal);
|
||||
int getYVal() const;
|
||||
|
||||
protected:
|
||||
TracePlotLine();
|
||||
|
||||
QString label;
|
||||
int yVal;
|
||||
};
|
||||
|
||||
class TracePlotBankLine : public TracePlotLine
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TracePlotBankLine(unsigned int rank, unsigned int group, unsigned int bank,
|
||||
std::shared_ptr<TracePlotFirstRankLine> firstRankLine);
|
||||
|
||||
TracePlotBankLine(unsigned int rank, unsigned int group, unsigned int bank);
|
||||
~TracePlotBankLine() = default;
|
||||
|
||||
virtual bool isCollapsed() const override;
|
||||
std::shared_ptr<TracePlotFirstRankLine> getFirstRankLine() const {
|
||||
return firstRankLine.lock();
|
||||
}
|
||||
|
||||
const unsigned int rank;
|
||||
const unsigned int group;
|
||||
const unsigned int bank;
|
||||
|
||||
private:
|
||||
std::weak_ptr<TracePlotFirstRankLine> firstRankLine;
|
||||
};
|
||||
|
||||
|
||||
class TracePlotFirstRankLine final : public TracePlotBankLine
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TracePlotFirstRankLine(unsigned int rank, unsigned int group, unsigned int bank,
|
||||
TracePlot *tracePlot);
|
||||
|
||||
~TracePlotFirstRankLine();
|
||||
|
||||
bool isCollapsed() const override;
|
||||
QString getLabel() const override;
|
||||
QString getFullLabel() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void updateButtonPosition();
|
||||
|
||||
Q_SIGNALS:
|
||||
void collapsedStateChanged();
|
||||
void collapseRequested();
|
||||
|
||||
private:
|
||||
QString collapsedLabel;
|
||||
QPushButton *collapseButton;
|
||||
bool collapsed = true;
|
||||
TracePlot *tracePlot;
|
||||
};
|
||||
|
||||
|
||||
class TracePlotRequestLine final : public TracePlotLine
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TracePlotRequestLine() : TracePlotLine("REQ") {}
|
||||
~TracePlotRequestLine() = default;
|
||||
};
|
||||
|
||||
class TracePlotResponseLine final : public TracePlotLine
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TracePlotResponseLine() : TracePlotLine("RESP") {}
|
||||
~TracePlotResponseLine() = default;
|
||||
};
|
||||
|
||||
class TracePlotDataBusLine final : public TracePlotLine
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TracePlotDataBusLine() : TracePlotLine("Data Bus") {}
|
||||
~TracePlotDataBusLine() = default;
|
||||
};
|
||||
|
||||
class TracePlotCommandBusLine final : public TracePlotLine
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TracePlotCommandBusLine() : TracePlotLine("Command Bus") {}
|
||||
~TracePlotCommandBusLine() = default;
|
||||
};
|
||||
|
||||
#endif // TRACELOTLINE_H
|
||||
@@ -1,223 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Technische Universität 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.
|
||||
*
|
||||
* Author:
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#include "traceplotlinecache.h"
|
||||
#include "../tracedrawingproperties.h"
|
||||
#include "traceplotline.h"
|
||||
|
||||
TracePlotLineCache::TracePlotLineCache(std::shared_ptr<TracePlotLineVector> tracePlotLines, unsigned int numberOfRanks,
|
||||
unsigned int groupsPerRank, unsigned int banksPerGroup) :
|
||||
tracePlotLines(tracePlotLines), numberOfRanks(numberOfRanks),
|
||||
groupsPerRank(groupsPerRank), banksPerGroup(banksPerGroup)
|
||||
{
|
||||
}
|
||||
|
||||
void TracePlotLineCache::clearCache() const
|
||||
{
|
||||
bankLinesCache.clear();
|
||||
bankLinesFromGroupCache.clear();
|
||||
bankLinesFromRankCache.clear();
|
||||
firstRankLinesCache.clear();
|
||||
requestLinesCache.clear();
|
||||
responseLinesCache.clear();
|
||||
commandBusLinesCache.clear();
|
||||
dataBusLinesCache.clear();
|
||||
}
|
||||
|
||||
TracePlotLineVector TracePlotLineCache::getCommandBusLines() const
|
||||
{
|
||||
if (commandBusLinesCache.size() != 0)
|
||||
return commandBusLinesCache;
|
||||
|
||||
std::vector<std::shared_ptr<TracePlotLine>> commandBusLines;
|
||||
for (auto line : *tracePlotLines)
|
||||
{
|
||||
auto commandBusLine = std::dynamic_pointer_cast<TracePlotCommandBusLine>(line);
|
||||
if (commandBusLine)
|
||||
commandBusLines.push_back(commandBusLine);
|
||||
}
|
||||
|
||||
commandBusLinesCache = commandBusLines;
|
||||
|
||||
return commandBusLines;
|
||||
}
|
||||
|
||||
TracePlotLineVector TracePlotLineCache::getDataBusLines() const
|
||||
{
|
||||
if (dataBusLinesCache.size() != 0)
|
||||
return dataBusLinesCache;
|
||||
|
||||
std::vector<std::shared_ptr<TracePlotLine>> dataBusLines;
|
||||
for (auto line : *tracePlotLines)
|
||||
{
|
||||
auto dataBusLine = std::dynamic_pointer_cast<TracePlotDataBusLine>(line);
|
||||
if (dataBusLine)
|
||||
dataBusLines.push_back(dataBusLine);
|
||||
}
|
||||
|
||||
dataBusLinesCache = dataBusLines;
|
||||
|
||||
return dataBusLines;
|
||||
}
|
||||
|
||||
TracePlotLineVector TracePlotLineCache::getRequestLines() const
|
||||
{
|
||||
if (requestLinesCache.size() != 0)
|
||||
return requestLinesCache;
|
||||
|
||||
std::vector<std::shared_ptr<TracePlotLine>> requestLines;
|
||||
for (auto line : *tracePlotLines)
|
||||
{
|
||||
auto requestLine = std::dynamic_pointer_cast<TracePlotRequestLine>(line);
|
||||
if (requestLine)
|
||||
requestLines.push_back(requestLine);
|
||||
}
|
||||
|
||||
requestLinesCache = requestLines;
|
||||
|
||||
return requestLines;
|
||||
}
|
||||
|
||||
TracePlotLineVector TracePlotLineCache::getResponseLines() const
|
||||
{
|
||||
if (responseLinesCache.size() != 0)
|
||||
return responseLinesCache;
|
||||
|
||||
std::vector<std::shared_ptr<TracePlotLine>> responseLines;
|
||||
for (auto line : *tracePlotLines)
|
||||
{
|
||||
auto responseLine = std::dynamic_pointer_cast<TracePlotResponseLine>(line);
|
||||
if (responseLine)
|
||||
responseLines.push_back(responseLine);
|
||||
}
|
||||
|
||||
responseLinesCache = responseLines;
|
||||
|
||||
return responseLines;
|
||||
}
|
||||
|
||||
TracePlotLineVector TracePlotLineCache::getFirstRankLines(unsigned int rank) const
|
||||
{
|
||||
Q_ASSERT(rank <= numberOfRanks - 1);
|
||||
|
||||
if (firstRankLinesCache.find(rank) != firstRankLinesCache.end())
|
||||
return firstRankLinesCache[rank];
|
||||
|
||||
std::vector<std::shared_ptr<TracePlotLine>> firstRankLines;
|
||||
|
||||
for (auto line : *tracePlotLines)
|
||||
{
|
||||
auto firstRankLine = std::dynamic_pointer_cast<TracePlotFirstRankLine>(line);
|
||||
if (firstRankLine && firstRankLine->rank == rank)
|
||||
firstRankLines.push_back(firstRankLine);
|
||||
}
|
||||
|
||||
firstRankLinesCache[rank] = firstRankLines;
|
||||
|
||||
return firstRankLines;
|
||||
}
|
||||
|
||||
TracePlotLineVector TracePlotLineCache::getBankLinesFromRank(unsigned int rank) const
|
||||
{
|
||||
Q_ASSERT(rank <= numberOfRanks - 1);
|
||||
|
||||
if (bankLinesFromRankCache.find(rank) != bankLinesFromRankCache.end())
|
||||
return bankLinesFromRankCache[rank];
|
||||
|
||||
std::vector<std::shared_ptr<TracePlotLine>> bankLines;
|
||||
for (auto line : *tracePlotLines)
|
||||
{
|
||||
auto bankLine = std::dynamic_pointer_cast<TracePlotBankLine>(line);
|
||||
|
||||
if (bankLine && bankLine->rank == rank)
|
||||
bankLines.push_back(bankLine);
|
||||
}
|
||||
|
||||
bankLinesFromRankCache[rank] = bankLines;
|
||||
|
||||
return bankLines;
|
||||
}
|
||||
|
||||
TracePlotLineVector TracePlotLineCache::getBankLinesFromGroup(unsigned int rank, unsigned int group) const
|
||||
{
|
||||
Q_ASSERT(rank <= numberOfRanks - 1);
|
||||
Q_ASSERT(group <= groupsPerRank - 1);
|
||||
|
||||
std::tuple<int, int> bankLinesTuple {rank, group};
|
||||
|
||||
if (bankLinesFromGroupCache.find(bankLinesTuple) != bankLinesFromGroupCache.end())
|
||||
return bankLinesFromGroupCache[bankLinesTuple];
|
||||
|
||||
std::vector<std::shared_ptr<TracePlotLine>> bankLines;
|
||||
|
||||
for (auto line : *tracePlotLines)
|
||||
{
|
||||
auto bankLine = std::dynamic_pointer_cast<TracePlotBankLine>(line);
|
||||
|
||||
if (bankLine && bankLine->rank == rank && bankLine->group == group)
|
||||
bankLines.push_back(bankLine);
|
||||
}
|
||||
|
||||
bankLinesFromGroupCache[bankLinesTuple] = bankLines;
|
||||
|
||||
return bankLines;
|
||||
}
|
||||
|
||||
TracePlotLineVector TracePlotLineCache::getBankLines(unsigned int rank, unsigned int group,
|
||||
unsigned int bank) const
|
||||
{
|
||||
Q_ASSERT(rank <= numberOfRanks - 1);
|
||||
Q_ASSERT(group <= groupsPerRank - 1);
|
||||
Q_ASSERT(bank <= banksPerGroup - 1);
|
||||
|
||||
std::tuple<int, int, int> bankLinesTuple {rank, group, bank};
|
||||
|
||||
if (bankLinesCache.find(bankLinesTuple) != bankLinesCache.end())
|
||||
return bankLinesCache[bankLinesTuple];
|
||||
|
||||
std::vector<std::shared_ptr<TracePlotLine>> bankLines;
|
||||
|
||||
for (auto line : *tracePlotLines)
|
||||
{
|
||||
auto bankLine = std::dynamic_pointer_cast<TracePlotBankLine>(line);
|
||||
|
||||
if (bankLine && bankLine->rank == rank && bankLine->group == group && bankLine->bank == bank)
|
||||
bankLines.push_back(bankLine);
|
||||
}
|
||||
|
||||
bankLinesCache[bankLinesTuple] = bankLines;
|
||||
|
||||
return bankLines;
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Technische Universität 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.
|
||||
*
|
||||
* Author:
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#ifndef TRACELOTLINECACHE_H
|
||||
#define TRACELOTLINECACHE_H
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
class TracePlotLine;
|
||||
|
||||
using TracePlotLineVector = std::vector<std::shared_ptr<TracePlotLine>>;
|
||||
|
||||
struct TracePlotLineCache
|
||||
{
|
||||
TracePlotLineCache(std::shared_ptr<TracePlotLineVector> tracePlotLines, unsigned int numberOfRanks,
|
||||
unsigned int groupsPerRank, unsigned int banksPerGroup);
|
||||
|
||||
TracePlotLineVector getRequestLines() const;
|
||||
TracePlotLineVector getResponseLines() const;
|
||||
TracePlotLineVector getCommandBusLines() const;
|
||||
TracePlotLineVector getDataBusLines() const;
|
||||
TracePlotLineVector getFirstRankLines(unsigned int rank) const;
|
||||
TracePlotLineVector getBankLines(unsigned int rank, unsigned int group, unsigned int bank) const;
|
||||
TracePlotLineVector getBankLinesFromGroup(unsigned int rank, unsigned int group) const;
|
||||
TracePlotLineVector getBankLinesFromRank(unsigned int rank) const;
|
||||
|
||||
void clearCache() const;
|
||||
|
||||
private:
|
||||
std::shared_ptr<TracePlotLineVector> tracePlotLines;
|
||||
|
||||
unsigned int numberOfRanks;
|
||||
unsigned int groupsPerRank;
|
||||
unsigned int banksPerGroup;
|
||||
|
||||
mutable std::map<std::tuple<int, int, int>, std::vector<std::shared_ptr<TracePlotLine>>> bankLinesCache;
|
||||
mutable std::map<std::tuple<int, int>, std::vector<std::shared_ptr<TracePlotLine>>> bankLinesFromGroupCache;
|
||||
mutable std::map<int, std::vector<std::shared_ptr<TracePlotLine>>> bankLinesFromRankCache;
|
||||
mutable std::map<int, std::vector<std::shared_ptr<TracePlotLine>>> firstRankLinesCache;
|
||||
mutable std::vector<std::shared_ptr<TracePlotLine>> requestLinesCache;
|
||||
mutable std::vector<std::shared_ptr<TracePlotLine>> responseLinesCache;
|
||||
mutable std::vector<std::shared_ptr<TracePlotLine>> commandBusLinesCache;
|
||||
mutable std::vector<std::shared_ptr<TracePlotLine>> dataBusLinesCache;
|
||||
};
|
||||
|
||||
#endif // TRACELOTLINECACHE_H
|
||||
@@ -39,24 +39,51 @@ def trace_length_in_ns(connection):
|
||||
@metric
|
||||
def command_bus_utilisation_in_percent(connection):
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("""
|
||||
SELECT
|
||||
SUM(CommandLengths.Length)
|
||||
FROM
|
||||
Phases
|
||||
INNER JOIN
|
||||
CommandLengths
|
||||
cursor.execute("""SELECT RowColumnCommandBus FROM GeneralInfo""")
|
||||
rowColumnCommandBus = cursor.fetchone()[0]
|
||||
if rowColumnCommandBus:
|
||||
cursor.execute("""
|
||||
SELECT SUM(CommandLengths.Length)
|
||||
FROM Phases
|
||||
INNER JOIN CommandLengths
|
||||
ON Phases.PhaseName = CommandLengths.Command
|
||||
""")
|
||||
result = cursor.fetchone()[0]
|
||||
WHERE PhaseName <> 'RD' AND PhaseName <> 'RDA' AND PhaseName <> 'WR' AND PhaseName <> 'WRA'
|
||||
""")
|
||||
rowBusUtil = cursor.fetchone()[0]
|
||||
if rowBusUtil is None:
|
||||
rowBusUtil = 0
|
||||
|
||||
cursor.execute("""
|
||||
SELECT SUM(CommandLengths.Length)
|
||||
FROM Phases
|
||||
INNER JOIN CommandLengths
|
||||
ON Phases.PhaseName = CommandLengths.Command
|
||||
WHERE PhaseName = 'RD' OR PhaseName = 'RDA' OR PhaseName = 'WR' OR PhaseName = 'WRA'
|
||||
""")
|
||||
columnBusUtil = cursor.fetchone()[0]
|
||||
if columnBusUtil is None:
|
||||
columnBusUtil = 0
|
||||
|
||||
clk, _ = getClock(connection)
|
||||
traceEnd = getTraceEndTime(connection)
|
||||
rowBusOccupied = rowBusUtil * clk / traceEnd * 100
|
||||
columnBusOccupied = columnBusUtil * clk / traceEnd * 100
|
||||
return "row commands: {}, column commands: {}".format(rowBusOccupied, columnBusOccupied)
|
||||
else:
|
||||
cursor.execute("""
|
||||
SELECT SUM(CommandLengths.Length)
|
||||
FROM Phases
|
||||
INNER JOIN CommandLengths
|
||||
ON Phases.PhaseName = CommandLengths.Command
|
||||
""")
|
||||
util = cursor.fetchone()[0]
|
||||
if (util is None):
|
||||
util = 0
|
||||
|
||||
if (result is None):
|
||||
result = 0
|
||||
|
||||
clk, _ = getClock(connection)
|
||||
traceEnd = getTraceEndTime(connection)
|
||||
cmdBusOccupied = result * clk
|
||||
return cmdBusOccupied / traceEnd * 100
|
||||
clk, _ = getClock(connection)
|
||||
traceEnd = getTraceEndTime(connection)
|
||||
commandBusOccupied = util * clk / traceEnd * 100
|
||||
return ": {}".format(commandBusOccupied)
|
||||
|
||||
@metric
|
||||
def average_response_latency_in_ns(connection):
|
||||
@@ -1027,7 +1054,7 @@ def calculateMetrics(pathToTrace, selectedMetrics=[]):
|
||||
nbanks = nbanks + 1
|
||||
r = (name, float(v))
|
||||
calculatedMetrics.append(r)
|
||||
elif (metric.__name__ == "delayed_reasons"):
|
||||
elif (metric.__name__ == "delayed_reasons" or metric.__name__ == "command_bus_utilisation_in_percent"):
|
||||
values = mres.split(",")
|
||||
for v in values:
|
||||
name = mname + " (" + v.partition(":")[0].strip() + ")"
|
||||
|
||||
@@ -179,7 +179,7 @@ void TraceAnalyzer::reloadTab(int index)
|
||||
QString traceFile = traceFileTab->getPathToTraceFile();
|
||||
traceTime time = traceFileTab->getCurrentTraceTime();
|
||||
traceTime zoomLevel = traceFileTab->getZoomLevel();
|
||||
auto treeItems = traceFileTab->saveTraceSelectorState();
|
||||
auto rootNode = traceFileTab->saveTraceSelectorState();
|
||||
|
||||
if (!traceFileTab->close())
|
||||
return;
|
||||
@@ -190,7 +190,7 @@ void TraceAnalyzer::reloadTab(int index)
|
||||
traceFileTab = createTraceFileTab(traceFile);
|
||||
traceFileTab->setZoomLevel(zoomLevel);
|
||||
traceFileTab->navigateToTime(time);
|
||||
traceFileTab->restoreTraceSelectorState(treeItems);
|
||||
traceFileTab->restoreTraceSelectorState(std::move(rootNode));
|
||||
|
||||
ui->traceFileTabs->insertTab(index, traceFileTab, QFileInfo(traceFile).baseName());
|
||||
ui->traceFileTabs->setCurrentIndex(index);
|
||||
|
||||
@@ -42,8 +42,8 @@
|
||||
#include "businessObjects/commentmodel.h"
|
||||
#include "businessObjects/configmodels.h"
|
||||
#include "businessObjects/pythoncaller.h"
|
||||
#include "businessObjects/traceplotlinemodel.h"
|
||||
#include "businessObjects/tracetime.h"
|
||||
#include "presentation/traceselector.h"
|
||||
#include "qmessagebox.h"
|
||||
#include "queryeditor.h"
|
||||
#include "qwt_legend.h"
|
||||
@@ -72,8 +72,12 @@ TraceFileTab::TraceFileTab(QWidget *parent, const QString &path)
|
||||
: QWidget(parent), ui(new Ui::TraceFileTab), commentModel(new CommentModel(this)),
|
||||
navigator(new TraceNavigator(path, commentModel, this)),
|
||||
mcConfigModel(new McConfigModel(navigator->TraceFile(), this)),
|
||||
memSpecModel(new MemSpecModel(navigator->TraceFile(), this)), savingChangesToDB(false),
|
||||
depInfosView(new DependencyInfosModel(navigator->TraceFile(), this))
|
||||
memSpecModel(new MemSpecModel(navigator->TraceFile(), this)),
|
||||
availableRowsModel(new AvailableTracePlotLineModel(navigator->GeneralTraceInfo(), this)),
|
||||
selectedRowsModel(new SelectedTracePlotLineModel(navigator->GeneralTraceInfo(), this)),
|
||||
tracePlotLineDataSource(new TracePlotLineDataSource(selectedRowsModel, this)),
|
||||
depInfosView(new DependencyInfosModel(navigator->TraceFile(), this)),
|
||||
savingChangesToDB(false)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
this->path = path;
|
||||
@@ -81,12 +85,6 @@ TraceFileTab::TraceFileTab(QWidget *parent, const QString &path)
|
||||
std::cout << "Opening new tab for \"" << path.toStdString() << "\"" <<
|
||||
std::endl;
|
||||
|
||||
initNavigatorAndItsDependentWidgets(path);
|
||||
setUpFileWatcher(path);
|
||||
setUpTraceplotScrollbar();
|
||||
setUpTraceSelector();
|
||||
setUpCommentView();
|
||||
|
||||
ui->mcConfigView->setModel(mcConfigModel);
|
||||
ui->mcConfigView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||
|
||||
@@ -96,6 +94,12 @@ TraceFileTab::TraceFileTab(QWidget *parent, const QString &path)
|
||||
ui->depInfosView->setModel(depInfosView);
|
||||
ui->depInfosView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||
|
||||
setUpTraceSelector();
|
||||
initNavigatorAndItsDependentWidgets(path);
|
||||
setUpFileWatcher(path);
|
||||
setUpTraceplotScrollbar();
|
||||
setUpCommentView();
|
||||
|
||||
tracefileChanged();
|
||||
}
|
||||
|
||||
@@ -131,6 +135,32 @@ void TraceFileTab::exportAsVCD()
|
||||
}
|
||||
}
|
||||
|
||||
void TraceFileTab::setUpTraceSelector()
|
||||
{
|
||||
ui->availableTreeView->setModel(availableRowsModel);
|
||||
ui->availableTreeView->setSelectionModel(availableRowsModel->selectionModel());
|
||||
ui->availableTreeView->installEventFilter(availableRowsModel);
|
||||
|
||||
ui->selectedTreeView->setModel(selectedRowsModel);
|
||||
ui->selectedTreeView->setSelectionModel(selectedRowsModel->selectionModel());
|
||||
ui->selectedTreeView->installEventFilter(selectedRowsModel);
|
||||
|
||||
connect(availableRowsModel, &AvailableTracePlotLineModel::returnPressed, selectedRowsModel,
|
||||
&SelectedTracePlotLineModel::addIndexesFromAvailableModel);
|
||||
|
||||
connect(ui->availableTreeView, &QAbstractItemView::doubleClicked, availableRowsModel,
|
||||
&AvailableTracePlotLineModel::itemsDoubleClicked);
|
||||
connect(ui->selectedTreeView, &QAbstractItemView::doubleClicked, selectedRowsModel,
|
||||
&SelectedTracePlotLineModel::itemsDoubleClicked);
|
||||
|
||||
connect(selectedRowsModel, &QAbstractItemModel::dataChanged, tracePlotLineDataSource,
|
||||
&TracePlotLineDataSource::updateModel);
|
||||
connect(selectedRowsModel, &QAbstractItemModel::rowsInserted, tracePlotLineDataSource,
|
||||
&TracePlotLineDataSource::updateModel);
|
||||
connect(selectedRowsModel, &QAbstractItemModel::rowsRemoved, tracePlotLineDataSource,
|
||||
&TracePlotLineDataSource::updateModel);
|
||||
}
|
||||
|
||||
void TraceFileTab::setUpTraceplotScrollbar()
|
||||
{
|
||||
QObject::connect(ui->traceplotScrollbar, SIGNAL(valueChanged(int)),
|
||||
@@ -139,9 +169,9 @@ void TraceFileTab::setUpTraceplotScrollbar()
|
||||
|
||||
void TraceFileTab::initNavigatorAndItsDependentWidgets(QString path)
|
||||
{
|
||||
ui->traceplot->init(navigator, ui->traceplotScrollbar, commentModel);
|
||||
ui->traceplot->init(navigator, ui->traceplotScrollbar, tracePlotLineDataSource, commentModel);
|
||||
|
||||
ui->traceScroller->init(navigator, ui->traceplot);
|
||||
ui->traceScroller->init(navigator, ui->traceplot, tracePlotLineDataSource);
|
||||
connect(this, SIGNAL(colorGroupingChanged(ColorGrouping)),
|
||||
ui->traceScroller, SLOT(colorGroupingChanged(ColorGrouping)));
|
||||
|
||||
@@ -160,14 +190,6 @@ void TraceFileTab::setUpFileWatcher(QString path)
|
||||
SLOT(tracefileChanged()));
|
||||
}
|
||||
|
||||
void TraceFileTab::setUpTraceSelector()
|
||||
{
|
||||
TraceSelector *selector = static_cast<TraceSelector *>(ui->tabCustomizePlot);
|
||||
connect(selector, &TraceSelector::selectedTreeChanged,
|
||||
ui->traceplot, &TracePlot::updateTracePlotLines);
|
||||
selector->init(ui->traceplot);
|
||||
}
|
||||
|
||||
void TraceFileTab::setUpCommentView()
|
||||
{
|
||||
ui->commentView->setModel(commentModel);
|
||||
@@ -262,16 +284,14 @@ void TraceFileTab::setZoomLevel(traceTime zoomLevel)
|
||||
tracescroller->tracePlotZoomChanged();
|
||||
}
|
||||
|
||||
std::vector<QTreeWidgetItem *> TraceFileTab::saveTraceSelectorState() const
|
||||
std::shared_ptr<AbstractTracePlotLineModel::Node> TraceFileTab::saveTraceSelectorState() const
|
||||
{
|
||||
TraceSelector *selector = static_cast<TraceSelector *>(ui->tabCustomizePlot);
|
||||
return selector->getTraceSelectorState();
|
||||
return selectedRowsModel->getClonedRootNode();
|
||||
}
|
||||
|
||||
void TraceFileTab::restoreTraceSelectorState(const std::vector<QTreeWidgetItem *> &items)
|
||||
void TraceFileTab::restoreTraceSelectorState(std::shared_ptr<AbstractTracePlotLineModel::Node> rootNode)
|
||||
{
|
||||
TraceSelector *selector = static_cast<TraceSelector *>(ui->tabCustomizePlot);
|
||||
selector->restoreTraceSelectorState(items);
|
||||
selectedRowsModel->setRootNode(std::move(rootNode));
|
||||
}
|
||||
|
||||
class ItemDelegate: public QItemDelegate
|
||||
|
||||
@@ -40,15 +40,19 @@
|
||||
#ifndef TRACEFILETAB_H
|
||||
#define TRACEFILETAB_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QString>
|
||||
#include <QFileSystemWatcher>
|
||||
#include "businessObjects/traceplotlinemodel.h"
|
||||
#include "presentation/tracenavigator.h"
|
||||
#include "presentation/traceplot.h"
|
||||
#include "presentation/tracescroller.h"
|
||||
#include "businessObjects/configmodels.h"
|
||||
|
||||
#include <QFileSystemWatcher>
|
||||
#include <QString>
|
||||
#include <QTreeWidget>
|
||||
#include <QWidget>
|
||||
|
||||
class CommentModel;
|
||||
class McConfigModel;
|
||||
class MemSpecModel;
|
||||
|
||||
namespace Ui {
|
||||
class TraceFileTab;
|
||||
@@ -64,8 +68,8 @@ public:
|
||||
|
||||
void setUpFileWatcher(QString filename);
|
||||
void setUpTraceplotScrollbar();
|
||||
void setUpTraceSelector();
|
||||
void setUpCommentView();
|
||||
void setUpTraceSelector();
|
||||
void initNavigatorAndItsDependentWidgets(QString path);
|
||||
QString getPathToTraceFile()
|
||||
{
|
||||
@@ -79,8 +83,8 @@ public:
|
||||
traceTime getZoomLevel() const;
|
||||
void setZoomLevel(traceTime zoomLevel);
|
||||
|
||||
std::vector<QTreeWidgetItem *> saveTraceSelectorState() const;
|
||||
void restoreTraceSelectorState(const std::vector<QTreeWidgetItem *> &items);
|
||||
std::shared_ptr<AbstractTracePlotLineModel::Node> saveTraceSelectorState() const;
|
||||
void restoreTraceSelectorState(std::shared_ptr<AbstractTracePlotLineModel::Node> rootNode);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
@@ -100,8 +104,12 @@ private:
|
||||
CommentModel *commentModel;
|
||||
TraceNavigator *navigator;
|
||||
|
||||
QAbstractItemModel *mcConfigModel;
|
||||
QAbstractItemModel *memSpecModel;
|
||||
McConfigModel *mcConfigModel;
|
||||
MemSpecModel *memSpecModel;
|
||||
|
||||
AvailableTracePlotLineModel *availableRowsModel;
|
||||
SelectedTracePlotLineModel *selectedRowsModel;
|
||||
TracePlotLineDataSource *tracePlotLineDataSource;
|
||||
|
||||
QAbstractItemModel *depInfosView;
|
||||
|
||||
|
||||
@@ -197,10 +197,69 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="TraceSelector" name="tabCustomizePlot">
|
||||
<widget class="QWidget" name="tabCustomizePlot">
|
||||
<attribute name="title">
|
||||
<string>Customize Plot</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="customizePlotDescription">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>To customize the displayed rows double click or drag and drop items from the upper list to the lower list.</p></body></html></string>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeView" name="availableTreeView">
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="dragEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::DragOnly</enum>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
<property name="expandsOnDoubleClick">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeView" name="selectedTreeView">
|
||||
<property name="acceptDrops">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::DragDrop</enum>
|
||||
</property>
|
||||
<property name="defaultDropAction">
|
||||
<enum>Qt::MoveAction</enum>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
<property name="expandsOnDoubleClick">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
||||
<widget class="QWidget" name="tabDepInfos">
|
||||
@@ -377,6 +436,7 @@
|
||||
<class>QwtPlot</class>
|
||||
<extends>QFrame</extends>
|
||||
<header>qwt_plot.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>TracePlot</class>
|
||||
@@ -393,12 +453,6 @@
|
||||
<extends>QTreeWidget</extends>
|
||||
<header>presentation/selectedtransactiontreewidget.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>TraceSelector</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>presentation/traceselector.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
||||
Reference in New Issue
Block a user