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