mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-20 03:46:11 +00:00
Show Anal Class Attributes
This commit is contained in:
parent
6087ab8016
commit
af20c35ab0
@ -2014,6 +2014,7 @@ QList<AnalMethodDescription> CutterCore::getAnalClassMethods(const QString &cls)
|
|||||||
desc.name = QString::fromUtf8(meth->name);
|
desc.name = QString::fromUtf8(meth->name);
|
||||||
desc.addr = meth->addr;
|
desc.addr = meth->addr;
|
||||||
desc.vtableOffset = meth->vtable_offset;
|
desc.vtableOffset = meth->vtable_offset;
|
||||||
|
ret.append(desc);
|
||||||
}
|
}
|
||||||
r_vector_free(meths);
|
r_vector_free(meths);
|
||||||
|
|
||||||
@ -2036,6 +2037,7 @@ QList<AnalBaseClassDescription> CutterCore::getAnalClassBaseClasses(const QStrin
|
|||||||
desc.id = QString::fromUtf8(base->id);
|
desc.id = QString::fromUtf8(base->id);
|
||||||
desc.offset = base->offset;
|
desc.offset = base->offset;
|
||||||
desc.className = QString::fromUtf8(base->class_name);
|
desc.className = QString::fromUtf8(base->class_name);
|
||||||
|
ret.append(desc);
|
||||||
}
|
}
|
||||||
r_vector_free(bases);
|
r_vector_free(bases);
|
||||||
|
|
||||||
@ -2058,6 +2060,7 @@ QList<AnalVTableDescription> CutterCore::getAnalClassVTables(const QString &cls)
|
|||||||
desc.id = QString::fromUtf8(vtable->id);
|
desc.id = QString::fromUtf8(vtable->id);
|
||||||
desc.offset = vtable->offset;
|
desc.offset = vtable->offset;
|
||||||
desc.addr = vtable->addr;
|
desc.addr = vtable->addr;
|
||||||
|
ret.append(desc);
|
||||||
}
|
}
|
||||||
r_vector_free(vtables);
|
r_vector_free(vtables);
|
||||||
|
|
||||||
|
@ -391,6 +391,9 @@ Q_DECLARE_METATYPE(BinClassDescription)
|
|||||||
Q_DECLARE_METATYPE(const BinClassDescription *)
|
Q_DECLARE_METATYPE(const BinClassDescription *)
|
||||||
Q_DECLARE_METATYPE(const BinClassMethodDescription *)
|
Q_DECLARE_METATYPE(const BinClassMethodDescription *)
|
||||||
Q_DECLARE_METATYPE(const BinClassFieldDescription *)
|
Q_DECLARE_METATYPE(const BinClassFieldDescription *)
|
||||||
|
Q_DECLARE_METATYPE(AnalBaseClassDescription)
|
||||||
|
Q_DECLARE_METATYPE(AnalMethodDescription)
|
||||||
|
Q_DECLARE_METATYPE(AnalVTableDescription)
|
||||||
Q_DECLARE_METATYPE(ResourcesDescription)
|
Q_DECLARE_METATYPE(ResourcesDescription)
|
||||||
Q_DECLARE_METATYPE(VTableDescription)
|
Q_DECLARE_METATYPE(VTableDescription)
|
||||||
Q_DECLARE_METATYPE(TypeDescription)
|
Q_DECLARE_METATYPE(TypeDescription)
|
||||||
|
@ -48,21 +48,24 @@ void BinClassesModel::setClasses(const QList<BinClassDescription> &classes)
|
|||||||
|
|
||||||
QModelIndex BinClassesModel::index(int row, int column, const QModelIndex &parent) const
|
QModelIndex BinClassesModel::index(int row, int column, const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
if (!parent.isValid())
|
if (!parent.isValid()) {
|
||||||
return createIndex(row, column, (quintptr)0); // root function nodes have id = 0
|
return createIndex(row, column, (quintptr)0); // root function nodes have id = 0
|
||||||
|
}
|
||||||
|
|
||||||
return createIndex(row, column, (quintptr)parent.row() + 1); // sub-nodes have id = class index + 1
|
return createIndex(row, column, (quintptr)parent.row() + 1); // sub-nodes have id = class index + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex BinClassesModel::parent(const QModelIndex &index) const
|
QModelIndex BinClassesModel::parent(const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
if (!index.isValid() || index.column() != 0)
|
if (!index.isValid()) {
|
||||||
return QModelIndex();
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
if (index.internalId() == 0) // root function node
|
if (index.internalId() == 0) { // root function node
|
||||||
return QModelIndex();
|
return {};
|
||||||
else // sub-node
|
} else { // sub-node
|
||||||
return this->index((int)(index.internalId() - 1), 0);
|
return this->index((int)(index.internalId() - 1), 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int BinClassesModel::rowCount(const QModelIndex &parent) const
|
int BinClassesModel::rowCount(const QModelIndex &parent) const
|
||||||
@ -134,7 +137,7 @@ QVariant BinClassesModel::data(const QModelIndex &index, int role) const
|
|||||||
case NameRole:
|
case NameRole:
|
||||||
return meth->name;
|
return meth->name;
|
||||||
case TypeRole:
|
case TypeRole:
|
||||||
return QVariant::fromValue(METHOD);
|
return QVariant::fromValue(RowType::Method);
|
||||||
case DataRole:
|
case DataRole:
|
||||||
return QVariant::fromValue(*meth);
|
return QVariant::fromValue(*meth);
|
||||||
default:
|
default:
|
||||||
@ -158,7 +161,7 @@ QVariant BinClassesModel::data(const QModelIndex &index, int role) const
|
|||||||
case NameRole:
|
case NameRole:
|
||||||
return field->name;
|
return field->name;
|
||||||
case TypeRole:
|
case TypeRole:
|
||||||
return QVariant::fromValue(FIELD);
|
return QVariant::fromValue(RowType::Field);
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
@ -178,7 +181,7 @@ QVariant BinClassesModel::data(const QModelIndex &index, int role) const
|
|||||||
case NameRole:
|
case NameRole:
|
||||||
return base->name;
|
return base->name;
|
||||||
case TypeRole:
|
case TypeRole:
|
||||||
return QVariant::fromValue(BASE);
|
return QVariant::fromValue(RowType::Base);
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
@ -205,7 +208,7 @@ QVariant BinClassesModel::data(const QModelIndex &index, int role) const
|
|||||||
case NameRole:
|
case NameRole:
|
||||||
return cls->name;
|
return cls->name;
|
||||||
case TypeRole:
|
case TypeRole:
|
||||||
return QVariant::fromValue(CLASS);
|
return QVariant::fromValue(RowType::Class);
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
@ -214,7 +217,7 @@ QVariant BinClassesModel::data(const QModelIndex &index, int role) const
|
|||||||
|
|
||||||
|
|
||||||
AnalClassesModel::AnalClassesModel(QObject *parent)
|
AnalClassesModel::AnalClassesModel(QObject *parent)
|
||||||
: ClassesModel(parent)
|
: ClassesModel(parent), attrs(new QMap<QString, QVector<Attribute>>)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,24 +228,54 @@ void AnalClassesModel::refreshClasses()
|
|||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QVector<AnalClassesModel::Attribute> &AnalClassesModel::getAttrs(const QString &cls) const
|
||||||
|
{
|
||||||
|
auto it = attrs->find(cls);
|
||||||
|
if(it != attrs->end()) {
|
||||||
|
return it.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<AnalClassesModel::Attribute> clsAttrs;
|
||||||
|
QList<AnalBaseClassDescription> bases = Core()->getAnalClassBaseClasses(cls);
|
||||||
|
QList<AnalMethodDescription> meths = Core()->getAnalClassMethods(cls);
|
||||||
|
QList<AnalVTableDescription> vtables = Core()->getAnalClassVTables(cls);
|
||||||
|
clsAttrs.reserve(bases.size() + meths.size() + vtables.size());
|
||||||
|
|
||||||
|
for(const AnalBaseClassDescription &base : bases) {
|
||||||
|
clsAttrs.push_back(Attribute(Attribute::Type::Base, QVariant::fromValue(base)));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const AnalVTableDescription &vtable : vtables) {
|
||||||
|
clsAttrs.push_back(Attribute(Attribute::Type::VTable, QVariant::fromValue(vtable)));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const AnalMethodDescription &meth : meths) {
|
||||||
|
clsAttrs.push_back(Attribute(Attribute::Type::Method, QVariant::fromValue(meth)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return attrs->insert(cls, clsAttrs).value();
|
||||||
|
}
|
||||||
|
|
||||||
QModelIndex AnalClassesModel::index(int row, int column, const QModelIndex &parent) const
|
QModelIndex AnalClassesModel::index(int row, int column, const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
if (!parent.isValid())
|
if (!parent.isValid()) {
|
||||||
return createIndex(row, column, (quintptr)0); // root function nodes have id = 0
|
return createIndex(row, column, (quintptr)0); // root function nodes have id = 0
|
||||||
|
}
|
||||||
|
|
||||||
return createIndex(row, column, (quintptr)parent.row() + 1); // sub-nodes have id = class index + 1
|
return createIndex(row, column, (quintptr)parent.row() + 1); // sub-nodes have id = class index + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex AnalClassesModel::parent(const QModelIndex &index) const
|
QModelIndex AnalClassesModel::parent(const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
if (!index.isValid() || index.column() != 0)
|
if (!index.isValid()) {
|
||||||
return QModelIndex();
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
if (index.internalId() == 0) // root function node
|
if (index.internalId() == 0) { // root function node
|
||||||
return QModelIndex();
|
return {};
|
||||||
else // sub-node
|
} else { // sub-node
|
||||||
return this->index((int)(index.internalId() - 1), 0);
|
return this->index((int)(index.internalId() - 1), 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int AnalClassesModel::rowCount(const QModelIndex &parent) const
|
int AnalClassesModel::rowCount(const QModelIndex &parent) const
|
||||||
@ -252,9 +285,7 @@ int AnalClassesModel::rowCount(const QModelIndex &parent) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (parent.internalId() == 0) { // methods/fields
|
if (parent.internalId() == 0) { // methods/fields
|
||||||
return 0;
|
return getAttrs(classes[parent.row()]).size();
|
||||||
// TODO const BinClassDescription *cls = &classes.at(parent.row());
|
|
||||||
// TODO return cls->baseClasses.length() + cls->methods.length() + cls->fields.length();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0; // below methods/fields
|
return 0; // below methods/fields
|
||||||
@ -262,7 +293,7 @@ int AnalClassesModel::rowCount(const QModelIndex &parent) const
|
|||||||
|
|
||||||
bool AnalClassesModel::hasChildren(const QModelIndex &parent) const
|
bool AnalClassesModel::hasChildren(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
return true;
|
return !parent.isValid() || !parent.parent().isValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
int AnalClassesModel::columnCount(const QModelIndex &) const
|
int AnalClassesModel::columnCount(const QModelIndex &) const
|
||||||
@ -272,104 +303,12 @@ int AnalClassesModel::columnCount(const QModelIndex &) const
|
|||||||
|
|
||||||
QVariant AnalClassesModel::data(const QModelIndex &index, int role) const
|
QVariant AnalClassesModel::data(const QModelIndex &index, int role) const
|
||||||
{
|
{
|
||||||
QString cls;
|
|
||||||
const BinClassMethodDescription *meth = nullptr;
|
|
||||||
const BinClassFieldDescription *field = nullptr;
|
|
||||||
const BinClassBaseClassDescription *base = nullptr;
|
|
||||||
if (index.internalId() == 0) { // class row
|
if (index.internalId() == 0) { // class row
|
||||||
if (index.row() >= classes.count()) {
|
if (index.row() >= classes.count()) {
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
cls = classes.at(index.row());
|
QString cls = classes.at(index.row());
|
||||||
} else { // method/field/base row
|
|
||||||
cls = classes.at(static_cast<int>(index.internalId() - 1));
|
|
||||||
|
|
||||||
/*if (index.row() >= cls->baseClasses.length() + cls->methods.length() + cls->fields.length()) {
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index.row() < cls->baseClasses.length()) {
|
|
||||||
base = &cls->baseClasses[index.row()];
|
|
||||||
} else if (index.row() - cls->baseClasses.length() < cls->methods.length()) {
|
|
||||||
meth = &cls->methods[index.row() - cls->baseClasses.length()];
|
|
||||||
} else {
|
|
||||||
field = &cls->fields[index.row() - cls->baseClasses.length() - cls->methods.length()];
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
if (meth) {
|
|
||||||
switch (role) {
|
|
||||||
case Qt::DisplayRole:
|
|
||||||
switch (index.column()) {
|
|
||||||
case NAME:
|
|
||||||
return meth->name;
|
|
||||||
case TYPE:
|
|
||||||
return tr("method");
|
|
||||||
case OFFSET:
|
|
||||||
return meth->addr == RVA_INVALID ? QString() : RAddressString(meth->addr);
|
|
||||||
case VTABLE:
|
|
||||||
return meth->vtableOffset < 0 ? QString() : QString("+%1").arg(meth->vtableOffset);
|
|
||||||
default:
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
case OffsetRole:
|
|
||||||
return QVariant::fromValue(meth->addr);
|
|
||||||
case VTableOffsetRole:
|
|
||||||
return QVariant::fromValue(index.parent().data(VTableOffsetRole).toULongLong() + meth->vtableOffset);
|
|
||||||
case NameRole:
|
|
||||||
return meth->name;
|
|
||||||
case TypeRole:
|
|
||||||
return QVariant::fromValue(METHOD);
|
|
||||||
case DataRole:
|
|
||||||
return QVariant::fromValue(*meth);
|
|
||||||
default:
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
} else if (field) {
|
|
||||||
switch (role) {
|
|
||||||
case Qt::DisplayRole:
|
|
||||||
switch (index.column()) {
|
|
||||||
case NAME:
|
|
||||||
return field->name;
|
|
||||||
case TYPE:
|
|
||||||
return tr("field");
|
|
||||||
case OFFSET:
|
|
||||||
return field->addr == RVA_INVALID ? QString() : RAddressString(field->addr);
|
|
||||||
default:
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
case OffsetRole:
|
|
||||||
return QVariant::fromValue(field->addr);
|
|
||||||
case NameRole:
|
|
||||||
return field->name;
|
|
||||||
case TypeRole:
|
|
||||||
return QVariant::fromValue(FIELD);
|
|
||||||
default:
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
} else if (base) {
|
|
||||||
switch (role) {
|
|
||||||
case Qt::DisplayRole:
|
|
||||||
switch (index.column()) {
|
|
||||||
case NAME:
|
|
||||||
return base->name;
|
|
||||||
case TYPE:
|
|
||||||
return tr("base class");
|
|
||||||
case OFFSET:
|
|
||||||
return QString("+%1").arg(base->offset);
|
|
||||||
default:
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
case NameRole:
|
|
||||||
return base->name;
|
|
||||||
case TypeRole:
|
|
||||||
return QVariant::fromValue(BASE);
|
|
||||||
default:
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case Qt::DisplayRole:
|
case Qt::DisplayRole:
|
||||||
switch (index.column()) {
|
switch (index.column()) {
|
||||||
@ -377,25 +316,97 @@ QVariant AnalClassesModel::data(const QModelIndex &index, int role) const
|
|||||||
return cls;
|
return cls;
|
||||||
case TYPE:
|
case TYPE:
|
||||||
return tr("class");
|
return tr("class");
|
||||||
// TODO case OFFSET:
|
|
||||||
// TODO return cls->addr == RVA_INVALID ? QString() : RAddressString(cls->addr);
|
|
||||||
// TODO case VTABLE:
|
|
||||||
// TODO return cls->vtableAddr == RVA_INVALID ? QString() : RAddressString(cls->vtableAddr);
|
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
// TODO case OffsetRole:
|
|
||||||
// TODO return QVariant::fromValue(cls->addr);
|
|
||||||
// TODO case VTableOffsetRole:
|
|
||||||
// TODO return QVariant::fromValue(cls->vtableAddr);
|
|
||||||
// TODO case NameRole:
|
|
||||||
// TODO return cls->name;
|
|
||||||
case TypeRole:
|
case TypeRole:
|
||||||
return QVariant::fromValue(CLASS);
|
return QVariant::fromValue(RowType::Class);
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
} else { // method/field/base row
|
||||||
|
QString cls = classes.at(static_cast<int>(index.internalId() - 1));
|
||||||
|
const Attribute &attr = getAttrs(cls)[index.row()];
|
||||||
|
|
||||||
|
switch (attr.type) {
|
||||||
|
case Attribute::Type::Base: {
|
||||||
|
AnalBaseClassDescription base = attr.data.value<AnalBaseClassDescription>();
|
||||||
|
switch (role) {
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
switch (index.column()) {
|
||||||
|
case NAME:
|
||||||
|
return base.className;
|
||||||
|
case TYPE:
|
||||||
|
return tr("base");
|
||||||
|
case OFFSET:
|
||||||
|
return QString("+%1").arg(base.offset);
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
case NameRole:
|
||||||
|
return base.className;
|
||||||
|
case TypeRole:
|
||||||
|
return QVariant::fromValue(RowType::Base);
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Attribute::Type::Method: {
|
||||||
|
AnalMethodDescription meth = attr.data.value<AnalMethodDescription>();
|
||||||
|
switch (role) {
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
switch (index.column()) {
|
||||||
|
case NAME:
|
||||||
|
return meth.name;
|
||||||
|
case TYPE:
|
||||||
|
return tr("method");
|
||||||
|
case OFFSET:
|
||||||
|
return meth.addr == RVA_INVALID ? QString() : RAddressString(meth.addr);
|
||||||
|
case VTABLE:
|
||||||
|
return meth.vtableOffset < 0 ? QString() : QString("+%1").arg(meth.vtableOffset);
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
case OffsetRole:
|
||||||
|
return QVariant::fromValue(meth.addr);
|
||||||
|
case VTableOffsetRole:
|
||||||
|
return QVariant::fromValue(index.parent().data(VTableOffsetRole).toULongLong() + meth.vtableOffset);
|
||||||
|
case NameRole:
|
||||||
|
return meth.name;
|
||||||
|
case TypeRole:
|
||||||
|
return QVariant::fromValue(RowType::Method);
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Attribute::Type::VTable: {
|
||||||
|
AnalVTableDescription vtable = attr.data.value<AnalVTableDescription>();
|
||||||
|
switch (role) {
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
switch (index.column()) {
|
||||||
|
case NAME:
|
||||||
|
return "vtable";
|
||||||
|
case TYPE:
|
||||||
|
return tr("vtable");
|
||||||
|
case OFFSET:
|
||||||
|
return RAddressString(vtable.addr);
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
case OffsetRole:
|
||||||
|
return QVariant::fromValue(vtable.addr);
|
||||||
|
case TypeRole:
|
||||||
|
return QVariant::fromValue(RowType::VTable);
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -531,7 +542,7 @@ void ClassesWidget::showContextMenu(const QPoint &pt)
|
|||||||
|
|
||||||
menu.addAction(ui->addMethodAction);
|
menu.addAction(ui->addMethodAction);
|
||||||
|
|
||||||
if (index.data(ClassesModel::TypeRole) == ClassesModel::METHOD) {
|
if (index.data(ClassesModel::TypeRole).toInt() == static_cast<int>(ClassesModel::RowType::Method)) {
|
||||||
menu.addAction(ui->editMethodAction);
|
menu.addAction(ui->editMethodAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -555,7 +566,7 @@ void ClassesWidget::on_addMethodAction_triggered()
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString className;
|
QString className;
|
||||||
if (index.data(ClassesModel::TypeRole).toInt() == ClassesModel::CLASS) {
|
if (index.data(ClassesModel::TypeRole).toInt() == static_cast<int>(ClassesModel::RowType::Class)) {
|
||||||
className = index.data(ClassesModel::NameRole).toString();
|
className = index.data(ClassesModel::NameRole).toString();
|
||||||
} else {
|
} else {
|
||||||
className = index.parent().data(ClassesModel::NameRole).toString();
|
className = index.parent().data(ClassesModel::NameRole).toString();
|
||||||
@ -570,7 +581,7 @@ void ClassesWidget::on_addMethodAction_triggered()
|
|||||||
void ClassesWidget::on_editMethodAction_triggered()
|
void ClassesWidget::on_editMethodAction_triggered()
|
||||||
{
|
{
|
||||||
QModelIndex index = ui->classesTreeView->selectionModel()->currentIndex();
|
QModelIndex index = ui->classesTreeView->selectionModel()->currentIndex();
|
||||||
if (!index.isValid() || index.data(ClassesModel::TypeRole).toInt() != ClassesModel::METHOD) {
|
if (!index.isValid() || index.data(ClassesModel::TypeRole).toInt() != static_cast<int>(ClassesModel::RowType::Method)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ class ClassesModel: public QAbstractItemModel
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Columns { NAME = 0, TYPE, OFFSET, VTABLE, COUNT };
|
enum Columns { NAME = 0, TYPE, OFFSET, VTABLE, COUNT };
|
||||||
enum RowType { CLASS = 0, METHOD = 1, FIELD = 2, BASE = 3 };
|
enum class RowType { Class = 0, Method = 1, Field = 2, Base = 3, VTable = 4 };
|
||||||
|
|
||||||
static const int OffsetRole = Qt::UserRole;
|
static const int OffsetRole = Qt::UserRole;
|
||||||
static const int NameRole = Qt::UserRole + 1;
|
static const int NameRole = Qt::UserRole + 1;
|
||||||
@ -64,7 +64,20 @@ class AnalClassesModel: public ClassesModel
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct Attribute
|
||||||
|
{
|
||||||
|
enum class Type { VTable, Base, Method };
|
||||||
|
Type type;
|
||||||
|
QVariant data;
|
||||||
|
|
||||||
|
Attribute() = default;
|
||||||
|
Attribute(Type type, const QVariant &data) : type(type), data(data) {}
|
||||||
|
};
|
||||||
|
|
||||||
QList<QString> classes;
|
QList<QString> classes;
|
||||||
|
std::unique_ptr<QMap<QString, QVector<Attribute>>> attrs;
|
||||||
|
|
||||||
|
const QVector<Attribute> &getAttrs(const QString &cls) const;
|
||||||
|
|
||||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
|
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user