diff options
| author | Alexander Taylor <alex@vector35.com> | 2025-04-02 20:03:51 -0400 |
|---|---|---|
| committer | Alexander Taylor <alex@vector35.com> | 2025-04-02 20:03:51 -0400 |
| commit | 1b32a95b3a88567b349e1d3a57dea2fea9f42961 (patch) | |
| tree | cce799bc75a63fe5dc6a4606e9a02b2ecb252dc7 /view/sharedcache | |
| parent | 58568cd94ea54723b95eaae83ccc387415ff8547 (diff) | |
Styling for data in shared cache view.
Diffstat (limited to 'view/sharedcache')
| -rw-r--r-- | view/sharedcache/ui/dsctriage.cpp | 71 | ||||
| -rw-r--r-- | view/sharedcache/ui/dsctriage.h | 20 | ||||
| -rw-r--r-- | view/sharedcache/ui/symboltable.cpp | 35 | ||||
| -rw-r--r-- | view/sharedcache/ui/symboltable.h | 117 |
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 |
