summaryrefslogtreecommitdiff
path: root/view/sharedcache/ui/symboltable.h
blob: ab0174f98b2b8239957cbdf034682a0fc6a3edaf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#pragma once

#include <sharedcacheapi.h>
#include "viewframe.h"

#include <QTableView>
#include <QStandardItemModel>
#include "filter.h"

#ifndef BINARYNINJA_DSCSYMBOLTABLE_H
#define BINARYNINJA_DSCSYMBOLTABLE_H

class SymbolTableView;


class SymbolTableModel : public QAbstractTableModel
{
Q_OBJECT
	SymbolTableView* m_parent;
	QFont m_font;
	std::string m_filter;

	std::vector<SharedCacheAPI::CacheSymbol> m_symbols;
	std::vector<SharedCacheAPI::CacheSymbol> m_filteredSymbols;

	// A pointer to either m_symbols or m_filteredSymbols, depending on whether a filter is applied.
	std::vector<SharedCacheAPI::CacheSymbol> *m_displaySymbols = nullptr;

public:
	explicit SymbolTableModel(SymbolTableView* parent);

	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 sort(int column, Qt::SortOrder order) 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;

	SymbolTableModel* m_model;

public:
	explicit SymbolTableView(QWidget* parent);
	~SymbolTableView() override;

	// Call this to populate the symbols from the given view.
	void populateSymbols(BinaryNinja::BinaryView& view);

	void scrollToFirstItem() override
	{
		if (model()->rowCount() > 0) {
			QModelIndex top = indexAt(rect().topLeft());
			if (top.isValid())
				scrollTo(top);
		}
	}

	void scrollToCurrentItem() override
	{
		QModelIndex currentIndex = selectionModel()->currentIndex();
		if (currentIndex.isValid())
			scrollTo(currentIndex);
	}

	void ensureSelection() override
	{
		QModelIndex current = selectionModel()->currentIndex();
		if (current.isValid() || model()->rowCount() == 0)
			return;

		if (auto top = indexAt(rect().topLeft()); top.isValid())
		{
			selectionModel()->select(top, QItemSelectionModel::ClearAndSelect);
			setCurrentIndex(top);
		}
	}


	void activateSelection() override
	{
		ensureSelection();
		if (auto current = selectionModel()->currentIndex(); current.isValid())
			emit activated(current);
	}

	SharedCacheAPI::CacheSymbol getSymbolAtRow(int row) const
	{
		return m_model->symbolAt(row);
	}

	void setFilter(const std::string& filter) override;
};


#endif  // BINARYNINJA_DSCSYMBOLTABLE_H