cutter/src/widgets/VTablesWidget.cpp

206 lines
6.2 KiB
C++
Raw Normal View History

2018-02-26 22:26:18 +00:00
#include <QShortcut>
#include <QModelIndex>
2018-02-26 22:26:18 +00:00
#include "core/MainWindow.h"
2018-10-17 07:55:53 +00:00
#include "common/Helpers.h"
2018-02-26 22:26:18 +00:00
#include "VTablesWidget.h"
#include "ui_VTablesWidget.h"
VTableModel::VTableModel(QList<VTableDescription> *vtables, QObject *parent)
: QAbstractItemModel(parent),
vtables(vtables)
{
}
QModelIndex VTableModel::index(int row, int column, const QModelIndex &parent) const
{
2018-03-21 20:32:32 +00:00
return createIndex(row, column, (quintptr) parent.isValid() ? parent.row() : -1);
2018-02-26 22:26:18 +00:00
}
QModelIndex VTableModel::parent(const QModelIndex &index) const
{
2018-03-21 20:32:32 +00:00
return index.isValid() && index.internalId() != (quintptr) - 1 ?
this->index(index.internalId(), index.column()) : QModelIndex();
2018-02-26 22:26:18 +00:00
}
int VTableModel::rowCount(const QModelIndex &parent) const
{
2018-03-21 20:32:32 +00:00
return parent.isValid() ? (parent.parent().isValid() ? 0 : vtables->at(
parent.row()).methods.count()) : vtables->count();
2018-02-26 22:26:18 +00:00
}
int VTableModel::columnCount(const QModelIndex &) const
{
return Columns::COUNT;
}
QVariant VTableModel::data(const QModelIndex &index, int role) const
{
QModelIndex parent = index.parent();
2018-03-21 20:32:32 +00:00
if (parent.isValid()) {
2019-01-31 16:45:58 +00:00
const BinClassMethodDescription &res = vtables->at(parent.row()).methods.at(index.row());
2018-03-21 20:32:32 +00:00
switch (role) {
2018-02-26 22:26:18 +00:00
case Qt::DisplayRole:
2018-03-21 20:32:32 +00:00
switch (index.column()) {
2018-02-26 22:26:18 +00:00
case NAME:
return res.name;
case ADDRESS:
return RAddressString(res.addr);
}
break;
case VTableDescriptionRole:
return QVariant::fromValue(res);
2018-02-26 22:26:18 +00:00
default:
break;
}
2018-03-21 20:32:32 +00:00
} else
switch (role) {
2018-02-26 22:26:18 +00:00
case Qt::DisplayRole:
2018-03-21 20:32:32 +00:00
switch (index.column()) {
2018-02-26 22:26:18 +00:00
case NAME:
return tr("VTable") + " " + QString::number(index.row() + 1);
2018-02-26 22:26:18 +00:00
case ADDRESS:
return RAddressString(vtables->at(index.row()).addr);
}
break;
2018-03-21 20:32:32 +00:00
case VTableDescriptionRole: {
const VTableDescription &res = vtables->at(index.row());
return QVariant::fromValue(res);
}
2018-02-26 22:26:18 +00:00
default:
break;
}
return QVariant();
}
QVariant VTableModel::headerData(int section, Qt::Orientation, int role) const
{
2018-03-21 20:32:32 +00:00
switch (role) {
2018-02-26 22:26:18 +00:00
case Qt::DisplayRole:
2018-03-21 20:32:32 +00:00
switch (section) {
2018-02-26 22:26:18 +00:00
case NAME:
return tr("Name");
case ADDRESS:
return tr("Address");
default:
break;
}
break;
2018-02-26 22:26:18 +00:00
default:
break;
}
return QVariant();
}
2018-03-21 20:32:32 +00:00
VTableSortFilterProxyModel::VTableSortFilterProxyModel(VTableModel *model, QObject *parent)
2018-02-26 22:26:18 +00:00
: QSortFilterProxyModel(parent)
{
setSourceModel(model);
setFilterCaseSensitivity(Qt::CaseInsensitive);
setSortCaseSensitivity(Qt::CaseInsensitive);
setFilterKeyColumn(VTableModel::NAME);
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
setRecursiveFilteringEnabled(true);
#endif
}
2018-03-21 20:32:32 +00:00
bool VTableSortFilterProxyModel::filterAcceptsRow(int source_row,
const QModelIndex &source_parent) const
2018-02-26 22:26:18 +00:00
{
2018-03-21 20:32:32 +00:00
if (QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent))
2018-02-26 22:26:18 +00:00
return true;
2018-03-21 20:32:32 +00:00
if (source_parent.isValid())
2018-02-26 22:26:18 +00:00
return QSortFilterProxyModel::filterAcceptsRow(source_parent.row(), QModelIndex());
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
2018-03-21 20:32:32 +00:00
else {
QAbstractItemModel *const model = sourceModel();
2018-02-26 22:26:18 +00:00
const QModelIndex source = model->index(source_row, 0, QModelIndex());
const int rows = model->rowCount(source);
2018-03-21 20:32:32 +00:00
for (int i = 0; i < rows; ++i)
if (QSortFilterProxyModel::filterAcceptsRow(i, source))
2018-02-26 22:26:18 +00:00
return true;
}
#endif
return false;
}
VTablesWidget::VTablesWidget(MainWindow *main) :
CutterDockWidget(main),
ui(new Ui::VTablesWidget),
tree(new CutterTreeWidget(this))
2018-02-26 22:26:18 +00:00
{
ui->setupUi(this);
// Add Status Bar footer
tree->addStatusBar(ui->verticalLayout);
2018-02-26 22:26:18 +00:00
model = new VTableModel(&vtables, this);
proxy = new VTableSortFilterProxyModel(model, this);
2018-02-26 22:26:18 +00:00
ui->vTableTreeView->setModel(proxy);
ui->vTableTreeView->sortByColumn(VTableModel::ADDRESS, Qt::AscendingOrder);
// Esc to clear the filter entry
QShortcut *clear_shortcut = new QShortcut(QKeySequence(Qt::Key_Escape), this);
connect(clear_shortcut, &QShortcut::activated, ui->quickFilterView, &QuickFilterView::clearFilter);
clear_shortcut->setContext(Qt::WidgetWithChildrenShortcut);
2018-02-26 22:26:18 +00:00
// Ctrl-F to show/hide the filter entry
QShortcut *search_shortcut = new QShortcut(QKeySequence::Find, this);
connect(search_shortcut, &QShortcut::activated, ui->quickFilterView, &QuickFilterView::showFilter);
search_shortcut->setContext(Qt::WidgetWithChildrenShortcut);
2018-03-21 20:32:32 +00:00
connect(ui->quickFilterView, SIGNAL(filterTextChanged(const QString &)), proxy,
SLOT(setFilterWildcard(const QString &)));
2018-02-26 22:26:18 +00:00
connect(ui->quickFilterView, SIGNAL(filterClosed()), ui->vTableTreeView, SLOT(setFocus()));
connect(ui->quickFilterView, &QuickFilterView::filterTextChanged, this, [this] {
tree->showItemsNumber(proxy->rowCount());
});
connect(Core(), &CutterCore::codeRebased, this, &VTablesWidget::refreshVTables);
connect(Core(), &CutterCore::refreshAll, this, &VTablesWidget::refreshVTables);
refreshDeferrer = createRefreshDeferrer([this]() { refreshVTables(); });
2018-02-26 22:26:18 +00:00
}
VTablesWidget::~VTablesWidget()
{
}
void VTablesWidget::refreshVTables()
{
if (!refreshDeferrer->attemptRefresh(nullptr)) {
return;
}
model->beginResetModel();
2018-04-12 06:33:30 +00:00
vtables = Core()->getAllVTables();
model->endResetModel();
2018-02-26 22:26:18 +00:00
qhelpers::adjustColumns(ui->vTableTreeView, 3, 0);
2018-02-26 22:26:18 +00:00
ui->vTableTreeView->setColumnWidth(0, 200);
tree->showItemsNumber(proxy->rowCount());
2018-02-26 22:26:18 +00:00
}
void VTablesWidget::on_vTableTreeView_doubleClicked(const QModelIndex &index)
{
2018-11-05 21:51:27 +00:00
if (!index.isValid()) {
return;
2018-11-05 21:51:27 +00:00
}
QModelIndex parent = index.parent();
2018-11-05 21:51:27 +00:00
if (parent.isValid()) {
Core()->seekAndShow(index.data(
2019-01-31 16:45:58 +00:00
VTableModel::VTableDescriptionRole).value<BinClassMethodDescription>().addr);
2018-11-05 21:51:27 +00:00
} else {
Core()->seekAndShow(index.data(
2018-09-30 20:00:53 +00:00
VTableModel::VTableDescriptionRole).value<VTableDescription>().addr);
2018-11-05 21:51:27 +00:00
}
}