Click and Seek implemented for the address maps in the Section Widget (#1046)

* Touch and Seek implemented, not yet refactoring

* Done
This commit is contained in:
Vanellope 2018-12-31 01:13:27 +09:00 committed by Itay Cohen
parent 8ff915c21a
commit 8e76a9aca5
2 changed files with 114 additions and 22 deletions

View File

@ -2,6 +2,8 @@
#include <QGraphicsView> #include <QGraphicsView>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QGraphicsSceneMouseEvent>
#include <QToolTip>
#include "common/Configuration.h" #include "common/Configuration.h"
#include "SectionsWidget.h" #include "SectionsWidget.h"
@ -304,10 +306,10 @@ void SectionsWidget::updateToggle()
AbstractAddrDock::AbstractAddrDock(SectionsModel *model, QWidget *parent) : AbstractAddrDock::AbstractAddrDock(SectionsModel *model, QWidget *parent) :
QDockWidget(parent), QDockWidget(parent),
graphicsScene(new QGraphicsScene), addrDockScene(new AddrDockScene),
graphicsView(new QGraphicsView) graphicsView(new QGraphicsView)
{ {
graphicsView->setScene(graphicsScene); graphicsView->setScene(addrDockScene);
setWidget(graphicsView); setWidget(graphicsView);
setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
proxyModel = new SectionsProxyModel(model, this); proxyModel = new SectionsProxyModel(model, this);
@ -328,10 +330,10 @@ AbstractAddrDock::~AbstractAddrDock() {}
void AbstractAddrDock::updateDock() void AbstractAddrDock::updateDock()
{ {
graphicsScene->clear(); addrDockScene->clear();
const QBrush bg = QBrush(ConfigColor("gui.background")); const QBrush bg = QBrush(ConfigColor("gui.background"));
graphicsScene->setBackgroundBrush(bg); addrDockScene->setBackgroundBrush(bg);
textColor = ConfigColor("gui.dataoffset"); textColor = ConfigColor("gui.dataoffset");
} }
@ -342,24 +344,75 @@ void AbstractAddrDock::addTextItem(QColor color, QPoint pos, QString string)
text->setDefaultTextColor(color); text->setDefaultTextColor(color);
text->setPos(pos); text->setPos(pos);
text->setPlainText(string); text->setPlainText(string);
graphicsScene->addItem(text); addrDockScene->addItem(text);
} }
void AbstractAddrDock::drawIndicator(QString name, float ratio) void AbstractAddrDock::drawIndicator(QString name, float ratio)
{ {
RVA offset = Core()->getOffset(); RVA offset = Core()->getOffset();
float padding = nameHeightMap[name] * ratio; float padding = addrDockScene->nameHeightMap[name] * ratio;
int y = namePosYMap[name] + (int)padding; int y = addrDockScene->namePosYMap[name] + (int)padding;
QColor color = indicatorColor; QColor color = indicatorColor;
QGraphicsRectItem *indicator = new QGraphicsRectItem(QRectF(0, y, indicatorWidth, indicatorHeight)); QGraphicsRectItem *indicator = new QGraphicsRectItem(QRectF(0, y, indicatorWidth, indicatorHeight));
indicator->setBrush(QBrush(color)); indicator->setBrush(QBrush(color));
graphicsScene->addItem(indicator); addrDockScene->addItem(indicator);
if (!addrDockScene->disableCenterOn) {
graphicsView->centerOn(indicator); graphicsView->centerOn(indicator);
}
addTextItem(color, QPoint(rectOffset + rectWidth, y - indicatorParamPosY), name); addTextItem(color, QPoint(rectOffset + rectWidth, y - indicatorParamPosY), name);
addTextItem(color, QPoint(0, y - indicatorParamPosY), QString("0x%1").arg(offset, 0, 16)); addTextItem(color, QPoint(0, y - indicatorParamPosY), QString("0x%1").arg(offset, 0, 16));
} }
AddrDockScene::AddrDockScene(QWidget *parent) :
QGraphicsScene(parent)
{
disableCenterOn = false;
}
AddrDockScene::~AddrDockScene() {}
void AddrDockScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
RVA addr = getAddrFromPos((int)event->scenePos().y(), false);
if (addr != RVA_INVALID) {
QToolTip::showText(event->screenPos(), RAddressString(addr));
if (event->buttons() & Qt::LeftButton) {
RVA seekAddr = getAddrFromPos((int)event->scenePos().y(), true);
disableCenterOn = true;
Core()->seek(seekAddr);
disableCenterOn = false;
return;
}
}
}
void AddrDockScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
mousePressEvent(event);
}
RVA AddrDockScene::getAddrFromPos(int posY, bool seek)
{
QHash<QString, int>::const_iterator i = namePosYMap.constBegin();
QHash<QString, RVA> addrMap = seek ? seekAddrMap : nameAddrMap;
QHash<QString, int> addrSizeMap = seek ? seekAddrSizeMap : nameAddrSizeMap;
while (i != namePosYMap.constEnd()) {
QString name = i.key();
int y = i.value();
int h = nameHeightMap[name];
if (posY >= y && y + h >= posY) {
if (h == 0) {
return addrMap[name];
}
return addrMap[name] + (float)addrSizeMap[name] * ((float)(posY - y) / (float)h);
}
i++;
}
return 0;
}
RawAddrDock::RawAddrDock(SectionsModel *model, QWidget *parent) : RawAddrDock::RawAddrDock(SectionsModel *model, QWidget *parent) :
AbstractAddrDock(model, parent) AbstractAddrDock(model, parent)
{ {
@ -379,9 +432,18 @@ void RawAddrDock::updateDock()
proxyModel->sort(2, Qt::AscendingOrder); proxyModel->sort(2, Qt::AscendingOrder);
for (int i = 0; i < proxyModel->rowCount(); i++) { for (int i = 0; i < proxyModel->rowCount(); i++) {
QModelIndex idx = proxyModel->index(i, 0); QModelIndex idx = proxyModel->index(i, 0);
QString name = idx.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>().name;
RVA vaddr = idx.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>().vaddr;
int vsize = idx.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>().vsize;
addrDockScene->seekAddrMap[name] = vaddr;
addrDockScene->seekAddrSizeMap[name] = vsize;
RVA addr = idx.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>().paddr; RVA addr = idx.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>().paddr;
int size = idx.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>().size; int size = idx.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>().size;
QString name = idx.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>().name; addrDockScene->nameAddrMap[name] = addr;
addrDockScene->nameAddrSizeMap[name] = size;
if (size < heightThreshold) { if (size < heightThreshold) {
size = heightThreshold; size = heightThreshold;
} else { } else {
@ -390,14 +452,14 @@ void RawAddrDock::updateDock()
} }
QGraphicsRectItem *rect = new QGraphicsRectItem(rectOffset, y, rectWidth, size); QGraphicsRectItem *rect = new QGraphicsRectItem(rectOffset, y, rectWidth, size);
rect->setBrush(QBrush(idx.data(Qt::DecorationRole).value<QColor>())); rect->setBrush(QBrush(idx.data(Qt::DecorationRole).value<QColor>()));
graphicsScene->addItem(rect); addrDockScene->addItem(rect);
addTextItem(textColor, QPoint(0, y), QString("0x%1").arg(addr, 0, 16)); addTextItem(textColor, QPoint(0, y), QString("0x%1").arg(addr, 0, 16));
addTextItem(textColor, QPoint(rectOffset, y), QString::number(size)); addTextItem(textColor, QPoint(rectOffset, y), QString::number(size));
addTextItem(textColor, QPoint(rectOffset + rectWidth, y), name); addTextItem(textColor, QPoint(rectOffset + rectWidth, y), name);
namePosYMap[name] = y; addrDockScene->namePosYMap[name] = y;
nameHeightMap[name] = size; addrDockScene->nameHeightMap[name] = size;
y += size; y += size;
} }
@ -425,6 +487,12 @@ void VirtualAddrDock::updateDock()
RVA addr = idx.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>().vaddr; RVA addr = idx.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>().vaddr;
int size = idx.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>().vsize; int size = idx.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>().vsize;
QString name = idx.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>().name; QString name = idx.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>().name;
addrDockScene->seekAddrMap[name] = addr;
addrDockScene->seekAddrSizeMap[name] = size;
addrDockScene->nameAddrMap[name] = addr;
addrDockScene->nameAddrSizeMap[name] = size;
if (size < heightThreshold) { if (size < heightThreshold) {
size = heightThreshold; size = heightThreshold;
} else { } else {
@ -433,14 +501,14 @@ void VirtualAddrDock::updateDock()
} }
QGraphicsRectItem *rect = new QGraphicsRectItem(rectOffset, y, rectWidth, size); QGraphicsRectItem *rect = new QGraphicsRectItem(rectOffset, y, rectWidth, size);
rect->setBrush(QBrush(idx.data(Qt::DecorationRole).value<QColor>())); rect->setBrush(QBrush(idx.data(Qt::DecorationRole).value<QColor>()));
graphicsScene->addItem(rect); addrDockScene->addItem(rect);
addTextItem(textColor, QPoint(0, y), QString("0x%1").arg(addr, 0, 16)); addTextItem(textColor, QPoint(0, y), QString("0x%1").arg(addr, 0, 16));
addTextItem(textColor, QPoint(rectOffset, y), QString::number(size)); addTextItem(textColor, QPoint(rectOffset, y), QString::number(size));
addTextItem(textColor, QPoint(rectOffset + rectWidth, y), name); addTextItem(textColor, QPoint(rectOffset + rectWidth, y), name);
namePosYMap[name] = y; addrDockScene->namePosYMap[name] = y;
nameHeightMap[name] = size; addrDockScene->nameHeightMap[name] = size;
y += size; y += size;
} }

View File

@ -19,6 +19,8 @@ class QAbstractItemView;
class MainWindow; class MainWindow;
class SectionsWidget; class SectionsWidget;
class AbstractAddrDock; class AbstractAddrDock;
class AddrDockScene;
class QGraphicsSceneMouseEvent;
class RawAddrDock; class RawAddrDock;
class VirtualAddrDock; class VirtualAddrDock;
class QuickFilterView; class QuickFilterView;
@ -105,9 +107,6 @@ public:
virtual void updateDock(); virtual void updateDock();
protected slots:
void addTextItem(QColor color, QPoint pos, QString string);
protected: protected:
int indicatorWidth; int indicatorWidth;
int indicatorHeight; int indicatorHeight;
@ -117,16 +116,41 @@ protected:
int rectWidth; int rectWidth;
QColor indicatorColor; QColor indicatorColor;
QColor textColor; QColor textColor;
QGraphicsScene *graphicsScene; AddrDockScene *addrDockScene;
QGraphicsView *graphicsView; QGraphicsView *graphicsView;
SectionsProxyModel *proxyModel; SectionsProxyModel *proxyModel;
QHash<QString, int> namePosYMap;
QHash<QString, int> nameHeightMap; void addTextItem(QColor color, QPoint pos, QString string);
private: private:
void drawIndicator(QString name, float ratio); void drawIndicator(QString name, float ratio);
}; };
class AddrDockScene : public QGraphicsScene
{
Q_OBJECT
public:
explicit AddrDockScene(QWidget *parent = nullptr);
~AddrDockScene();
bool disableCenterOn;
QHash<QString, RVA> nameAddrMap;
QHash<QString, int> nameAddrSizeMap;
QHash<QString, RVA> seekAddrMap;
QHash<QString, int> seekAddrSizeMap;
QHash<QString, int> namePosYMap;
QHash<QString, int> nameHeightMap;
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
private:
RVA getAddrFromPos(int posY, bool seek);
};
class RawAddrDock : public AbstractAddrDock class RawAddrDock : public AbstractAddrDock
{ {
Q_OBJECT Q_OBJECT