mirror of
https://github.com/rizinorg/cutter.git
synced 2025-01-19 02:48:49 +00:00
Added some of the features mentioned in the Types Widget Project. (#1153)
* Added filter widget to types widget * Added filter capibility in types widget * Added comments and refactored some code * Corrected some details
This commit is contained in:
parent
f5709830b9
commit
601339d86f
@ -2004,12 +2004,24 @@ QList<VTableDescription> CutterCore::getAllVTables()
|
||||
}
|
||||
|
||||
QList<TypeDescription> CutterCore::getAllTypes()
|
||||
{
|
||||
QList<TypeDescription> ret;
|
||||
|
||||
ret.append(getAllPrimitiveTypes());
|
||||
ret.append(getAllUnions());
|
||||
ret.append(getAllStructs());
|
||||
ret.append(getAllEnums());
|
||||
ret.append(getAllTypedefs());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QList<TypeDescription> CutterCore::getAllPrimitiveTypes()
|
||||
{
|
||||
CORE_LOCK();
|
||||
QList<TypeDescription> ret;
|
||||
|
||||
QJsonArray typesArray = cmdj("tj").array();
|
||||
|
||||
for (const QJsonValue &value : typesArray) {
|
||||
QJsonObject typeObject = value.toObject();
|
||||
|
||||
@ -2018,7 +2030,75 @@ QList<TypeDescription> CutterCore::getAllTypes()
|
||||
exp.type = typeObject[RJsonKey::type].toString();
|
||||
exp.size = typeObject[RJsonKey::size].toVariant().toULongLong();
|
||||
exp.format = typeObject[RJsonKey::format].toString();
|
||||
exp.category = tr("Primitive");
|
||||
ret << exp;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QList<TypeDescription> CutterCore::getAllUnions()
|
||||
{
|
||||
CORE_LOCK();
|
||||
QList<TypeDescription> ret;
|
||||
|
||||
QJsonArray typesArray = cmdj("tuj").array();
|
||||
for (auto value: typesArray) {
|
||||
TypeDescription exp;
|
||||
exp.type = value.toString();
|
||||
exp.size = 0;
|
||||
exp.category = tr("Union");
|
||||
ret << exp;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QList<TypeDescription> CutterCore::getAllStructs()
|
||||
{
|
||||
CORE_LOCK();
|
||||
QList<TypeDescription> ret;
|
||||
|
||||
QJsonArray typesArray = cmdj("tsj").array();
|
||||
for (auto value: typesArray) {
|
||||
TypeDescription exp;
|
||||
exp.type = value.toString();
|
||||
exp.size = 0;
|
||||
exp.category = tr("Struct");
|
||||
ret << exp;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QList<TypeDescription> CutterCore::getAllEnums()
|
||||
{
|
||||
CORE_LOCK();
|
||||
QList<TypeDescription> ret;
|
||||
|
||||
QJsonObject typesObject = cmdj("tej").object();
|
||||
for (QString key: typesObject.keys()) {
|
||||
TypeDescription exp;
|
||||
exp.type = key;
|
||||
exp.size = 0;
|
||||
exp.category = tr("Enum");
|
||||
ret << exp;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QList<TypeDescription> CutterCore::getAllTypedefs()
|
||||
{
|
||||
CORE_LOCK();
|
||||
QList<TypeDescription> ret;
|
||||
|
||||
QJsonObject typesObject = cmdj("ttj").object();
|
||||
for (QString key: typesObject.keys()) {
|
||||
TypeDescription exp;
|
||||
exp.type = key;
|
||||
exp.size = 0;
|
||||
exp.category = tr("Typedef");
|
||||
ret << exp;
|
||||
}
|
||||
|
||||
|
31
src/Cutter.h
31
src/Cutter.h
@ -133,6 +133,7 @@ struct TypeDescription {
|
||||
QString type;
|
||||
int size;
|
||||
QString format;
|
||||
QString category;
|
||||
};
|
||||
|
||||
struct SearchDescription {
|
||||
@ -606,7 +607,37 @@ public:
|
||||
QList<ClassDescription> getAllClassesFromFlags();
|
||||
QList<ResourcesDescription> getAllResources();
|
||||
QList<VTableDescription> getAllVTables();
|
||||
|
||||
/*!
|
||||
* \return all loaded types
|
||||
*/
|
||||
QList<TypeDescription> getAllTypes();
|
||||
|
||||
/*!
|
||||
* \return all loaded primitive types
|
||||
*/
|
||||
QList<TypeDescription> getAllPrimitiveTypes();
|
||||
|
||||
/*!
|
||||
* \return all loaded unions
|
||||
*/
|
||||
QList<TypeDescription> getAllUnions();
|
||||
|
||||
/*!
|
||||
* \return all loaded structs
|
||||
*/
|
||||
QList<TypeDescription> getAllStructs();
|
||||
|
||||
/*!
|
||||
* \return all loaded enums
|
||||
*/
|
||||
QList<TypeDescription> getAllEnums();
|
||||
|
||||
/*!
|
||||
* \return all loaded typedefs
|
||||
*/
|
||||
QList<TypeDescription> getAllTypedefs();
|
||||
|
||||
QList<MemoryMapDescription> getMemoryMap();
|
||||
QList<SearchDescription> getAllSearch(QString search_for, QString space);
|
||||
BlockStatistics getBlockStatistics(unsigned int blocksCount);
|
||||
|
@ -32,9 +32,11 @@ QVariant TypesModel::data(const QModelIndex &index, int role) const
|
||||
case TYPE:
|
||||
return exp.type;
|
||||
case SIZE:
|
||||
return exp.size;
|
||||
return exp.category == tr("Primitive") ? exp.size : QVariant();
|
||||
case FORMAT:
|
||||
return exp.format;
|
||||
case CATEGORY:
|
||||
return exp.category;
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
@ -56,6 +58,8 @@ QVariant TypesModel::headerData(int section, Qt::Orientation, int role) const
|
||||
return tr("Size");
|
||||
case FORMAT:
|
||||
return tr("Format");
|
||||
case CATEGORY:
|
||||
return tr("Category");
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
@ -75,7 +79,11 @@ bool TypesSortFilterProxyModel::filterAcceptsRow(int row, const QModelIndex &par
|
||||
{
|
||||
QModelIndex index = sourceModel()->index(row, 0, parent);
|
||||
TypeDescription exp = index.data(TypesModel::TypeDescriptionRole).value<TypeDescription>();
|
||||
return exp.type.contains(filterRegExp());
|
||||
if (selectedCategory.isEmpty()) {
|
||||
return exp.type.contains(filterRegExp());
|
||||
} else {
|
||||
return selectedCategory == exp.category && exp.type.contains(filterRegExp());
|
||||
}
|
||||
}
|
||||
|
||||
bool TypesSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
||||
@ -90,6 +98,8 @@ bool TypesSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIn
|
||||
return left_exp.size < right_exp.size;
|
||||
case TypesModel::FORMAT:
|
||||
return left_exp.format < right_exp.format;
|
||||
case TypesModel::CATEGORY:
|
||||
return left_exp.category < right_exp.category;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -101,9 +111,14 @@ bool TypesSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIn
|
||||
|
||||
TypesWidget::TypesWidget(MainWindow *main, QAction *action) :
|
||||
CutterDockWidget(main, action),
|
||||
ui(new Ui::TypesWidget)
|
||||
ui(new Ui::TypesWidget),
|
||||
tree(new CutterTreeWidget(this))
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->quickFilterView->setLabelText(tr("Category"));
|
||||
|
||||
// Add status bar which displays the count
|
||||
tree->addStatusBar(ui->verticalLayout);
|
||||
|
||||
types_model = new TypesModel(&types, this);
|
||||
types_proxy_model = new TypesSortFilterProxyModel(types_model, this);
|
||||
@ -112,7 +127,31 @@ TypesWidget::TypesWidget(MainWindow *main, QAction *action) :
|
||||
|
||||
setScrollMode();
|
||||
|
||||
connect(ui->quickFilterView, SIGNAL(filterTextChanged(const QString &)), types_proxy_model,
|
||||
SLOT(setFilterWildcard(const QString &)));
|
||||
|
||||
connect(ui->quickFilterView, &ComboQuickFilterView::filterTextChanged, this, [this] {
|
||||
tree->showItemsNumber(types_proxy_model->rowCount());
|
||||
});
|
||||
|
||||
QShortcut *searchShortcut = new QShortcut(QKeySequence::Find, this);
|
||||
connect(searchShortcut, &QShortcut::activated, ui->quickFilterView, &ComboQuickFilterView::showFilter);
|
||||
searchShortcut->setContext(Qt::WidgetWithChildrenShortcut);
|
||||
|
||||
QShortcut *clearShortcut = new QShortcut(QKeySequence(Qt::Key_Escape), this);
|
||||
connect(clearShortcut, &QShortcut::activated, ui->quickFilterView, &ComboQuickFilterView::clearFilter);
|
||||
clearShortcut->setContext(Qt::WidgetWithChildrenShortcut);
|
||||
|
||||
connect(Core(), SIGNAL(refreshAll()), this, SLOT(refreshTypes()));
|
||||
|
||||
connect(
|
||||
ui->quickFilterView->comboBox(), &QComboBox::currentTextChanged, this,
|
||||
[this]() {
|
||||
types_proxy_model->selectedCategory = ui->quickFilterView->comboBox()->currentData().toString();
|
||||
types_proxy_model->setFilterRegExp(types_proxy_model->filterRegExp());
|
||||
tree->showItemsNumber(types_proxy_model->rowCount());
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
TypesWidget::~TypesWidget() {}
|
||||
@ -123,9 +162,30 @@ void TypesWidget::refreshTypes()
|
||||
types = Core()->getAllTypes();
|
||||
types_model->endResetModel();
|
||||
|
||||
QStringList categories;
|
||||
for (TypeDescription exp: types) {
|
||||
categories << exp.category;
|
||||
}
|
||||
categories.removeDuplicates();
|
||||
refreshCategoryCombo(categories);
|
||||
|
||||
qhelpers::adjustColumns(ui->typesTreeView, 3, 0);
|
||||
}
|
||||
|
||||
void TypesWidget::refreshCategoryCombo(const QStringList &categories)
|
||||
{
|
||||
QComboBox *combo = ui->quickFilterView->comboBox();
|
||||
|
||||
combo->clear();
|
||||
combo->addItem(tr("(All)"));
|
||||
|
||||
for (const QString &category : categories) {
|
||||
combo->addItem(category, category);
|
||||
}
|
||||
|
||||
types_proxy_model->selectedCategory.clear();
|
||||
}
|
||||
|
||||
void TypesWidget::setScrollMode()
|
||||
{
|
||||
qhelpers::setVerticalScrollMode(ui->typesTreeView);
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "Cutter.h"
|
||||
#include "CutterDockWidget.h"
|
||||
#include "CutterTreeWidget.h"
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QSortFilterProxyModel>
|
||||
@ -32,7 +33,7 @@ private:
|
||||
QList<TypeDescription> *types;
|
||||
|
||||
public:
|
||||
enum Columns { TYPE = 0, SIZE, FORMAT, COUNT };
|
||||
enum Columns { TYPE = 0, SIZE, FORMAT, CATEGORY, COUNT };
|
||||
static const int TypeDescriptionRole = Qt::UserRole;
|
||||
|
||||
TypesModel(QList<TypeDescription> *types, QObject *parent = nullptr);
|
||||
@ -50,12 +51,16 @@ class TypesSortFilterProxyModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
friend TypesWidget;
|
||||
|
||||
public:
|
||||
TypesSortFilterProxyModel(TypesModel *source_model, QObject *parent = nullptr);
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(int row, const QModelIndex &parent) const override;
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
|
||||
QString selectedCategory;
|
||||
};
|
||||
|
||||
|
||||
@ -77,8 +82,15 @@ private:
|
||||
TypesModel *types_model;
|
||||
TypesSortFilterProxyModel *types_proxy_model;
|
||||
QList<TypeDescription> types;
|
||||
CutterTreeWidget *tree;
|
||||
|
||||
void setScrollMode();
|
||||
|
||||
/*!
|
||||
* \brief Sets the contents of the ComboBox to the supplied contents
|
||||
* \param categories The list of categories which has to be added to the ComboBox
|
||||
*/
|
||||
void refreshCategoryCombo(const QStringList &categories);
|
||||
};
|
||||
|
||||
|
||||
|
@ -15,6 +15,9 @@
|
||||
</property>
|
||||
<widget class="QWidget" name="dockWidgetContents">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
@ -29,6 +32,12 @@
|
||||
</property>
|
||||
<item>
|
||||
<widget class="CutterTreeView" name="typesTreeView">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">CutterTreeView::item
|
||||
{
|
||||
@ -50,6 +59,16 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ComboQuickFilterView" name="quickFilterView" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
@ -60,6 +79,12 @@
|
||||
<header>widgets/CutterTreeView.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ComboQuickFilterView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>widgets/ComboQuickFilterView.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
Loading…
Reference in New Issue
Block a user