mirror of
https://github.com/rizinorg/cutter.git
synced 2025-01-19 02:48:49 +00:00
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:
parent
8ff915c21a
commit
8e76a9aca5
@ -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);
|
||||||
graphicsView->centerOn(indicator);
|
|
||||||
|
if (!addrDockScene->disableCenterOn) {
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user