1 #include "HeadersWidget.h"
2 #include "ui_ListDockWidget.h"
3 #include "core/MainWindow.h"
4 #include "common/Helpers.h"
5 
HeadersModel(QList<HeaderDescription> * headers,QObject * parent)6 HeadersModel::HeadersModel(QList<HeaderDescription> *headers, QObject *parent)
7     : AddressableItemModel<QAbstractListModel>(parent),
8       headers(headers)
9 {
10 }
11 
rowCount(const QModelIndex &) const12 int HeadersModel::rowCount(const QModelIndex &) const
13 {
14     return headers->count();
15 }
16 
columnCount(const QModelIndex &) const17 int HeadersModel::columnCount(const QModelIndex &) const
18 {
19     return HeadersModel::ColumnCount;
20 }
21 
data(const QModelIndex & index,int role) const22 QVariant HeadersModel::data(const QModelIndex &index, int role) const
23 {
24     if (index.row() >= headers->count())
25         return QVariant();
26 
27     const HeaderDescription &header = headers->at(index.row());
28 
29     switch (role) {
30     case Qt::DisplayRole:
31         switch (index.column()) {
32         case OffsetColumn:
33             return RAddressString(header.vaddr);
34         case NameColumn:
35             return header.name;
36         case ValueColumn:
37             return header.value;
38         case CommentColumn:
39             return Core()->getCommentAt(header.vaddr);
40         default:
41             return QVariant();
42         }
43     case HeaderDescriptionRole:
44         return QVariant::fromValue(header);
45     default:
46         return QVariant();
47     }
48 }
49 
headerData(int section,Qt::Orientation,int role) const50 QVariant HeadersModel::headerData(int section, Qt::Orientation, int role) const
51 {
52     switch (role) {
53     case Qt::DisplayRole:
54         switch (section) {
55         case OffsetColumn:
56             return tr("Offset");
57         case NameColumn:
58             return tr("Name");
59         case ValueColumn:
60             return tr("Value");
61         case CommentColumn:
62             return tr("Comment");
63         default:
64             return QVariant();
65         }
66     default:
67         return QVariant();
68     }
69 }
70 
address(const QModelIndex & index) const71 RVA HeadersModel::address(const QModelIndex &index) const
72 {
73     const HeaderDescription &header = headers->at(index.row());
74     return header.vaddr;
75 }
76 
name(const QModelIndex & index) const77 QString HeadersModel::name(const QModelIndex &index) const
78 {
79     const HeaderDescription &header = headers->at(index.row());
80     return header.name;
81 }
82 
HeadersProxyModel(HeadersModel * sourceModel,QObject * parent)83 HeadersProxyModel::HeadersProxyModel(HeadersModel *sourceModel, QObject *parent)
84     : AddressableFilterProxyModel(sourceModel, parent)
85 {
86 }
87 
filterAcceptsRow(int row,const QModelIndex & parent) const88 bool HeadersProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const
89 {
90     QModelIndex index = sourceModel()->index(row, 0, parent);
91     HeaderDescription item = index.data(HeadersModel::HeaderDescriptionRole).value<HeaderDescription>();
92     return item.name.contains(filterRegExp());
93 }
94 
lessThan(const QModelIndex & left,const QModelIndex & right) const95 bool HeadersProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
96 {
97     HeaderDescription leftHeader = left.data(
98                                        HeadersModel::HeaderDescriptionRole).value<HeaderDescription>();
99     HeaderDescription rightHeader = right.data(
100                                         HeadersModel::HeaderDescriptionRole).value<HeaderDescription>();
101 
102     switch (left.column()) {
103     case HeadersModel::OffsetColumn:
104         return leftHeader.vaddr < rightHeader.vaddr;
105     case HeadersModel::NameColumn:
106         return leftHeader.name < rightHeader.name;
107     case HeadersModel::ValueColumn:
108         return leftHeader.value < rightHeader.value;
109     case HeadersModel::CommentColumn:
110         return Core()->getCommentAt(leftHeader.vaddr) < Core()->getCommentAt(rightHeader.vaddr);
111     default:
112         break;
113     }
114 
115     return leftHeader.vaddr < rightHeader.vaddr;
116 }
117 
HeadersWidget(MainWindow * main)118 HeadersWidget::HeadersWidget(MainWindow *main) :
119     ListDockWidget(main)
120 {
121     setWindowTitle(tr("Headers"));
122     setObjectName("HeadersWidget");
123 
124     headersModel = new HeadersModel(&headers, this);
125     headersProxyModel = new HeadersProxyModel(headersModel, this);
126     setModels(headersProxyModel);
127     ui->treeView->sortByColumn(HeadersModel::OffsetColumn, Qt::AscendingOrder);
128 
129     ui->quickFilterView->closeFilter();
130     showCount(false);
131 
132     connect(Core(), &CutterCore::codeRebased, this, &HeadersWidget::refreshHeaders);
133     connect(Core(), &CutterCore::refreshAll, this, &HeadersWidget::refreshHeaders);
134     connect(Core(), &CutterCore::commentsChanged, this, [this]() {
135         qhelpers::emitColumnChanged(headersModel, HeadersModel::CommentColumn);
136     });
137 }
138 
~HeadersWidget()139 HeadersWidget::~HeadersWidget() {}
140 
refreshHeaders()141 void HeadersWidget::refreshHeaders()
142 {
143     headersModel->beginResetModel();
144     headers = Core()->getAllHeaders();
145     headersModel->endResetModel();
146 
147     ui->treeView->resizeColumnToContents(0);
148     ui->treeView->resizeColumnToContents(1);
149 }
150