diff --git a/src/widgets/flagswidget.cpp b/src/widgets/flagswidget.cpp index 1a54171d..78dc3251 100644 --- a/src/widgets/flagswidget.cpp +++ b/src/widgets/flagswidget.cpp @@ -9,6 +9,126 @@ #include + +FlagsModel::FlagsModel(QList *flags, MainWindow *main, QObject *parent) + : QAbstractListModel(parent), + main(main), + flags(flags) +{ +} + +int FlagsModel::rowCount(const QModelIndex &parent) const +{ + return flags->count(); +} + +int FlagsModel::columnCount(const QModelIndex &parent) const +{ + return Columns::COUNT; +} + +QVariant FlagsModel::data(const QModelIndex &index, int role) const +{ + if(index.row() >= flags->count()) + return QVariant(); + + const FlagDescription &flag = flags->at(index.row()); + + switch(role) + { + case Qt::DisplayRole: + switch(index.column()) + { + case SIZE: + return RSizeString(flag.size); + case OFFSET: + return RAddressString(flag.offset); + case NAME: + return flag.name; + default: + return QVariant(); + } + case FlagDescriptionRole: + return QVariant::fromValue(flag); + default: + return QVariant(); + } +} + +QVariant FlagsModel::headerData(int section, Qt::Orientation, int role) const +{ + switch(role) + { + case Qt::DisplayRole: + switch(section) + { + case SIZE: + return tr("Size"); + case OFFSET: + return tr("Offset"); + case NAME: + return tr("Name"); + default: + return QVariant(); + } + default: + return QVariant(); + } +} + +void FlagsModel::beginReloadFlags() +{ + beginResetModel(); +} + +void FlagsModel::endReloadFlags() +{ + endResetModel(); +} + + + + + +FlagsSortFilterProxyModel::FlagsSortFilterProxyModel(FlagsModel *source_model, QObject *parent) + : QSortFilterProxyModel(parent) +{ + setSourceModel(source_model); +} + +bool FlagsSortFilterProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const +{ + QModelIndex index = sourceModel()->index(row, 0, parent); + FlagDescription flag = index.data(FlagsModel::FlagDescriptionRole).value(); + return flag.name.contains(filterRegExp()); +} + +bool FlagsSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const +{ + FlagDescription left_flag = left.data(FlagsModel::FlagDescriptionRole).value(); + FlagDescription right_flag = right.data(FlagsModel::FlagDescriptionRole).value(); + + switch(left.column()) + { + case FlagsModel::SIZE: + if(left_flag.size != right_flag.size) + return left_flag.size < right_flag.size; + // fallthrough + case FlagsModel::OFFSET: + if(left_flag.offset != right_flag.offset) + return left_flag.offset < right_flag.offset; + // fallthrough + case FlagsModel::NAME: + return left_flag.name < right_flag.name; + default: + break; + } + + // fallback + return left_flag.offset < right_flag.offset; +} + + FlagsWidget::FlagsWidget(MainWindow *main, QWidget *parent) : DockWidget(parent), ui(new Ui::FlagsWidget), @@ -16,7 +136,11 @@ FlagsWidget::FlagsWidget(MainWindow *main, QWidget *parent) : { ui->setupUi(this); - ui->flagsTreeWidget->hideColumn(0); + flags_model = new FlagsModel(&flags, main, this); + flags_proxy_model = new FlagsSortFilterProxyModel(flags_model, this); + connect(ui->filterLineEdit, SIGNAL(textChanged(const QString &)), flags_proxy_model, SLOT(setFilterWildcard(const QString &))); + ui->flagsTreeView->setModel(flags_proxy_model); + ui->flagsTreeView->sortByColumn(FlagsModel::OFFSET, Qt::AscendingOrder); } FlagsWidget::~FlagsWidget() @@ -33,21 +157,13 @@ void FlagsWidget::setup() void FlagsWidget::refresh() { - setup(); + refreshFlagspaces(); } -void FlagsWidget::clear() +void FlagsWidget::on_flagsTreeView_doubleClicked(const QModelIndex &index) { - ui->flagsTreeWidget->clear(); -} - -void FlagsWidget::on_flagsTreeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column) -{ - QNOTUSED(column); - - QString offset = item->text(2); - QString name = item->text(3); - this->main->seek(offset, name, true); + FlagDescription flag = index.data(FlagsModel::FlagDescriptionRole).value(); + this->main->seek(flag.offset, flag.name, true); } void FlagsWidget::on_flagspaceCombo_currentTextChanged(const QString &arg1) @@ -86,23 +202,20 @@ void FlagsWidget::refreshFlags() flagspace = flagspace_data.value().name; - ui->flagsTreeWidget->clear(); + flags_model->beginReloadFlags(); + flags = main->core->getAllFlags(flagspace); + flags_model->endReloadFlags(); - QStringList flags; + ui->flagsTreeView->resizeColumnToContents(0); + ui->flagsTreeView->resizeColumnToContents(1); - for (auto i : main->core->getAllFlags(flagspace)) - { - QTreeWidgetItem *item = qhelpers::appendRow(ui->flagsTreeWidget, RSizeString(i.size), RAddressString(i.offset), i.name); - item->setData(0, Qt::UserRole, QVariant::fromValue(i)); - - flags.append(i.name); - } - qhelpers::adjustColumns(ui->flagsTreeWidget); - - main->refreshOmniBar(flags); + QStringList flagNames; + for (auto i : flags) + flagNames.append(i.name); + main->refreshOmniBar(flagNames); } void FlagsWidget::setScrollMode() { - qhelpers::setVerticalScrollMode(ui->flagsTreeWidget); + qhelpers::setVerticalScrollMode(ui->flagsTreeView); } diff --git a/src/widgets/flagswidget.h b/src/widgets/flagswidget.h index 76e556f5..2aac4805 100644 --- a/src/widgets/flagswidget.h +++ b/src/widgets/flagswidget.h @@ -1,11 +1,58 @@ #ifndef FLAGSWIDGET_H #define FLAGSWIDGET_H +#include +#include +#include #include "dockwidget.h" class MainWindow; class QTreeWidgetItem; + + + + +class FlagsModel: public QAbstractListModel +{ + Q_OBJECT + +private: + MainWindow *main; + QList *flags; + +public: + enum Columns { OFFSET = 0, SIZE, NAME, COUNT }; + static const int FlagDescriptionRole = Qt::UserRole; + + FlagsModel(QList *flags, MainWindow *main, QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + + void beginReloadFlags(); + void endReloadFlags(); +}; + + + +class FlagsSortFilterProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT + +public: + FlagsSortFilterProxyModel(FlagsModel *source_model, QObject *parent = 0); + +protected: + bool filterAcceptsRow(int row, const QModelIndex &parent) const override; + bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; +}; + + + namespace Ui { class FlagsWidget; @@ -20,21 +67,20 @@ public: ~FlagsWidget(); void setup() override; - void refresh() override; - void clear(); - - private slots: - void on_flagsTreeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column); - + void on_flagsTreeView_doubleClicked(const QModelIndex &index); void on_flagspaceCombo_currentTextChanged(const QString &arg1); private: Ui::FlagsWidget *ui; MainWindow *main; + FlagsModel *flags_model; + FlagsSortFilterProxyModel *flags_proxy_model; + QList flags; + void refreshFlags(); void refreshFlagspaces(); void setScrollMode(); diff --git a/src/widgets/flagswidget.ui b/src/widgets/flagswidget.ui index 841a1e69..154c3002 100644 --- a/src/widgets/flagswidget.ui +++ b/src/widgets/flagswidget.ui @@ -31,48 +31,9 @@ 0 - - - 10 - - - 10 - - - 0 - - - 5 - - - - - Flagspace: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - + - QTreeWidget::item + QTreeView::item { padding-left:10px; padding-top: 1px; @@ -80,13 +41,13 @@ border-left: 10px; } -QTreeWidget::item:hover +QTreeView::item:hover { background: rgb(242, 246, 248); color: black; } -QTreeWidget::item:selected +QTreeView::item:selected { background: gray; color: white; @@ -98,40 +59,53 @@ QTreeWidget::item:selected true + + 0 + true true - - false - - - 4 - - - - Dummy - - - - - Size - - - - - Offset - - - - - Name - - + + + + 10 + + + 0 + + + 0 + + + 0 + + + + + + + + Quick Filter + + + + + + + Flagspace: + + + + + + + + diff --git a/src/widgets/functionswidget.cpp b/src/widgets/functionswidget.cpp index 3a3b22f7..3cbf2912 100644 --- a/src/widgets/functionswidget.cpp +++ b/src/widgets/functionswidget.cpp @@ -351,8 +351,8 @@ FunctionsWidget::FunctionsWidget(MainWindow *main, QWidget *parent) : this, SLOT(showFunctionsContextMenu(const QPoint &))); - connect(ui->functionsTreeView, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(on_functionsTreeView_itemDoubleClicked(const QModelIndex &))); - connect(ui->nestedFunctionsTreeView, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(on_functionsTreeView_itemDoubleClicked(const QModelIndex &))); + connect(ui->functionsTreeView, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(functionsTreeView_doubleClicked(const QModelIndex &))); + connect(ui->nestedFunctionsTreeView, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(functionsTreeView_doubleClicked(const QModelIndex &))); // Hide the tabs QTabBar *tabs = ui->tabWidget->tabBar(); @@ -410,7 +410,7 @@ QTreeView *FunctionsWidget::getCurrentTreeView() return ui->nestedFunctionsTreeView; } -void FunctionsWidget::on_functionsTreeView_itemDoubleClicked(const QModelIndex &index) +void FunctionsWidget::functionsTreeView_doubleClicked(const QModelIndex &index) { FunctionDescription function = index.data(FunctionModel::FunctionDescriptionRole).value(); this->main->seek(function.offset, function.name, true); diff --git a/src/widgets/functionswidget.h b/src/widgets/functionswidget.h index 5c768dde..9249a031 100644 --- a/src/widgets/functionswidget.h +++ b/src/widgets/functionswidget.h @@ -89,7 +89,7 @@ public: void refresh() override; private slots: - void on_functionsTreeView_itemDoubleClicked(const QModelIndex &index); + void functionsTreeView_doubleClicked(const QModelIndex &index); void showFunctionsContextMenu(const QPoint &pt); void on_actionDisasAdd_comment_triggered();