mirror of
https://github.com/rizinorg/cutter.git
synced 2025-01-31 16:47:26 +00:00
Refactor StringsWidget to use QTreeView+QAbstractListModel #183
This commit is contained in:
parent
2522e6a378
commit
326bf70ff2
@ -1,5 +1,6 @@
|
|||||||
#include <QTreeWidget>
|
|
||||||
#include <QAbstractItemView>
|
#include <QModelIndex>
|
||||||
|
|
||||||
#include "StringsWidget.h"
|
#include "StringsWidget.h"
|
||||||
#include "ui_StringsWidget.h"
|
#include "ui_StringsWidget.h"
|
||||||
|
|
||||||
@ -7,48 +8,146 @@
|
|||||||
#include "utils/Helpers.h"
|
#include "utils/Helpers.h"
|
||||||
|
|
||||||
|
|
||||||
StringsWidget::StringsWidget(MainWindow *main, QWidget *parent) :
|
StringsModel::StringsModel(QList<StringDescription> *strings, QObject *parent)
|
||||||
|
: QAbstractListModel(parent),
|
||||||
|
strings(strings)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int StringsModel::rowCount(const QModelIndex &) const
|
||||||
|
{
|
||||||
|
return strings->count();
|
||||||
|
}
|
||||||
|
|
||||||
|
int StringsModel::columnCount(const QModelIndex &) const
|
||||||
|
{
|
||||||
|
return Columns::COUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant StringsModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (index.row() >= strings->count())
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
const StringDescription &str = strings->at(index.row());
|
||||||
|
|
||||||
|
switch (role)
|
||||||
|
{
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
switch (index.column())
|
||||||
|
{
|
||||||
|
case OFFSET:
|
||||||
|
return RAddressString(str.vaddr);
|
||||||
|
case STRING:
|
||||||
|
return str.string;
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
case StringDescriptionRole:
|
||||||
|
return QVariant::fromValue(str);
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant StringsModel::headerData(int section, Qt::Orientation, int role) const
|
||||||
|
{
|
||||||
|
switch (role)
|
||||||
|
{
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
switch (section)
|
||||||
|
{
|
||||||
|
case OFFSET:
|
||||||
|
return tr("Address");
|
||||||
|
case STRING:
|
||||||
|
return tr("String");
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringsModel::beginReload()
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringsModel::endReload()
|
||||||
|
{
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
StringsSortFilterProxyModel::StringsSortFilterProxyModel(StringsModel *source_model, QObject *parent)
|
||||||
|
: QSortFilterProxyModel(parent)
|
||||||
|
{
|
||||||
|
setSourceModel(source_model);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StringsSortFilterProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
QModelIndex index = sourceModel()->index(row, 0, parent);
|
||||||
|
StringDescription str = index.data(StringsModel::StringDescriptionRole).value<StringDescription>();
|
||||||
|
return str.string.contains(filterRegExp());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StringsSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
||||||
|
{
|
||||||
|
StringDescription left_str = left.data(StringsModel::StringDescriptionRole).value<StringDescription>();
|
||||||
|
StringDescription right_str = right.data(StringsModel::StringDescriptionRole).value<StringDescription>();
|
||||||
|
|
||||||
|
switch (left.column())
|
||||||
|
{
|
||||||
|
case StringsModel::OFFSET:
|
||||||
|
if (left_str.vaddr != right_str.vaddr)
|
||||||
|
return left_str.vaddr < right_str.vaddr;
|
||||||
|
// fallthrough
|
||||||
|
case StringsModel::STRING:
|
||||||
|
return left_str.string < right_str.string;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback
|
||||||
|
return left_str.vaddr < right_str.vaddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
StringsWidget::StringsWidget(QWidget *parent) :
|
||||||
QDockWidget(parent),
|
QDockWidget(parent),
|
||||||
ui(new Ui::StringsWidget),
|
ui(new Ui::StringsWidget)
|
||||||
main(main)
|
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
setScrollMode();
|
qhelpers::setVerticalScrollMode(ui->stringsTreeView);
|
||||||
|
|
||||||
ui->stringsTreeWidget->sortByColumn(1, Qt::AscendingOrder);
|
model = new StringsModel(&strings, this);
|
||||||
|
proxy_model = new StringsSortFilterProxyModel(model, this);
|
||||||
|
ui->stringsTreeView->setModel(proxy_model);
|
||||||
|
ui->stringsTreeView->sortByColumn(StringsModel::OFFSET, Qt::AscendingOrder);
|
||||||
|
|
||||||
connect(Core(), SIGNAL(refreshAll()), this, SLOT(fillTreeWidget()));
|
connect(Core(), SIGNAL(refreshAll()), this, SLOT(refreshStrings()));
|
||||||
}
|
}
|
||||||
|
|
||||||
StringsWidget::~StringsWidget() {}
|
StringsWidget::~StringsWidget() {}
|
||||||
|
|
||||||
void StringsWidget::on_stringsTreeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column)
|
void StringsWidget::on_stringsTreeView_doubleClicked(const QModelIndex &index)
|
||||||
{
|
{
|
||||||
Q_UNUSED(column);
|
StringDescription str = index.data(StringsModel::StringDescriptionRole).value<StringDescription>();
|
||||||
|
|
||||||
StringDescription str = item->data(0, Qt::UserRole).value<StringDescription>();
|
|
||||||
CutterCore::getInstance()->seek(str.vaddr);
|
CutterCore::getInstance()->seek(str.vaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StringsWidget::fillTreeWidget()
|
void StringsWidget::refreshStrings()
|
||||||
{
|
{
|
||||||
ui->stringsTreeWidget->clear();
|
model->beginReload();
|
||||||
for (auto i : CutterCore::getInstance()->getAllStrings())
|
strings = CutterCore::getInstance()->getAllStrings();
|
||||||
{
|
model->endReload();
|
||||||
QTreeWidgetItem *item = new QTreeWidgetItem();
|
|
||||||
|
|
||||||
item->setText(0, RAddressString(i.vaddr));
|
ui->stringsTreeView->resizeColumnToContents(0);
|
||||||
item->setText(1, i.string);
|
ui->stringsTreeView->resizeColumnToContents(1);
|
||||||
|
|
||||||
ui->stringsTreeWidget->insertTopLevelItem(0, item);
|
|
||||||
|
|
||||||
item->setData(0, Qt::UserRole, QVariant::fromValue(i));
|
|
||||||
}
|
|
||||||
qhelpers::adjustColumns(ui->stringsTreeWidget);
|
|
||||||
}
|
|
||||||
|
|
||||||
void StringsWidget::setScrollMode()
|
|
||||||
{
|
|
||||||
qhelpers::setVerticalScrollMode(ui->stringsTreeWidget);
|
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,10 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "cutter.h"
|
||||||
|
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
#include <QDockWidget>
|
#include <QDockWidget>
|
||||||
|
|
||||||
class MainWindow;
|
class MainWindow;
|
||||||
@ -13,24 +17,65 @@ namespace Ui
|
|||||||
class StringsWidget;
|
class StringsWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class StringsModel: public QAbstractListModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<StringDescription> *strings;
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum Columns { OFFSET = 0, STRING, COUNT };
|
||||||
|
static const int StringDescriptionRole = Qt::UserRole;
|
||||||
|
|
||||||
|
StringsModel(QList<StringDescription> *strings, 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 beginReload();
|
||||||
|
void endReload();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class StringsSortFilterProxyModel : public QSortFilterProxyModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
StringsSortFilterProxyModel(StringsModel *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;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class StringsWidget : public QDockWidget
|
class StringsWidget : public QDockWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit StringsWidget(MainWindow *main, QWidget *parent = 0);
|
explicit StringsWidget(QWidget *parent = nullptr);
|
||||||
~StringsWidget();
|
~StringsWidget();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_stringsTreeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column);
|
void on_stringsTreeView_doubleClicked(const QModelIndex &index);
|
||||||
|
|
||||||
void fillTreeWidget();
|
void refreshStrings();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Ui::StringsWidget> ui;
|
std::unique_ptr<Ui::StringsWidget> ui;
|
||||||
MainWindow *main;
|
|
||||||
|
|
||||||
void setScrollMode();
|
StringsModel *model;
|
||||||
|
StringsSortFilterProxyModel *proxy_model;
|
||||||
|
QList<StringDescription> strings;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // STRINGSWIDGET_H
|
#endif // STRINGSWIDGET_H
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTreeWidget" name="stringsTreeWidget">
|
<widget class="QTreeView" name="stringsTreeView">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
@ -54,16 +54,6 @@
|
|||||||
<property name="sortingEnabled">
|
<property name="sortingEnabled">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>Address</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>Name</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
Loading…
Reference in New Issue
Block a user