summaryrefslogtreecommitdiff
path: root/view/sharedcache
diff options
context:
space:
mode:
authorAlexander Taylor <alex@vector35.com>2025-04-02 20:03:51 -0400
committerAlexander Taylor <alex@vector35.com>2025-04-02 20:03:51 -0400
commit1b32a95b3a88567b349e1d3a57dea2fea9f42961 (patch)
treecce799bc75a63fe5dc6a4606e9a02b2ecb252dc7 /view/sharedcache
parent58568cd94ea54723b95eaae83ccc387415ff8547 (diff)
Styling for data in shared cache view.
Diffstat (limited to 'view/sharedcache')
-rw-r--r--view/sharedcache/ui/dsctriage.cpp71
-rw-r--r--view/sharedcache/ui/dsctriage.h20
-rw-r--r--view/sharedcache/ui/symboltable.cpp35
-rw-r--r--view/sharedcache/ui/symboltable.h117
4 files changed, 144 insertions, 99 deletions
diff --git a/view/sharedcache/ui/dsctriage.cpp b/view/sharedcache/ui/dsctriage.cpp
index 8ed9728c..91e1d24c 100644
--- a/view/sharedcache/ui/dsctriage.cpp
+++ b/view/sharedcache/ui/dsctriage.cpp
@@ -97,30 +97,27 @@ DSCTriageView::DSCTriageView(QWidget* parent, BinaryViewRef data) : QWidget(pare
auto loadImageTable = new FilterableTableView;
{
m_imageModel = new QStandardItemModel(0, 3, loadImageTable);
- {
- m_imageModel->setHorizontalHeaderLabels({"Address", "Loaded", "Name"});
- } // loadImageModel
+ m_imageModel->setHorizontalHeaderLabels({"Address", "Loaded", "Name"});
- // Show the icon in the loaded column.
+ // Apply custom column styling
+ loadImageTable->setItemDelegateForColumn(0, new AddressColorDelegate(loadImageTable));
loadImageTable->setItemDelegateForColumn(1, new LoadedDelegate());
auto loadImageButton = new QPushButton();
- {
- connect(loadImageButton, &QPushButton::clicked,
- [loadImageTable, loadImagesWithAddr](bool) {
- auto selected = loadImageTable->selectionModel()->selectedRows();
- std::vector<uint64_t> addresses;
- for (const auto& idx : selected)
- {
- // Skip rows hidden by the filter.
- if (loadImageTable->isRowHidden(idx.row()))
- continue;
- addresses.push_back(idx.data().toString().toULongLong(nullptr, 16));
- }
- loadImagesWithAddr(addresses);
- });
- loadImageButton->setText("Load Selected");
- } // loadImageButton
+ connect(loadImageButton, &QPushButton::clicked,
+ [loadImageTable, loadImagesWithAddr](bool) {
+ auto selected = loadImageTable->selectionModel()->selectedRows();
+ std::vector<uint64_t> addresses;
+ for (const auto& idx : selected)
+ {
+ // Skip rows hidden by the filter.
+ if (loadImageTable->isRowHidden(idx.row()))
+ continue;
+ addresses.push_back(idx.data().toString().toULongLong(nullptr, 16));
+ }
+ loadImagesWithAddr(addresses);
+ });
+ loadImageButton->setText("Load Selected");
auto refreshDataButton = new QPushButton();
{
@@ -130,17 +127,14 @@ DSCTriageView::DSCTriageView(QWidget* parent, BinaryViewRef data) : QWidget(pare
} // refreshDataButton
auto loadImageFilterEdit = new FilterEdit(loadImageTable);
- {
- connect(loadImageFilterEdit, &FilterEdit::textChanged, [loadImageTable](const QString& filter) {
- loadImageTable->setFilter(filter.toStdString());
- });
- } // loadImageFilterEdit
+ connect(loadImageFilterEdit, &FilterEdit::textChanged, [loadImageTable](const QString& filter) {
+ loadImageTable->setFilter(filter.toStdString());
+ });
- connect(loadImageTable, &FilterableTableView::activated, this, [=](const QModelIndex& index)
- {
- auto addr = m_imageModel->item(index.row(), 0)->text().toULongLong(nullptr, 16);
- loadImagesWithAddr({addr});
- });
+ connect(loadImageTable, &FilterableTableView::activated, this, [=](const QModelIndex& index) {
+ auto addr = m_imageModel->item(index.row(), 0)->text().toULongLong(nullptr, 16);
+ loadImagesWithAddr({addr});
+ });
auto loadImageLayout = new QVBoxLayout;
loadImageLayout->addWidget(loadImageFilterEdit);
@@ -178,11 +172,12 @@ DSCTriageView::DSCTriageView(QWidget* parent, BinaryViewRef data) : QWidget(pare
m_symbolTable = new SymbolTableView(this);
{
auto symbolFilterEdit = new FilterEdit(m_symbolTable);
- {
- connect(symbolFilterEdit, &FilterEdit::textChanged, [this](const QString& filter) {
- m_symbolTable->setFilter(filter.toStdString());
- });
- }
+ connect(symbolFilterEdit, &FilterEdit::textChanged, [this](const QString& filter) {
+ m_symbolTable->setFilter(filter.toStdString());
+ });
+
+ // Apply custom column styling
+ m_symbolTable->setItemDelegateForColumn(0, new AddressColorDelegate(m_symbolTable));
auto loadSymbolImageButton = new QPushButton();
{
@@ -270,6 +265,9 @@ DSCTriageView::DSCTriageView(QWidget* parent, BinaryViewRef data) : QWidget(pare
m_mappingModel = new QStandardItemModel(0, 4, mappingTable);
m_mappingModel->setHorizontalHeaderLabels({"Address", "Size", "File Address", "File Path"});
+ // Apply custom column styling
+ mappingTable->setItemDelegateForColumn(0, new AddressColorDelegate(mappingTable));
+
mappingTable->setModel(m_mappingModel);
mappingTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
@@ -290,6 +288,9 @@ DSCTriageView::DSCTriageView(QWidget* parent, BinaryViewRef data) : QWidget(pare
m_regionModel = new QStandardItemModel(0, 4, regionTable);
m_regionModel->setHorizontalHeaderLabels({"Address", "Size", "Type", "Name"});
+ // Apply custom column styling
+ regionTable->setItemDelegateForColumn(0, new AddressColorDelegate(regionTable));
+
regionTable->setModel(m_regionModel);
regionTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
diff --git a/view/sharedcache/ui/dsctriage.h b/view/sharedcache/ui/dsctriage.h
index 243f7bc8..edab8358 100644
--- a/view/sharedcache/ui/dsctriage.h
+++ b/view/sharedcache/ui/dsctriage.h
@@ -14,9 +14,28 @@
#include "filter.h"
#include "symboltable.h"
+#include "ui/fontsettings.h"
+
#ifndef BINARYNINJA_DSCTRIAGE_H
#define BINARYNINJA_DSCTRIAGE_H
+class AddressColorDelegate : public QStyledItemDelegate
+{
+
+public:
+ AddressColorDelegate(QObject* parent = nullptr) : QStyledItemDelegate(parent) {}
+
+ void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override
+ {
+ QStyleOptionViewItem opt = option;
+ initStyleOption(&opt, index);
+
+ opt.palette.setColor(QPalette::Text, getThemeColor(BNThemeColor::AddressColor));
+
+ QStyledItemDelegate::paint(painter, opt, index);
+ }
+};
+
class FilterableTableView : public QTableView, public FilterTarget {
Q_OBJECT
@@ -26,6 +45,7 @@ public:
explicit FilterableTableView(QWidget* parent = nullptr, bool filterByHiding = true)
: QTableView(parent), m_filterByHiding(filterByHiding) {
viewport()->installEventFilter(this);
+ setFont(getMonospaceFont(parent));
}
~FilterableTableView() override = default;
diff --git a/view/sharedcache/ui/symboltable.cpp b/view/sharedcache/ui/symboltable.cpp
index f4a062da..c96ce086 100644
--- a/view/sharedcache/ui/symboltable.cpp
+++ b/view/sharedcache/ui/symboltable.cpp
@@ -3,6 +3,8 @@
#include <QHeaderView>
+#include "ui/fontsettings.h"
+
#include "binaryninjaapi.h"
using namespace BinaryNinja;
@@ -10,6 +12,8 @@ using namespace SharedCacheAPI;
SymbolTableModel::SymbolTableModel(SymbolTableView* parent)
: QAbstractTableModel(parent), m_parent(parent) {
+ // TODO: Need to implement updating this font if it is changed by the user
+ m_font = getMonospaceFont(parent);
}
int SymbolTableModel::rowCount(const QModelIndex& parent) const {
@@ -24,20 +28,31 @@ int SymbolTableModel::columnCount(const QModelIndex& parent) const {
}
QVariant SymbolTableModel::data(const QModelIndex& index, int role) const {
- if (!index.isValid() || role != Qt::DisplayRole) {
+ if (!index.isValid() || (role != Qt::DisplayRole && role != Qt::FontRole)) {
return QVariant();
}
- auto symbol = symbolAt(index.row());
- auto symbolType = GetSymbolTypeAsString(symbol.type);
+ switch (role)
+ {
+ case Qt::DisplayRole:
+ {
+ auto symbol = symbolAt(index.row());
+ auto symbolType = GetSymbolTypeAsString(symbol.type);
- switch (index.column()) {
- case 0: // Address column
- return QString("0x%1").arg(symbol.address, 0, 16); // Display address as hexadecimal
- case 1: // Type column
- return QString::fromUtf8(symbolType.c_str(), symbolType.size());
- case 2: // Name column
- return QString::fromUtf8(symbol.name.c_str(), symbol.name.size());
+ switch (index.column())
+ {
+ case 0: // Address column
+ return QString("0x%1").arg(symbol.address, 0, 16); // Display address as hexadecimal
+ case 1: // Type column
+ return QString::fromUtf8(symbolType.c_str(), symbolType.size());
+ case 2: // Name column
+ return QString::fromUtf8(symbol.name.c_str(), symbol.name.size());
+ default:
+ return QVariant();
+ }
+ }
+ case Qt::FontRole:
+ return m_font;
default:
return QVariant();
}
diff --git a/view/sharedcache/ui/symboltable.h b/view/sharedcache/ui/symboltable.h
index 53c71874..2fc5c892 100644
--- a/view/sharedcache/ui/symboltable.h
+++ b/view/sharedcache/ui/symboltable.h
@@ -8,79 +8,88 @@
#include <QStandardItemModel>
#include "filter.h"
+
class SymbolTableView;
-class SymbolTableModel : public QAbstractTableModel {
- Q_OBJECT
- SymbolTableView* m_parent;
- std::string m_filter;
- std::vector<SharedCacheAPI::CacheSymbol> m_preparedSymbols {};
- // the symbols we actually use.
- std::vector<SharedCacheAPI::CacheSymbol> m_modelSymbols {};
+class SymbolTableModel : public QAbstractTableModel
+{
+Q_OBJECT
+ SymbolTableView* m_parent;
+ QFont m_font;
+ std::string m_filter;
+ std::vector<SharedCacheAPI::CacheSymbol> m_preparedSymbols{};
+ // These are the symbols we actually use
+ std::vector<SharedCacheAPI::CacheSymbol> m_modelSymbols{};
public:
- explicit SymbolTableModel(SymbolTableView* parent);
-
- int rowCount(const QModelIndex& parent = QModelIndex()) const override;
- int columnCount(const QModelIndex& parent = QModelIndex()) const override;
- QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
- QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
+ explicit SymbolTableModel(SymbolTableView* parent);
- void updateSymbols(std::vector<SharedCacheAPI::CacheSymbol>&& symbols);
-
- void setFilter(std::string text);
-
- const SharedCacheAPI::CacheSymbol& symbolAt(int row) const;
+ int rowCount(const QModelIndex& parent) const override;
+ int columnCount(const QModelIndex& parent) const override;
+ QVariant data(const QModelIndex& index, int role) const override;
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
+ void updateSymbols(std::vector<SharedCacheAPI::CacheSymbol>&& symbols);
+ void setFilter(std::string text);
+ const SharedCacheAPI::CacheSymbol& symbolAt(int row) const;
};
class SymbolTableView : public QTableView, public FilterTarget
{
- Q_OBJECT
- friend class SymbolTableModel;
+Q_OBJECT
+ friend class SymbolTableModel;
- SymbolTableModel* m_model;
+ SymbolTableModel* m_model;
public:
- SymbolTableView(QWidget* parent);
- virtual ~SymbolTableView() override;
+ explicit SymbolTableView(QWidget* parent);
+
+ ~SymbolTableView() override;
- void scrollToFirstItem() override {
- if (model()->rowCount() > 0) {
- scrollTo(model()->index(0, 0));
- }
- }
+ void scrollToFirstItem() override
+ {
+ if (model()->rowCount() > 0)
+ {
+ scrollTo(model()->index(0, 0));
+ }
+ }
- // Call this to populate the symbols from the given view.
- void populateSymbols(BinaryNinja::BinaryView& view);
+ // Call this to populate the symbols from the given view.
+ void populateSymbols(BinaryNinja::BinaryView& view);
- void scrollToCurrentItem() override {
- QModelIndex currentIndex = selectionModel()->currentIndex();
- if (currentIndex.isValid()) {
- scrollTo(currentIndex);
- }
- }
+ void scrollToCurrentItem() override
+ {
+ QModelIndex currentIndex = selectionModel()->currentIndex();
+ if (currentIndex.isValid())
+ {
+ scrollTo(currentIndex);
+ }
+ }
- void selectFirstItem() override {
- if (model()->rowCount() > 0) {
- QModelIndex firstIndex = model()->index(0, 0);
- selectionModel()->select(firstIndex, QItemSelectionModel::ClearAndSelect);
- }
- }
+ void selectFirstItem() override
+ {
+ if (model()->rowCount() > 0)
+ {
+ QModelIndex firstIndex = model()->index(0, 0);
+ selectionModel()->select(firstIndex, QItemSelectionModel::ClearAndSelect);
+ }
+ }
- void activateFirstItem() override {
- if (model()->rowCount() > 0) {
- QModelIndex firstIndex = model()->index(0, 0);
- setCurrentIndex(firstIndex);
- emit activated(firstIndex);
- }
- }
+ void activateFirstItem() override
+ {
+ if (model()->rowCount() > 0)
+ {
+ QModelIndex firstIndex = model()->index(0, 0);
+ setCurrentIndex(firstIndex);
+ emit activated(firstIndex);
+ }
+ }
- SharedCacheAPI::CacheSymbol getSymbolAtRow(int row) const
- {
- return m_model->symbolAt(row);
- }
+ SharedCacheAPI::CacheSymbol getSymbolAtRow(int row) const
+ {
+ return m_model->symbolAt(row);
+ }
- void setFilter(const std::string& filter) override;
+ void setFilter(const std::string& filter) override;
}; \ No newline at end of file