Introduce a model/view based approach for the TraceSelector
Replace the old TraceSelector with a new, more generic model/view based approach. This approach has the advantage that the seperate lines that are available in a plot are generated at one single place in the code. Also states such as the collapsed state can be stored in this model, making it much easier to save and restore the whole selected tree of TracePlotLines. This approach makes it also easier to add new functionality to the TraceAnalyzer in the future.
This commit is contained in:
@@ -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) {}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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,43 @@ 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::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 +177,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,31 +275,35 @@ 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;
|
||||
}
|
||||
|
||||
for (Timespan span : spansOnCommandBus)
|
||||
{
|
||||
if (span.overlaps(timespan))
|
||||
{
|
||||
for (const auto &line : drawingProperties.getTracePlotLines())
|
||||
{
|
||||
if (line->data.type != AbstractTracePlotLineModel::CommandBusLine)
|
||||
continue;
|
||||
|
||||
if (fabs(yVal - line->data.yVal) <= hexagonHeight / 2)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (spanOnDataBus && spanOnDataBus->overlaps(timespan))
|
||||
{
|
||||
for (auto dataBusLine : drawingProperties.getDataBusLines())
|
||||
for (const auto &line : drawingProperties.getTracePlotLines())
|
||||
{
|
||||
if (fabs(yVal - dataBusLine->getYVal()) <= hexagonHeight)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (line->data.type != AbstractTracePlotLineModel::DataBusLine)
|
||||
continue;
|
||||
|
||||
for (const Timespan &span : spansOnCommandBus)
|
||||
{
|
||||
if (span.overlaps(timespan))
|
||||
{
|
||||
for (auto commandBusLine : drawingProperties.getCommandBusLines())
|
||||
{
|
||||
if (fabs(yVal - commandBusLine->getYVal()) <= hexagonHeight)
|
||||
return true;
|
||||
}
|
||||
if (fabs(yVal - line->data.yVal) <= hexagonHeight / 2)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,36 +315,6 @@ 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);
|
||||
|
||||
@@ -97,6 +97,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 +105,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 +128,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 +145,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
605
DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.cpp
Normal file
605
DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.cpp
Normal file
@@ -0,0 +1,605 @@
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
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));
|
||||
|
||||
addTopLevelNode(std::unique_ptr<Node>(
|
||||
new Node({LineType::CommandBusLine, getLabel(LineType::CommandBusLine)}, 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();
|
||||
|
||||
collapseButtons.clear();
|
||||
|
||||
for (const auto &node : rootNode->children)
|
||||
{
|
||||
if (node->data.type != LineType::RankGroup)
|
||||
continue;
|
||||
|
||||
QPushButton *collapseButton = new QPushButton(tracePlot);
|
||||
|
||||
unsigned int yVal = [&]()
|
||||
{
|
||||
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);
|
||||
};
|
||||
|
||||
connect(customLabelScaleDraw, &CustomLabelScaleDraw::scaleRedraw, this, 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::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);
|
||||
}
|
||||
|
||||
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 (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)
|
||||
{
|
||||
auto availableModel = qobject_cast<AvailableTracePlotLineModel *>(sender());
|
||||
|
||||
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 << "application/x-tracelinedata";
|
||||
|
||||
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("application/x-tracelinedata", 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("application/x-tracelinedata"))
|
||||
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("application/x-tracelinedata");
|
||||
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)
|
||||
{
|
||||
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();
|
||||
}
|
||||
256
DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.h
Normal file
256
DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.h
Normal file
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* 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,
|
||||
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:
|
||||
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);
|
||||
|
||||
QItemSelectionModel *internalSelectionModel;
|
||||
|
||||
std::shared_ptr<Node> rootNode;
|
||||
|
||||
unsigned int numberOfRanks;
|
||||
unsigned int groupsPerRank;
|
||||
unsigned int banksPerGroup;
|
||||
unsigned int banksPerRank;
|
||||
};
|
||||
|
||||
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
|
||||
@@ -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
|
||||
@@ -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