diff --git a/src/widgets/SectionsWidget.cpp b/src/widgets/SectionsWidget.cpp index 98d2129e..63f34765 100644 --- a/src/widgets/SectionsWidget.cpp +++ b/src/widgets/SectionsWidget.cpp @@ -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(§ions, 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().paddr; - size = idx.data(SectionsModel::SectionDescriptionRole).value().size; - break; - case SectionAddrDock::Virtual: - addr = idx.data(SectionsModel::SectionDescriptionRole).value().vaddr; - size = idx.data(SectionsModel::SectionDescriptionRole).value().vsize; - break; - default: - return; - } + RVA addr = idx.data(SectionsModel::SectionDescriptionRole).value().paddr; + int size = idx.data(SectionsModel::SectionDescriptionRole).value().size; QString name = idx.data(SectionsModel::SectionDescriptionRole).value().name; if (size < heightThreshold) { size = heightThreshold; @@ -393,9 +392,9 @@ void SectionAddrDock::updateDock() rect->setBrush(QBrush(idx.data(Qt::DecorationRole).value())); 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().vaddr; + int size = idx.data(SectionsModel::SectionDescriptionRole).value().vsize; + QString name = idx.data(SectionsModel::SectionDescriptionRole).value().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())); + 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; + } } diff --git a/src/widgets/SectionsWidget.h b/src/widgets/SectionsWidget.h index c4c22e7f..e4f1ca50 100644 --- a/src/widgets/SectionsWidget.h +++ b/src/widgets/SectionsWidget.h @@ -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 namePosYMap; QHash 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