mirror of
https://github.com/rizinorg/cutter.git
synced 2025-01-31 08:37:26 +00:00
Add ClassesWidget (Fix #193)
This commit is contained in:
parent
320a81ee14
commit
a476dda5d0
@ -33,12 +33,14 @@
|
||||
#include <QToolButton>
|
||||
#include <QToolTip>
|
||||
#include <QTreeWidgetItem>
|
||||
#include <QSvgRenderer>
|
||||
|
||||
#include "utils/Highlighter.h"
|
||||
#include "utils/HexAsciiHighlighter.h"
|
||||
#include "utils/Helpers.h"
|
||||
#include "dialogs/NewFileDialog.h"
|
||||
#include "utils/SvgIconEngine.h"
|
||||
|
||||
#include "dialogs/NewFileDialog.h"
|
||||
#include "widgets/DisassemblerGraphView.h"
|
||||
#include "widgets/FunctionsWidget.h"
|
||||
#include "widgets/SectionsWidget.h"
|
||||
@ -60,6 +62,7 @@
|
||||
#include "dialogs/OptionsDialog.h"
|
||||
#include "widgets/EntrypointWidget.h"
|
||||
#include "dialogs/SaveProjectDialog.h"
|
||||
#include "widgets/ClassesWidget.h"
|
||||
|
||||
// graphics
|
||||
#include <QGraphicsEllipseItem>
|
||||
@ -116,9 +119,6 @@ MainWindow::~MainWindow()
|
||||
{
|
||||
}
|
||||
|
||||
#include <QSvgRenderer>
|
||||
#include "utils/SvgIconEngine.h"
|
||||
|
||||
void MainWindow::initUI()
|
||||
{
|
||||
ui->setupUi(this);
|
||||
@ -241,6 +241,8 @@ void MainWindow::initUI()
|
||||
ADD_DOCK(Notepad, notepadDock, ui->actionNotepad);
|
||||
ADD_DOCK(Dashboard, dashboardDock, ui->actionDashboard);
|
||||
ADD_DOCK(SdbDock, sdbDock, ui->actionSDBBrowser);
|
||||
ADD_DOCK(ClassesWidget, classesDock, ui->actionClasses);
|
||||
|
||||
#undef ADD_DOCK
|
||||
|
||||
// Set up dock widgets default layout
|
||||
@ -622,6 +624,7 @@ void MainWindow::restoreDocks()
|
||||
tabifyDockWidget(dashboardDock, exportsDock);
|
||||
tabifyDockWidget(dashboardDock, symbolsDock);
|
||||
tabifyDockWidget(dashboardDock, notepadDock);
|
||||
tabifyDockWidget(dashboardDock, classesDock);
|
||||
|
||||
dashboardDock->raise();
|
||||
|
||||
|
@ -36,6 +36,7 @@ class SectionsDock;
|
||||
class ConsoleWidget;
|
||||
class EntrypointWidget;
|
||||
class DisassemblerGraphView;
|
||||
class ClassesWidget;
|
||||
|
||||
class QDockWidget;
|
||||
|
||||
@ -185,6 +186,7 @@ private:
|
||||
//QAction *sidebar_action;
|
||||
SectionsDock *sectionsDock;
|
||||
ConsoleWidget *consoleDock;
|
||||
ClassesWidget *classesDock;
|
||||
|
||||
QList<QDockWidget *> dockWidgets;
|
||||
QMap<QAction *, QDockWidget *> dockWidgetActions;
|
||||
|
@ -241,6 +241,7 @@ border-top: 0px;
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionEntrypoints"/>
|
||||
<addaction name="actionFunctions"/>
|
||||
<addaction name="actionClasses"/>
|
||||
<addaction name="actionImports"/>
|
||||
<addaction name="actionExports"/>
|
||||
<addaction name="actionSymbols"/>
|
||||
@ -1019,6 +1020,14 @@ QToolButton:pressed {
|
||||
<string>Console</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionClasses">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Classes</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources>
|
||||
|
@ -1175,6 +1175,46 @@ QList<EntrypointDescription> CutterCore::getAllEntrypoint()
|
||||
return ret;
|
||||
}
|
||||
|
||||
QList<ClassDescription> CutterCore::getAllClasses()
|
||||
{
|
||||
CORE_LOCK();
|
||||
QList<ClassDescription> ret;
|
||||
|
||||
QJsonArray classesArray = cmdj("icj").array();
|
||||
for (QJsonValueRef value : classesArray)
|
||||
{
|
||||
QJsonObject classObject = value.toObject();
|
||||
|
||||
ClassDescription cls;
|
||||
cls.name = classObject["classname"].toString();
|
||||
cls.addr = classObject["addr"].toVariant().toULongLong();
|
||||
cls.index = classObject["index"].toVariant().toULongLong();
|
||||
|
||||
for(QJsonValueRef value2 : classObject["methods"].toArray())
|
||||
{
|
||||
QJsonObject methObject = value2.toObject();
|
||||
|
||||
ClassMethodDescription meth;
|
||||
meth.name = methObject["name"].toString();
|
||||
meth.addr = methObject["addr"].toVariant().toULongLong();
|
||||
cls.methods << meth;
|
||||
}
|
||||
|
||||
for(QJsonValueRef value2 : classObject["fields"].toArray())
|
||||
{
|
||||
QJsonObject fieldObject = value2.toObject();
|
||||
|
||||
ClassFieldDescription field;
|
||||
field.name = fieldObject["name"].toString();
|
||||
field.addr = fieldObject["addr"].toVariant().toULongLong();
|
||||
cls.fields << field;
|
||||
}
|
||||
|
||||
ret << cls;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
QList<XrefDescription> CutterCore::getXRefs(RVA addr, bool to, bool whole_function, const QString &filterType)
|
||||
{
|
||||
QList<XrefDescription> ret = QList<XrefDescription>();
|
||||
|
28
src/cutter.h
28
src/cutter.h
@ -174,6 +174,27 @@ struct DisassemblyLine
|
||||
QString text;
|
||||
};
|
||||
|
||||
struct ClassMethodDescription
|
||||
{
|
||||
QString name;
|
||||
RVA addr;
|
||||
};
|
||||
|
||||
struct ClassFieldDescription
|
||||
{
|
||||
QString name;
|
||||
RVA addr;
|
||||
};
|
||||
|
||||
struct ClassDescription
|
||||
{
|
||||
QString name;
|
||||
RVA addr;
|
||||
ut64 index;
|
||||
QList<ClassMethodDescription> methods;
|
||||
QList<ClassFieldDescription> fields;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(FunctionDescription)
|
||||
Q_DECLARE_METATYPE(ImportDescription)
|
||||
Q_DECLARE_METATYPE(ExportDescription)
|
||||
@ -186,6 +207,12 @@ Q_DECLARE_METATYPE(FlagDescription)
|
||||
Q_DECLARE_METATYPE(XrefDescription)
|
||||
Q_DECLARE_METATYPE(EntrypointDescription)
|
||||
Q_DECLARE_METATYPE(RBinPluginDescription)
|
||||
Q_DECLARE_METATYPE(ClassMethodDescription)
|
||||
Q_DECLARE_METATYPE(ClassFieldDescription)
|
||||
Q_DECLARE_METATYPE(ClassDescription)
|
||||
Q_DECLARE_METATYPE(const ClassDescription *)
|
||||
Q_DECLARE_METATYPE(const ClassMethodDescription *)
|
||||
Q_DECLARE_METATYPE(const ClassFieldDescription *)
|
||||
|
||||
class CutterCore: public QObject
|
||||
{
|
||||
@ -313,6 +340,7 @@ public:
|
||||
QList<FlagDescription> getAllFlags(QString flagspace = NULL);
|
||||
QList<SectionDescription> getAllSections();
|
||||
QList<EntrypointDescription> getAllEntrypoint();
|
||||
QList<ClassDescription> getAllClasses();
|
||||
|
||||
QList<XrefDescription> getXRefs(RVA addr, bool to, bool whole_function, const QString &filterType = QString::null);
|
||||
|
||||
|
@ -85,7 +85,8 @@ SOURCES += \
|
||||
dialogs/preferences/PreferencesDialog.cpp \
|
||||
dialogs/preferences/GeneralOptionsWidget.cpp \
|
||||
dialogs/preferences/GraphOptionsWidget.cpp \
|
||||
widgets/QuickFilterView.cpp
|
||||
widgets/QuickFilterView.cpp \
|
||||
widgets/ClassesWidget.cpp
|
||||
|
||||
HEADERS += \
|
||||
cutter.h \
|
||||
@ -141,7 +142,8 @@ HEADERS += \
|
||||
dialogs/preferences/PreferencesDialog.h \
|
||||
dialogs/preferences/GeneralOptionsWidget.h \
|
||||
dialogs/preferences/GraphOptionsWidget.h \
|
||||
widgets/QuickFilterView.h
|
||||
widgets/QuickFilterView.h \
|
||||
widgets/ClassesWidget.h
|
||||
|
||||
FORMS += \
|
||||
dialogs/AboutDialog.ui \
|
||||
@ -175,7 +177,8 @@ FORMS += \
|
||||
dialogs/preferences/GeneralOptionsWidget.ui \
|
||||
dialogs/preferences/GraphOptionsWidget.ui \
|
||||
widgets/QuickFilterView.ui \
|
||||
widgets/PseudocodeWidget.ui
|
||||
widgets/PseudocodeWidget.ui \
|
||||
widgets/ClassesWidget.ui
|
||||
|
||||
RESOURCES += \
|
||||
resources.qrc
|
||||
|
@ -20,20 +20,24 @@ static QAbstractItemView::ScrollMode scrollMode()
|
||||
|
||||
namespace qhelpers
|
||||
{
|
||||
void adjustColumns(QTreeWidget *tw, int columnCount, int padding)
|
||||
void adjustColumns(QTreeView *tv, int columnCount, int padding)
|
||||
{
|
||||
const int count = columnCount == 0 ? tw->columnCount() : columnCount;
|
||||
for (int i = 0; i != count; ++i)
|
||||
for (int i = 0; i != columnCount; ++i)
|
||||
{
|
||||
tw->resizeColumnToContents(i);
|
||||
tv->resizeColumnToContents(i);
|
||||
if (padding > 0)
|
||||
{
|
||||
int width = tw->columnWidth(i);
|
||||
tw->setColumnWidth(i, width + padding);
|
||||
int width = tv->columnWidth(i);
|
||||
tv->setColumnWidth(i, width + padding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void adjustColumns(QTreeWidget *tw, int padding)
|
||||
{
|
||||
adjustColumns(tw, tw->columnCount(), padding);
|
||||
}
|
||||
|
||||
QTreeWidgetItem *appendRow(QTreeWidget *tw, const QString &str, const QString &str2,
|
||||
const QString &str3, const QString &str4, const QString &str5)
|
||||
{
|
||||
|
@ -13,10 +13,12 @@ class QTreeWidgetItem;
|
||||
class QAbstractItemView;
|
||||
class QAbstractButton;
|
||||
class QWidget;
|
||||
class QTreeView;
|
||||
|
||||
namespace qhelpers
|
||||
{
|
||||
void adjustColumns(QTreeWidget *tw, int columnCount = 0, int padding = 0);
|
||||
void adjustColumns(QTreeView *tv, int columnCount, int padding);
|
||||
void adjustColumns(QTreeWidget *tw, int padding);
|
||||
|
||||
QTreeWidgetItem *appendRow(QTreeWidget *tw, const QString &str, const QString &str2 = QString(),
|
||||
const QString &str3 = QString(), const QString &str4 = QString(), const QString &str5 = QString());
|
||||
|
283
src/widgets/ClassesWidget.cpp
Normal file
283
src/widgets/ClassesWidget.cpp
Normal file
@ -0,0 +1,283 @@
|
||||
|
||||
#include <QList>
|
||||
|
||||
#include "ClassesWidget.h"
|
||||
#include "ui_ClassesWidget.h"
|
||||
#include "MainWindow.h"
|
||||
#include "utils/Helpers.h"
|
||||
|
||||
ClassesModel::ClassesModel(QList<ClassDescription> *classes, QObject *parent)
|
||||
: QAbstractItemModel(parent),
|
||||
classes(classes)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
QModelIndex ClassesModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
if (!parent.isValid())
|
||||
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
|
||||
}
|
||||
|
||||
QModelIndex ClassesModel::parent(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid() || index.column() != 0)
|
||||
return QModelIndex();
|
||||
|
||||
if (index.internalId() == 0) // root function node
|
||||
return QModelIndex();
|
||||
else // sub-node
|
||||
return this->index((int)(index.internalId() - 1), 0);
|
||||
}
|
||||
|
||||
int ClassesModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (!parent.isValid()) // root
|
||||
{
|
||||
return classes->count();
|
||||
}
|
||||
|
||||
if (parent.internalId() == 0) // methods/fields
|
||||
{
|
||||
const ClassDescription *cls = &classes->at(parent.row());
|
||||
return cls->methods.length() + cls->fields.length();
|
||||
}
|
||||
|
||||
return 0; // below methods/fields
|
||||
}
|
||||
|
||||
int ClassesModel::columnCount(const QModelIndex &) const
|
||||
{
|
||||
return Columns::COUNT;
|
||||
}
|
||||
|
||||
QVariant ClassesModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
const ClassDescription *cls;
|
||||
const ClassMethodDescription *meth = nullptr;
|
||||
const ClassFieldDescription *field = nullptr;
|
||||
if (index.internalId() == 0) // class row
|
||||
{
|
||||
if (index.row() >= classes->count())
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
cls = &classes->at(index.row());
|
||||
}
|
||||
else // method/field row
|
||||
{
|
||||
cls = &classes->at(static_cast<int>(index.internalId() - 1));
|
||||
|
||||
if (index.row() >= cls->methods.length() + cls->fields.length())
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
if (index.row() < cls->methods.length())
|
||||
{
|
||||
meth = &cls->methods[index.row()];
|
||||
}
|
||||
else
|
||||
{
|
||||
field = &cls->fields[index.row() - 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 RAddressString(meth->addr);
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
case OffsetRole:
|
||||
return QVariant::fromValue(meth->addr);
|
||||
case NameRole:
|
||||
return meth->name;
|
||||
case TypeRole:
|
||||
return QVariant::fromValue(METHOD);
|
||||
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 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
|
||||
{
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
switch (index.column())
|
||||
{
|
||||
case NAME:
|
||||
return cls->name;
|
||||
case TYPE:
|
||||
return tr("class");
|
||||
case OFFSET:
|
||||
return RAddressString(cls->addr);
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
case OffsetRole:
|
||||
return QVariant::fromValue(cls->addr);
|
||||
case NameRole:
|
||||
return cls->name;
|
||||
case TypeRole:
|
||||
return QVariant::fromValue(CLASS);
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QVariant ClassesModel::headerData(int section, Qt::Orientation, int role) const
|
||||
{
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
switch (section)
|
||||
{
|
||||
case NAME:
|
||||
return tr("Name");
|
||||
case TYPE:
|
||||
return tr("Type");
|
||||
case OFFSET:
|
||||
return tr("Offset");
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
void ClassesModel::beginReload()
|
||||
{
|
||||
beginResetModel();
|
||||
}
|
||||
|
||||
void ClassesModel::endReload()
|
||||
{
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ClassesSortFilterProxyModel::ClassesSortFilterProxyModel(ClassesModel *source_model, QObject *parent)
|
||||
: QSortFilterProxyModel(parent)
|
||||
{
|
||||
setSourceModel(source_model);
|
||||
}
|
||||
|
||||
bool ClassesSortFilterProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const
|
||||
{
|
||||
QModelIndex index = sourceModel()->index(row, 0, parent);
|
||||
return index.data(ClassesModel::NameRole).toString().contains(filterRegExp());
|
||||
}
|
||||
|
||||
bool ClassesSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
||||
{
|
||||
switch (left.column())
|
||||
{
|
||||
case ClassesModel::OFFSET:
|
||||
{
|
||||
RVA left_offset = left.data(ClassesModel::OffsetRole).toULongLong();
|
||||
RVA right_offset = right.data(ClassesModel::OffsetRole).toULongLong();
|
||||
if (left_offset != right_offset)
|
||||
return left_offset < right_offset;
|
||||
}
|
||||
// fallthrough
|
||||
case ClassesModel::TYPE:
|
||||
{
|
||||
auto left_type = left.data(ClassesModel::TypeRole).value<ClassesModel::RowType>();
|
||||
auto right_type = right.data(ClassesModel::TypeRole).value<ClassesModel::RowType>();
|
||||
if (left_type != right_type)
|
||||
return left_type < right_type;
|
||||
}
|
||||
// fallthrough
|
||||
case ClassesModel::NAME:
|
||||
default:
|
||||
QString left_name = left.data(ClassesModel::NameRole).toString();
|
||||
QString right_name = right.data(ClassesModel::NameRole).toString();
|
||||
return left_name < right_name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
ClassesWidget::ClassesWidget(MainWindow *main, QWidget *parent) :
|
||||
QDockWidget(parent),
|
||||
ui(new Ui::ClassesWidget),
|
||||
main(main)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
// Radare core found in:
|
||||
this->main = main;
|
||||
|
||||
model = new ClassesModel(&classes, this);
|
||||
proxy_model = new ClassesSortFilterProxyModel(model, this);
|
||||
ui->classesTreeView->setModel(proxy_model);
|
||||
ui->classesTreeView->sortByColumn(ClassesModel::TYPE, Qt::AscendingOrder);
|
||||
|
||||
connect(Core(), SIGNAL(refreshAll()), this, SLOT(refreshClasses()));
|
||||
}
|
||||
|
||||
ClassesWidget::~ClassesWidget() {}
|
||||
|
||||
void ClassesWidget::refreshClasses()
|
||||
{
|
||||
model->beginReload();
|
||||
classes = CutterCore::getInstance()->getAllClasses();
|
||||
model->endReload();
|
||||
|
||||
ui->classesTreeView->resizeColumnToContents(0);
|
||||
ui->classesTreeView->resizeColumnToContents(1);
|
||||
ui->classesTreeView->resizeColumnToContents(2);
|
||||
|
||||
ui->classesTreeView->setColumnWidth(0, 200);
|
||||
}
|
||||
|
||||
void ClassesWidget::on_classesTreeView_doubleClicked(const QModelIndex &index)
|
||||
{
|
||||
RVA offset = index.data(ClassesModel::OffsetRole).value<RVA>();
|
||||
CutterCore::getInstance()->seek(offset);
|
||||
}
|
95
src/widgets/ClassesWidget.h
Normal file
95
src/widgets/ClassesWidget.h
Normal file
@ -0,0 +1,95 @@
|
||||
#ifndef CLASSWSWIDGET_H
|
||||
#define CLASSWSWIDGET_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "cutter.h"
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QDockWidget>
|
||||
|
||||
class MainWindow;
|
||||
class QTreeWidget;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ClassesWidget;
|
||||
}
|
||||
|
||||
|
||||
class MainWindow;
|
||||
class QTreeWidgetItem;
|
||||
|
||||
|
||||
class ClassesModel: public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
QList<ClassDescription> *classes;
|
||||
|
||||
public:
|
||||
enum Columns { NAME = 0, TYPE, OFFSET, COUNT };
|
||||
enum RowType { CLASS = 0, METHOD = 1, FIELD = 2 };
|
||||
|
||||
static const int OffsetRole = Qt::UserRole;
|
||||
static const int NameRole = Qt::UserRole + 1;
|
||||
static const int TypeRole = Qt::UserRole + 2;
|
||||
|
||||
explicit ClassesModel(QList<ClassDescription> *classes, QObject *parent = 0);
|
||||
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
|
||||
QModelIndex parent(const QModelIndex &index) const override;
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
|
||||
void beginReload();
|
||||
void endReload();
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(ClassesModel::RowType);
|
||||
|
||||
|
||||
class ClassesSortFilterProxyModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ClassesSortFilterProxyModel(ClassesModel *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 ClassesWidget : public QDockWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ClassesWidget(MainWindow *main, QWidget *parent = 0);
|
||||
~ClassesWidget();
|
||||
|
||||
private slots:
|
||||
void on_classesTreeView_doubleClicked(const QModelIndex &index);
|
||||
|
||||
void refreshClasses();
|
||||
|
||||
private:
|
||||
std::unique_ptr<Ui::ClassesWidget> ui;
|
||||
MainWindow *main;
|
||||
|
||||
ClassesModel *model;
|
||||
ClassesSortFilterProxyModel *proxy_model;
|
||||
QList<ClassDescription> classes;
|
||||
};
|
||||
|
||||
|
||||
#endif // CLASSWSWIDGET_H
|
58
src/widgets/ClassesWidget.ui
Normal file
58
src/widgets/ClassesWidget.ui
Normal file
@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ClassesWidget</class>
|
||||
<widget class="QDockWidget" name="ClassesWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Classes</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="dockWidgetContents">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTreeView" name="classesTreeView">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QTreeView::item
|
||||
{
|
||||
padding-top: 1px;
|
||||
padding-bottom: 1px;
|
||||
}</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="expandsOnDoubleClick">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -162,7 +162,7 @@ void CommentsWidget::refreshTree()
|
||||
|
||||
nestedComments[fcn_name].append(comment);
|
||||
}
|
||||
qhelpers::adjustColumns(ui->commentsTreeWidget);
|
||||
qhelpers::adjustColumns(ui->commentsTreeWidget, 0);
|
||||
|
||||
// Add nested comments
|
||||
ui->nestedCmtsTreeWidget->clear();
|
||||
@ -180,5 +180,5 @@ void CommentsWidget::refreshTree()
|
||||
}
|
||||
ui->nestedCmtsTreeWidget->addTopLevelItem(item);
|
||||
}
|
||||
qhelpers::adjustColumns(ui->nestedCmtsTreeWidget);
|
||||
qhelpers::adjustColumns(ui->nestedCmtsTreeWidget, 0);
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ void RelocsWidget::fillTreeWidget()
|
||||
ui->relocsTreeWidget->addTopLevelItem(item);
|
||||
}
|
||||
|
||||
qhelpers::adjustColumns(ui->relocsTreeWidget);
|
||||
qhelpers::adjustColumns(ui->relocsTreeWidget, 0);
|
||||
}
|
||||
|
||||
void RelocsWidget::setScrollMode()
|
||||
|
@ -34,7 +34,7 @@ void SectionsWidget::refreshSections()
|
||||
fillSections(row++, section);
|
||||
}
|
||||
|
||||
qhelpers::adjustColumns(tree);
|
||||
qhelpers::adjustColumns(tree, 0);
|
||||
}
|
||||
|
||||
void SectionsWidget::setupViews()
|
||||
|
@ -44,7 +44,7 @@ void SymbolsWidget::fillSymbols()
|
||||
item->setData(0, Qt::UserRole, QVariant::fromValue(symbol));
|
||||
ui->symbolsTreeWidget->addTopLevelItem(item);
|
||||
}
|
||||
qhelpers::adjustColumns(ui->symbolsTreeWidget);
|
||||
qhelpers::adjustColumns(ui->symbolsTreeWidget, 0);
|
||||
}
|
||||
|
||||
void SymbolsWidget::setScrollMode()
|
||||
|
Loading…
Reference in New Issue
Block a user