Only one close button should be shown for PE-Bear thingy. (#993)

* Only one close button should be shown for the AddrMaps in the Section Widget
This commit is contained in:
Vanellope 2018-12-13 21:24:56 +09:00 committed by xarkes
parent 984681700b
commit 16ad5c9220
2 changed files with 177 additions and 111 deletions

View File

@ -138,7 +138,18 @@ SectionsWidget::SectionsWidget(MainWindow *main, QAction *action) :
{
setObjectName("SectionsWidget");
setWindowTitle(QStringLiteral("Sections"));
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
initSectionsTable();
initQuickFilter();
initAddrMapDocks();
initConnects();
}
SectionsWidget::~SectionsWidget() {}
void SectionsWidget::initSectionsTable()
{
sectionsTable = new CutterTreeView;
sectionsModel = new SectionsModel(&sections, this);
auto proxyModel = new SectionsProxyModel(sectionsModel, this);
@ -147,12 +158,10 @@ SectionsWidget::SectionsWidget(MainWindow *main, QAction *action) :
sectionsTable->setIndentation(10);
sectionsTable->setSortingEnabled(true);
sectionsTable->sortByColumn(SectionsModel::NameColumn, Qt::AscendingOrder);
}
connect(sectionsTable, SIGNAL(doubleClicked(const QModelIndex &)),
this, SLOT(onSectionsDoubleClicked(const QModelIndex &)));
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
connect(Core(), SIGNAL(refreshAll()), this, SLOT(refreshSections()));
void SectionsWidget::initQuickFilter()
{
quickFilterView = new QuickFilterView(this, false);
quickFilterView->setObjectName(QStringLiteral("quickFilterView"));
QSizePolicy sizePolicy1(QSizePolicy::Preferred, QSizePolicy::Maximum);
@ -162,24 +171,24 @@ SectionsWidget::SectionsWidget(MainWindow *main, QAction *action) :
quickFilterView->setSizePolicy(sizePolicy1);
QShortcut *search_shortcut = new QShortcut(QKeySequence::Find, this);
connect(search_shortcut, &QShortcut::activated, quickFilterView, &QuickFilterView::showFilter);
search_shortcut->setContext(Qt::WidgetWithChildrenShortcut);
connect(search_shortcut, &QShortcut::activated, quickFilterView, &QuickFilterView::showFilter);
QShortcut *clear_shortcut = new QShortcut(QKeySequence(Qt::Key_Escape), this);
connect(clear_shortcut, &QShortcut::activated, quickFilterView, &QuickFilterView::clearFilter);
clear_shortcut->setContext(Qt::WidgetWithChildrenShortcut);
connect(clear_shortcut, &QShortcut::activated, quickFilterView, &QuickFilterView::clearFilter);
}
connect(quickFilterView, SIGNAL(filterTextChanged(const QString &)), proxyModel,
SLOT(setFilterWildcard(const QString &)));
connect(quickFilterView, SIGNAL(filterClosed()), sectionsTable, SLOT(setFocus()));
void SectionsWidget::initAddrMapDocks()
{
dockWidgetContents = new QWidget(this);
QVBoxLayout *layout = new QVBoxLayout();
layout->addWidget(sectionsTable);
layout->addWidget(quickFilterView);
rawAddrDock = new SectionAddrDock(sectionsModel, SectionAddrDock::Raw, this);
virtualAddrDock = new SectionAddrDock(sectionsModel, SectionAddrDock::Virtual, this);
rawAddrDock = new RawAddrDock(sectionsModel, this);
virtualAddrDock = new VirtualAddrDock(sectionsModel, this);
addrDockWidget = new QWidget();
QHBoxLayout *addrDockLayout = new QHBoxLayout();
addrDockLayout->addWidget(rawAddrDock);
@ -207,7 +216,16 @@ SectionsWidget::SectionsWidget(MainWindow *main, QAction *action) :
layout->setMargin(0);
dockWidgetContents->setLayout(layout);
setWidget(dockWidgetContents);
}
void SectionsWidget::initConnects()
{
connect(sectionsTable, SIGNAL(doubleClicked(const QModelIndex &)),
this, SLOT(onSectionsDoubleClicked(const QModelIndex &)));
connect(Core(), SIGNAL(refreshAll()), this, SLOT(refreshSections()));
connect(quickFilterView, SIGNAL(filterTextChanged(const QString &)), proxyModel,
SLOT(setFilterWildcard(const QString &)));
connect(quickFilterView, SIGNAL(filterClosed()), sectionsTable, SLOT(setFocus()));
connect(this, &QDockWidget::visibilityChanged, this, [ = ](bool visibility) {
if (visibility) {
refreshSections();
@ -218,19 +236,8 @@ SectionsWidget::SectionsWidget(MainWindow *main, QAction *action) :
connect(toggleButton, &QToolButton::clicked, this, [ = ] {
toggleButton->hide();
addrDockWidget->show();
rawAddrDock->show();
virtualAddrDock->show();
});
indicatorWidth = 600;
indicatorHeight = 5;
indicatorParamPosY = 20;
connect(rawAddrDock, &QDockWidget::visibilityChanged, this, [ = ](bool visibility) {
if (!visibility) {
updateToggle();
}
});
connect(virtualAddrDock, &QDockWidget::visibilityChanged, this, [ = ](bool visibility) {
if (!visibility) {
updateToggle();
@ -238,17 +245,12 @@ SectionsWidget::SectionsWidget(MainWindow *main, QAction *action) :
});
}
SectionsWidget::~SectionsWidget() {}
void SectionsWidget::refreshSections()
{
sectionsModel->beginResetModel();
sections = Core()->getAllSections();
sectionsModel->endResetModel();
qhelpers::adjustColumns(sectionsTable, SectionsModel::ColumnCount, 0);
rawAddrDock->show();
virtualAddrDock->show();
rawAddrDock->updateDock();
virtualAddrDock->updateDock();
drawIndicatorOnAddrDocks();
@ -285,103 +287,100 @@ void SectionsWidget::drawIndicatorOnAddrDocks()
if (vsize > 0 && offset > vaddr) {
ratio = (float)(offset - vaddr) / (float)vsize;
}
updateIndicator(rawAddrDock, name, ratio);
updateIndicator(virtualAddrDock, name, ratio);
rawAddrDock->drawIndicator(name, ratio);
virtualAddrDock->drawIndicator(name, ratio);
return;
}
}
}
void SectionsWidget::updateIndicator(SectionAddrDock *targetDock, QString name, float ratio)
{
RVA offset = Core()->getOffset();
float padding = targetDock->nameHeightMap[name] * ratio;
int y = targetDock->namePosYMap[name] + (int)padding;
QColor color = targetDock->indicatorColor;
QGraphicsRectItem *indicator = new QGraphicsRectItem(QRectF(0, y, indicatorWidth, indicatorHeight));
indicator->setBrush(QBrush(color));
targetDock->graphicsScene->addItem(indicator);
targetDock->graphicsView->centerOn(indicator);
targetDock->addTextItem(color, QPoint(targetDock->rectOffset + targetDock->rectWidth, y - indicatorParamPosY), name);
targetDock->addTextItem(color, QPoint(0, y - indicatorParamPosY), QString("0x%1").arg(offset, 0, 16));
}
void SectionsWidget::updateToggle()
{
if (!rawAddrDock->isVisible() && !virtualAddrDock->isVisible()) {
if (!virtualAddrDock->isVisible()) {
addrDockWidget->hide();
toggleButton->show();
}
}
SectionAddrDock::SectionAddrDock(SectionsModel *model, AddrType type, QWidget *parent) :
AbstractAddrDock::AbstractAddrDock(SectionsModel *model, QWidget *parent) :
QDockWidget(parent),
graphicsScene(new QGraphicsScene),
graphicsView(new QGraphicsView)
{
setStyleSheet(QString("color:%1;").arg(ConfigColor("gui.dataoffset").name()));
switch (type) {
case SectionAddrDock::Raw:
setWindowTitle(tr("Raw"));
break;
case SectionAddrDock::Virtual:
setWindowTitle(tr("Virtual"));
break;
default:
return;
}
graphicsView->setScene(graphicsScene);
setWidget(graphicsView);
setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
proxyModel = new SectionsProxyModel(model, this);
addrType = type;
QWidget *w = new QWidget();
QVBoxLayout *layout = new QVBoxLayout();
layout->addWidget(graphicsView);
w->setLayout(layout);
setWidget(w);
setWidget(graphicsView);
indicatorWidth = 600;
indicatorHeight = 5;
indicatorParamPosY = 20;
heightThreshold = 30;
rectOffset = 100;
rectWidth = 400;
indicatorColor = ConfigColor("gui.navbar.err");
connect(this, &QDockWidget::featuresChanged, this, [ = ](){
setFeatures(QDockWidget::DockWidgetClosable);
});
textColor = ConfigColor("gui.dataoffset");
}
void SectionAddrDock::updateDock()
{
setFeatures(QDockWidget::DockWidgetClosable);
AbstractAddrDock::~AbstractAddrDock() {}
void AbstractAddrDock::updateDock()
{
graphicsScene->clear();
setStyleSheet(QString("color:%1;").arg(ConfigColor("gui.dataoffset").name()));
const QBrush bg = QBrush(ConfigColor("gui.background"));
graphicsScene->setBackgroundBrush(bg);
textColor = ConfigColor("gui.dataoffset");
}
void AbstractAddrDock::addTextItem(QColor color, QPoint pos, QString string)
{
QGraphicsTextItem *text = new QGraphicsTextItem;
text->setDefaultTextColor(color);
text->setPos(pos);
text->setPlainText(string);
graphicsScene->addItem(text);
}
void AbstractAddrDock::drawIndicator(QString name, float ratio)
{
RVA offset = Core()->getOffset();
float padding = nameHeightMap[name] * ratio;
int y = namePosYMap[name] + (int)padding;
QColor color = indicatorColor;
QGraphicsRectItem *indicator = new QGraphicsRectItem(QRectF(0, y, indicatorWidth, indicatorHeight));
indicator->setBrush(QBrush(color));
graphicsScene->addItem(indicator);
graphicsView->centerOn(indicator);
addTextItem(color, QPoint(rectOffset + rectWidth, y - indicatorParamPosY), name);
addTextItem(color, QPoint(0, y - indicatorParamPosY), QString("0x%1").arg(offset, 0, 16));
}
RawAddrDock::RawAddrDock(SectionsModel *model, QWidget *parent) :
AbstractAddrDock(model, parent)
{
setWindowTitle(tr("Raw"));
connect(this, &QDockWidget::featuresChanged, this, [ = ](){
setFeatures(QDockWidget::NoDockWidgetFeatures);
});
}
RawAddrDock::~RawAddrDock() {}
void RawAddrDock::updateDock()
{
AbstractAddrDock::updateDock();
setFeatures(QDockWidget::DockWidgetClosable);
int y = 0;
proxyModel->sort(2, Qt::AscendingOrder);
for (int i = 0; i < proxyModel->rowCount(); i++) {
QModelIndex idx = proxyModel->index(i, 0);
RVA addr;
int size;
switch (addrType) {
case SectionAddrDock::Raw:
addr = idx.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>().paddr;
size = idx.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>().size;
break;
case SectionAddrDock::Virtual:
addr = idx.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>().vaddr;
size = idx.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>().vsize;
break;
default:
return;
}
RVA addr = idx.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>().paddr;
int size = idx.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>().size;
QString name = idx.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>().name;
if (size < heightThreshold) {
size = heightThreshold;
@ -393,9 +392,9 @@ void SectionAddrDock::updateDock()
rect->setBrush(QBrush(idx.data(Qt::DecorationRole).value<QColor>()));
graphicsScene->addItem(rect);
addTextItem(ConfigColor("gui.dataoffset"), QPoint(0, y), QString("0x%1").arg(addr, 0, 16));
addTextItem(ConfigColor("gui.dataoffset"), QPoint(rectOffset, y), QString::number(size));
addTextItem(ConfigColor("gui.dataoffset"), QPoint(rectOffset + rectWidth, y), name);
addTextItem(textColor, QPoint(0, y), QString("0x%1").arg(addr, 0, 16));
addTextItem(textColor, QPoint(rectOffset, y), QString::number(size));
addTextItem(textColor, QPoint(rectOffset + rectWidth, y), name);
namePosYMap[name] = y;
nameHeightMap[name] = size;
@ -404,11 +403,45 @@ void SectionAddrDock::updateDock()
}
}
void SectionAddrDock::addTextItem(QColor color, QPoint pos, QString string)
VirtualAddrDock::VirtualAddrDock(SectionsModel *model, QWidget *parent) :
AbstractAddrDock(model, parent)
{
QGraphicsTextItem *text = new QGraphicsTextItem;
text->setDefaultTextColor(color);
text->setPos(pos);
text->setPlainText(string);
graphicsScene->addItem(text);
setWindowTitle(tr("Virtual"));
connect(this, &QDockWidget::featuresChanged, this, [ = ](){
setFeatures(QDockWidget::DockWidgetClosable);
});
}
VirtualAddrDock::~VirtualAddrDock() {}
void VirtualAddrDock::updateDock()
{
AbstractAddrDock::updateDock();
setFeatures(QDockWidget::NoDockWidgetFeatures);
int y = 0;
proxyModel->sort(2, Qt::AscendingOrder);
for (int i = 0; i < proxyModel->rowCount(); i++) {
QModelIndex idx = proxyModel->index(i, 0);
RVA addr = idx.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>().vaddr;
int size = idx.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>().vsize;
QString name = idx.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>().name;
if (size < heightThreshold) {
size = heightThreshold;
} else {
size /= heightThreshold;
size = std::max(size, heightThreshold);
}
QGraphicsRectItem *rect = new QGraphicsRectItem(rectOffset, y, rectWidth, size);
rect->setBrush(QBrush(idx.data(Qt::DecorationRole).value<QColor>()));
graphicsScene->addItem(rect);
addTextItem(textColor, QPoint(0, y), QString("0x%1").arg(addr, 0, 16));
addTextItem(textColor, QPoint(rectOffset, y), QString::number(size));
addTextItem(textColor, QPoint(rectOffset + rectWidth, y), name);
namePosYMap[name] = y;
nameHeightMap[name] = size;
y += size;
}
}

View File

@ -18,7 +18,9 @@ class CutterTreeView;
class QAbstractItemView;
class MainWindow;
class SectionsWidget;
class SectionAddrDock;
class AbstractAddrDock;
class RawAddrDock;
class VirtualAddrDock;
class QuickFilterView;
class QGraphicsView;
class QGraphicsRectItem;
@ -79,41 +81,72 @@ private:
QuickFilterView *quickFilterView;
QWidget *addrDockWidget;
SectionAddrDock *rawAddrDock;
SectionAddrDock *virtualAddrDock;
RawAddrDock *rawAddrDock;
VirtualAddrDock *virtualAddrDock;
QToolButton *toggleButton;
int indicatorWidth;
int indicatorHeight;
int indicatorParamPosY;
void initSectionsTable();
void initQuickFilter();
void initConnects();
void initAddrMapDocks();
void drawIndicatorOnAddrDocks();
void updateIndicator(SectionAddrDock *targetDock, QString name, float ratio);
void updateToggle();
};
class SectionAddrDock : public QDockWidget
class AbstractAddrDock : public QDockWidget
{
Q_OBJECT
friend SectionsWidget;
private slots:
void updateDock();
public:
explicit AbstractAddrDock(SectionsModel *model, QWidget *parent = nullptr);
~AbstractAddrDock();
virtual void updateDock();
protected slots:
void addTextItem(QColor color, QPoint pos, QString string);
private:
enum AddrType { Raw = 0, Virtual };
protected:
int indicatorWidth;
int indicatorHeight;
int indicatorParamPosY;
int heightThreshold;
int rectOffset;
int rectWidth;
QColor indicatorColor;
explicit SectionAddrDock(SectionsModel *model, AddrType type, QWidget *parent = nullptr);
QColor textColor;
QGraphicsScene *graphicsScene;
QGraphicsView *graphicsView;
SectionsProxyModel *proxyModel;
AddrType addrType;
QHash<QString, int> namePosYMap;
QHash<QString, int> nameHeightMap;
private:
void drawIndicator(QString name, float ratio);
};
class RawAddrDock : public AbstractAddrDock
{
Q_OBJECT
public:
explicit RawAddrDock(SectionsModel *model, QWidget *parent = nullptr);
~RawAddrDock();
void updateDock() override;
};
class VirtualAddrDock : public AbstractAddrDock
{
Q_OBJECT
public:
explicit VirtualAddrDock(SectionsModel *model, QWidget *parent = nullptr);
~VirtualAddrDock();
void updateDock() override;
};
#endif // SECTIONSWIDGET_H