1 #include "SymbolsWidget.h"
2 #include "ui_ListDockWidget.h"
3 #include "core/MainWindow.h"
4 #include "common/Helpers.h"
5
6 #include <QShortcut>
7
SymbolsModel(QList<SymbolDescription> * symbols,QObject * parent)8 SymbolsModel::SymbolsModel(QList<SymbolDescription> *symbols, QObject *parent)
9 : AddressableItemModel<QAbstractListModel>(parent),
10 symbols(symbols)
11 {
12 }
13
rowCount(const QModelIndex &) const14 int SymbolsModel::rowCount(const QModelIndex &) const
15 {
16 return symbols->count();
17 }
18
columnCount(const QModelIndex &) const19 int SymbolsModel::columnCount(const QModelIndex &) const
20 {
21 return SymbolsModel::ColumnCount;
22 }
23
data(const QModelIndex & index,int role) const24 QVariant SymbolsModel::data(const QModelIndex &index, int role) const
25 {
26 if (index.row() >= symbols->count()) {
27 return QVariant();
28 }
29
30 const SymbolDescription &symbol = symbols->at(index.row());
31
32 switch (role) {
33 case Qt::DisplayRole:
34 switch (index.column()) {
35 case SymbolsModel::AddressColumn:
36 return RAddressString(symbol.vaddr);
37 case SymbolsModel::TypeColumn:
38 return QString("%1 %2").arg(symbol.bind, symbol.type).trimmed();
39 case SymbolsModel::NameColumn:
40 return symbol.name;
41 case SymbolsModel::CommentColumn:
42 return Core()->getCommentAt(symbol.vaddr);
43 default:
44 return QVariant();
45 }
46 case SymbolsModel::SymbolDescriptionRole:
47 return QVariant::fromValue(symbol);
48 default:
49 return QVariant();
50 }
51 }
52
headerData(int section,Qt::Orientation,int role) const53 QVariant SymbolsModel::headerData(int section, Qt::Orientation, int role) const
54 {
55 switch (role) {
56 case Qt::DisplayRole:
57 switch (section) {
58 case SymbolsModel::AddressColumn:
59 return tr("Address");
60 case SymbolsModel::TypeColumn:
61 return tr("Type");
62 case SymbolsModel::NameColumn:
63 return tr("Name");
64 case SymbolsModel::CommentColumn:
65 return tr("Comment");
66 default:
67 return QVariant();
68 }
69 default:
70 return QVariant();
71 }
72 }
73
address(const QModelIndex & index) const74 RVA SymbolsModel::address(const QModelIndex &index) const
75 {
76 const SymbolDescription &symbol = symbols->at(index.row());
77 return symbol.vaddr;
78 }
79
name(const QModelIndex & index) const80 QString SymbolsModel::name(const QModelIndex &index) const
81 {
82 const SymbolDescription &symbol = symbols->at(index.row());
83 return symbol.name;
84 }
85
SymbolsProxyModel(SymbolsModel * sourceModel,QObject * parent)86 SymbolsProxyModel::SymbolsProxyModel(SymbolsModel *sourceModel, QObject *parent)
87 : AddressableFilterProxyModel(sourceModel, parent)
88 {
89 setFilterCaseSensitivity(Qt::CaseInsensitive);
90 setSortCaseSensitivity(Qt::CaseInsensitive);
91 }
92
filterAcceptsRow(int row,const QModelIndex & parent) const93 bool SymbolsProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const
94 {
95 QModelIndex index = sourceModel()->index(row, 0, parent);
96 auto symbol = index.data(SymbolsModel::SymbolDescriptionRole).value<SymbolDescription>();
97
98 return symbol.name.contains(filterRegExp());
99 }
100
lessThan(const QModelIndex & left,const QModelIndex & right) const101 bool SymbolsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
102 {
103 auto leftSymbol = left.data(SymbolsModel::SymbolDescriptionRole).value<SymbolDescription>();
104 auto rightSymbol = right.data(SymbolsModel::SymbolDescriptionRole).value<SymbolDescription>();
105
106 switch (left.column()) {
107 case SymbolsModel::AddressColumn:
108 return leftSymbol.vaddr < rightSymbol.vaddr;
109 case SymbolsModel::TypeColumn:
110 return leftSymbol.type < rightSymbol.type;
111 case SymbolsModel::NameColumn:
112 return leftSymbol.name < rightSymbol.name;
113 case SymbolsModel::CommentColumn:
114 return Core()->getCommentAt(leftSymbol.vaddr) < Core()->getCommentAt(rightSymbol.vaddr);
115 default:
116 break;
117 }
118
119 return false;
120 }
121
SymbolsWidget(MainWindow * main)122 SymbolsWidget::SymbolsWidget(MainWindow *main) :
123 ListDockWidget(main)
124 {
125 setWindowTitle(tr("Symbols"));
126 setObjectName("SymbolsWidget");
127
128 symbolsModel = new SymbolsModel(&symbols, this);
129 symbolsProxyModel = new SymbolsProxyModel(symbolsModel, this);
130 setModels(symbolsProxyModel);
131 ui->treeView->sortByColumn(SymbolsModel::AddressColumn, Qt::AscendingOrder);
132
133 connect(Core(), &CutterCore::codeRebased, this, &SymbolsWidget::refreshSymbols);
134 connect(Core(), &CutterCore::refreshAll, this, &SymbolsWidget::refreshSymbols);
135 connect(Core(), &CutterCore::commentsChanged, this, [this]() {
136 qhelpers::emitColumnChanged(symbolsModel, SymbolsModel::CommentColumn);
137 });
138 }
139
~SymbolsWidget()140 SymbolsWidget::~SymbolsWidget() {}
141
refreshSymbols()142 void SymbolsWidget::refreshSymbols()
143 {
144 symbolsModel->beginResetModel();
145 symbols = Core()->getAllSymbols();
146 symbolsModel->endResetModel();
147
148 qhelpers::adjustColumns(ui->treeView, SymbolsModel::ColumnCount, 0);
149 }
150