mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-30 08:45:25 +00:00
Refactor SectionsWidget to use Model/View archictecture (#475)
This commit is contained in:
parent
fd829986af
commit
a30ac22056
@ -275,6 +275,7 @@ Q_DECLARE_METATYPE(ResourcesDescription)
|
|||||||
Q_DECLARE_METATYPE(VTableDescription)
|
Q_DECLARE_METATYPE(VTableDescription)
|
||||||
Q_DECLARE_METATYPE(TypeDescription)
|
Q_DECLARE_METATYPE(TypeDescription)
|
||||||
Q_DECLARE_METATYPE(SearchDescription)
|
Q_DECLARE_METATYPE(SearchDescription)
|
||||||
|
Q_DECLARE_METATYPE(SectionDescription)
|
||||||
|
|
||||||
class CutterCore: public QObject
|
class CutterCore: public QObject
|
||||||
{
|
{
|
||||||
|
@ -120,7 +120,6 @@ SOURCES += \
|
|||||||
widgets/PieView.cpp \
|
widgets/PieView.cpp \
|
||||||
widgets/RelocsWidget.cpp \
|
widgets/RelocsWidget.cpp \
|
||||||
widgets/SdbDock.cpp \
|
widgets/SdbDock.cpp \
|
||||||
widgets/SectionsDock.cpp \
|
|
||||||
widgets/SectionsWidget.cpp \
|
widgets/SectionsWidget.cpp \
|
||||||
widgets/Sidebar.cpp \
|
widgets/Sidebar.cpp \
|
||||||
widgets/StringsWidget.cpp \
|
widgets/StringsWidget.cpp \
|
||||||
@ -192,7 +191,6 @@ HEADERS += \
|
|||||||
widgets/PieView.h \
|
widgets/PieView.h \
|
||||||
widgets/RelocsWidget.h \
|
widgets/RelocsWidget.h \
|
||||||
widgets/SdbDock.h \
|
widgets/SdbDock.h \
|
||||||
widgets/SectionsDock.h \
|
|
||||||
widgets/SectionsWidget.h \
|
widgets/SectionsWidget.h \
|
||||||
widgets/Sidebar.h \
|
widgets/Sidebar.h \
|
||||||
widgets/StringsWidget.h \
|
widgets/StringsWidget.h \
|
||||||
@ -252,7 +250,7 @@ FORMS += \
|
|||||||
widgets/ImportsWidget.ui \
|
widgets/ImportsWidget.ui \
|
||||||
widgets/SdbDock.ui \
|
widgets/SdbDock.ui \
|
||||||
widgets/RelocsWidget.ui \
|
widgets/RelocsWidget.ui \
|
||||||
widgets/SectionsDock.ui \
|
widgets/SectionsWidget.ui \
|
||||||
widgets/Sidebar.ui \
|
widgets/Sidebar.ui \
|
||||||
widgets/StringsWidget.ui \
|
widgets/StringsWidget.ui \
|
||||||
widgets/SymbolsWidget.ui \
|
widgets/SymbolsWidget.ui \
|
||||||
|
@ -53,7 +53,6 @@
|
|||||||
#include "widgets/SearchWidget.h"
|
#include "widgets/SearchWidget.h"
|
||||||
#include "widgets/SymbolsWidget.h"
|
#include "widgets/SymbolsWidget.h"
|
||||||
#include "widgets/StringsWidget.h"
|
#include "widgets/StringsWidget.h"
|
||||||
#include "widgets/SectionsDock.h"
|
|
||||||
#include "widgets/RelocsWidget.h"
|
#include "widgets/RelocsWidget.h"
|
||||||
#include "widgets/FlagsWidget.h"
|
#include "widgets/FlagsWidget.h"
|
||||||
#include "widgets/VisualNavbar.h"
|
#include "widgets/VisualNavbar.h"
|
||||||
@ -163,7 +162,7 @@ void MainWindow::initUI()
|
|||||||
// Hide centralWidget as we do not need it
|
// Hide centralWidget as we do not need it
|
||||||
ui->centralWidget->hide();
|
ui->centralWidget->hide();
|
||||||
|
|
||||||
sectionsDock = new SectionsDock(this, ui->actionSections);
|
sectionsDock = new SectionsWidget(this, ui->actionSections);
|
||||||
entrypointDock = new EntrypointWidget(this, ui->actionEntrypoints);
|
entrypointDock = new EntrypointWidget(this, ui->actionEntrypoints);
|
||||||
functionsDock = new FunctionsWidget(this, ui->actionFunctions);
|
functionsDock = new FunctionsWidget(this, ui->actionFunctions);
|
||||||
importsDock = new ImportsWidget(this, ui->actionImports);
|
importsDock = new ImportsWidget(this, ui->actionImports);
|
||||||
|
@ -32,7 +32,7 @@ class Dashboard;
|
|||||||
class QLineEdit;
|
class QLineEdit;
|
||||||
class SdbDock;
|
class SdbDock;
|
||||||
class QAction;
|
class QAction;
|
||||||
class SectionsDock;
|
class SectionsWidget;
|
||||||
class ConsoleWidget;
|
class ConsoleWidget;
|
||||||
class EntrypointWidget;
|
class EntrypointWidget;
|
||||||
class DisassemblerGraphView;
|
class DisassemblerGraphView;
|
||||||
@ -188,7 +188,7 @@ private:
|
|||||||
Dashboard *dashboardDock = nullptr;
|
Dashboard *dashboardDock = nullptr;
|
||||||
QLineEdit *gotoEntry = nullptr;
|
QLineEdit *gotoEntry = nullptr;
|
||||||
SdbDock *sdbDock = nullptr;
|
SdbDock *sdbDock = nullptr;
|
||||||
SectionsDock *sectionsDock = nullptr;
|
SectionsWidget *sectionsDock = nullptr;
|
||||||
ConsoleWidget *consoleDock = nullptr;
|
ConsoleWidget *consoleDock = nullptr;
|
||||||
ClassesWidget *classesDock = nullptr;
|
ClassesWidget *classesDock = nullptr;
|
||||||
ResourcesWidget *resourcesDock = nullptr;
|
ResourcesWidget *resourcesDock = nullptr;
|
||||||
|
@ -121,8 +121,6 @@ bool ExportsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &rig
|
|||||||
return leftExp.vaddr < rightExp.vaddr;
|
return leftExp.vaddr < rightExp.vaddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ExportsWidget::ExportsWidget(MainWindow *main, QAction *action) :
|
ExportsWidget::ExportsWidget(MainWindow *main, QAction *action) :
|
||||||
CutterDockWidget(main, action),
|
CutterDockWidget(main, action),
|
||||||
ui(new Ui::ExportsWidget)
|
ui(new Ui::ExportsWidget)
|
||||||
|
@ -16,12 +16,7 @@ namespace Ui {
|
|||||||
class ExportsWidget;
|
class ExportsWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ExportsModel : public QAbstractListModel
|
||||||
class MainWindow;
|
|
||||||
class QTreeWidgetItem;
|
|
||||||
|
|
||||||
|
|
||||||
class ExportsModel: public QAbstractListModel
|
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -44,8 +39,6 @@ public:
|
|||||||
void endReloadExports();
|
void endReloadExports();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ExportsProxyModel : public QSortFilterProxyModel
|
class ExportsProxyModel : public QSortFilterProxyModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -58,8 +51,6 @@ protected:
|
|||||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ExportsWidget : public CutterDockWidget
|
class ExportsWidget : public CutterDockWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -83,5 +74,4 @@ private:
|
|||||||
void setScrollMode();
|
void setScrollMode();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // EXPORTSWIDGET_H
|
#endif // EXPORTSWIDGET_H
|
||||||
|
@ -1,71 +0,0 @@
|
|||||||
#include "SectionsDock.h"
|
|
||||||
#include "ui_SectionsDock.h"
|
|
||||||
|
|
||||||
#include "MainWindow.h"
|
|
||||||
#include "widgets/SectionsWidget.h"
|
|
||||||
|
|
||||||
#include <QMenu>
|
|
||||||
#include <QResizeEvent>
|
|
||||||
|
|
||||||
|
|
||||||
SectionsDock::SectionsDock(MainWindow *main, QAction *action) :
|
|
||||||
CutterDockWidget(main, action),
|
|
||||||
ui(new Ui::SectionsDock),
|
|
||||||
main(main)
|
|
||||||
{
|
|
||||||
ui->setupUi(this);
|
|
||||||
|
|
||||||
this->sectionsWidget = new SectionsWidget(this->main);
|
|
||||||
this->setWidget(this->sectionsWidget);
|
|
||||||
this->sectionsWidget->setContentsMargins(0, 0, 0, 5);
|
|
||||||
this->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
||||||
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)),
|
|
||||||
this, SLOT(showSectionsContextMenu(const QPoint &)));
|
|
||||||
}
|
|
||||||
|
|
||||||
SectionsDock::~SectionsDock() {}
|
|
||||||
|
|
||||||
void SectionsDock::showSectionsContextMenu(const QPoint &pt)
|
|
||||||
{
|
|
||||||
// Set functions popup menu
|
|
||||||
QMenu *menu = new QMenu(this);
|
|
||||||
menu->clear();
|
|
||||||
menu->addAction(ui->actionHorizontal);
|
|
||||||
menu->addAction(ui->actionVertical);
|
|
||||||
|
|
||||||
if (this->sectionsWidget->orientation() == 1) {
|
|
||||||
ui->actionHorizontal->setChecked(true);
|
|
||||||
ui->actionVertical->setChecked(false);
|
|
||||||
} else {
|
|
||||||
ui->actionVertical->setChecked(true);
|
|
||||||
ui->actionHorizontal->setChecked(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
||||||
menu->exec(this->mapToGlobal(pt));
|
|
||||||
delete menu;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SectionsDock::resizeEvent(QResizeEvent *event)
|
|
||||||
{
|
|
||||||
if (main->responsive && isVisible()) {
|
|
||||||
if (event->size().width() >= event->size().height()) {
|
|
||||||
// Set horizontal view (list)
|
|
||||||
this->on_actionHorizontal_triggered();
|
|
||||||
} else {
|
|
||||||
// Set vertical view (Tree)
|
|
||||||
this->on_actionVertical_triggered();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QWidget::resizeEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SectionsDock::on_actionVertical_triggered()
|
|
||||||
{
|
|
||||||
this->sectionsWidget->setOrientation(Qt::Vertical);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SectionsDock::on_actionHorizontal_triggered()
|
|
||||||
{
|
|
||||||
this->sectionsWidget->setOrientation(Qt::Horizontal);
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
#ifndef SECTIONSDOCK_H
|
|
||||||
#define SECTIONSDOCK_H
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "CutterDockWidget.h"
|
|
||||||
|
|
||||||
class MainWindow;
|
|
||||||
class SectionsWidget;
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class SectionsDock;
|
|
||||||
}
|
|
||||||
|
|
||||||
class SectionsDock : public CutterDockWidget
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit SectionsDock(MainWindow *main, QAction *action = nullptr);
|
|
||||||
~SectionsDock();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void resizeEvent(QResizeEvent *event) override;
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
|
|
||||||
void showSectionsContextMenu(const QPoint &pt);
|
|
||||||
|
|
||||||
void on_actionVertical_triggered();
|
|
||||||
|
|
||||||
void on_actionHorizontal_triggered();
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::unique_ptr<Ui::SectionsDock> ui;
|
|
||||||
MainWindow *main;
|
|
||||||
SectionsWidget *sectionsWidget;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // SECTIONSDOCK_H
|
|
@ -1,73 +1,32 @@
|
|||||||
#include "widgets/SectionsWidget.h"
|
#include <QMenu>
|
||||||
#include "widgets/PieView.h"
|
#include <QSplitter>
|
||||||
|
#include <QTreeView>
|
||||||
|
#include <QResizeEvent>
|
||||||
|
|
||||||
|
#include "SectionsWidget.h"
|
||||||
|
#include "ui_SectionsWidget.h"
|
||||||
|
#include "PieView.h"
|
||||||
|
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
#include "utils/Helpers.h"
|
#include "utils/Helpers.h"
|
||||||
|
|
||||||
#include <QtWidgets>
|
SectionsModel::SectionsModel(QList<SectionDescription> *sections, QObject *parent)
|
||||||
#include <QTreeWidget>
|
: QAbstractListModel(parent),
|
||||||
|
sections(sections)
|
||||||
SectionsWidget::SectionsWidget(MainWindow *main, QWidget *parent) :
|
|
||||||
QSplitter(main),
|
|
||||||
main(main)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(parent);
|
|
||||||
|
|
||||||
setupViews();
|
|
||||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
|
||||||
|
|
||||||
connect(this->tree, SIGNAL(doubleClicked(const QModelIndex &)), this,
|
|
||||||
SLOT(onSectionsDoubleClicked(const QModelIndex &)));
|
|
||||||
|
|
||||||
tree->sortByColumn(0, Qt::AscendingOrder);
|
|
||||||
|
|
||||||
connect(Core(), SIGNAL(refreshAll()), this, SLOT(refreshSections()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SectionsWidget::refreshSections()
|
int SectionsModel::rowCount(const QModelIndex &) const
|
||||||
{
|
{
|
||||||
tree->clear();
|
return sections->count();
|
||||||
|
|
||||||
int row = 0;
|
|
||||||
for (auto section : Core()->getAllSections()) {
|
|
||||||
fillSections(row++, section);
|
|
||||||
}
|
|
||||||
|
|
||||||
qhelpers::adjustColumns(tree, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SectionsWidget::setupViews()
|
int SectionsModel::columnCount(const QModelIndex &) const
|
||||||
{
|
{
|
||||||
// Table view
|
return SectionsModel::ColumnCount;
|
||||||
this->tree = new QTreeWidget;
|
|
||||||
this->tree->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
||||||
this->tree->setIndentation(10);
|
|
||||||
|
|
||||||
// Setup TreeWidget
|
|
||||||
this->tree->setColumnCount(4);
|
|
||||||
QList<QString> headers;
|
|
||||||
headers << tr("Name") << tr("Size") << tr("Address") << tr("End Address");
|
|
||||||
this->tree->setHeaderLabels(headers);
|
|
||||||
|
|
||||||
this->tree->setFrameShape(QFrame::NoFrame);
|
|
||||||
this->tree->setSortingEnabled(true);
|
|
||||||
|
|
||||||
pieChart = new PieView;
|
|
||||||
pieChart->setFrameShape(QFrame::NoFrame);
|
|
||||||
pieChart->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
||||||
this->addWidget(this->tree);
|
|
||||||
this->addWidget(pieChart);
|
|
||||||
this->setStretchFactor(0, 4);
|
|
||||||
|
|
||||||
//this->tree->setModel(model);
|
|
||||||
pieChart->setModel(this->tree->model());
|
|
||||||
|
|
||||||
QItemSelectionModel *selectionModel = new QItemSelectionModel(this->tree->model());
|
|
||||||
this->tree->setSelectionModel(selectionModel);
|
|
||||||
pieChart->setSelectionModel(selectionModel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SectionsWidget::fillSections(int row, const SectionDescription §ion)
|
QVariant SectionsModel::data(const QModelIndex &index, int role) const
|
||||||
{
|
{
|
||||||
// TODO: create unique colors, e. g. use HSV color space and rotate in H for 360/size
|
// TODO: create unique colors, e. g. use HSV color space and rotate in H for 360/size
|
||||||
static const QList<QColor> colors = { QColor("#1ABC9C"), //TURQUOISE
|
static const QList<QColor> colors = { QColor("#1ABC9C"), //TURQUOISE
|
||||||
@ -83,14 +42,200 @@ void SectionsWidget::fillSections(int row, const SectionDescription §ion)
|
|||||||
QColor("#95A5A6") //COBCRETE
|
QColor("#95A5A6") //COBCRETE
|
||||||
};
|
};
|
||||||
|
|
||||||
QTreeWidgetItem *tempItem = new QTreeWidgetItem();
|
if (index.row() >= sections->count())
|
||||||
tempItem->setText(0, section.name);
|
return QVariant();
|
||||||
tempItem->setData(1, Qt::DisplayRole, section.size);
|
|
||||||
tempItem->setTextAlignment(1, Qt::AlignRight | Qt::AlignVCenter);
|
const SectionDescription §ion = sections->at(index.row());
|
||||||
tempItem->setText(2, RAddressString(section.vaddr));
|
|
||||||
tempItem->setText(3, RAddressString(section.vaddr + section.vsize));
|
switch (role) {
|
||||||
tempItem->setData(0, Qt::DecorationRole, colors[row % colors.size()]);
|
case Qt::DisplayRole:
|
||||||
this->tree->insertTopLevelItem(0, tempItem);
|
switch (index.column()) {
|
||||||
|
case SectionsModel::NameColumn:
|
||||||
|
return section.name;
|
||||||
|
case SectionsModel::SizeColumn:
|
||||||
|
return section.size;
|
||||||
|
case SectionsModel::AddressColumn:
|
||||||
|
return RAddressString(section.vaddr);
|
||||||
|
case SectionsModel::EndAddressColumn:
|
||||||
|
return RAddressString(section.vaddr + section.size);
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
case Qt::DecorationRole:
|
||||||
|
if (index.column() == 0)
|
||||||
|
return colors[index.row() % colors.size()];
|
||||||
|
return QVariant();
|
||||||
|
case SectionsModel::SectionDescriptionRole:
|
||||||
|
return QVariant::fromValue(section);
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant SectionsModel::headerData(int section, Qt::Orientation, int role) const
|
||||||
|
{
|
||||||
|
switch (role) {
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
switch (section) {
|
||||||
|
case SectionsModel::NameColumn:
|
||||||
|
return tr("Name");
|
||||||
|
case SectionsModel::SizeColumn:
|
||||||
|
return tr("Size");
|
||||||
|
case SectionsModel::AddressColumn:
|
||||||
|
return tr("Address");
|
||||||
|
case SectionsModel::EndAddressColumn:
|
||||||
|
return tr("EndAddress");
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SectionsModel::beginReloadSections()
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SectionsModel::endReloadSections()
|
||||||
|
{
|
||||||
|
endResetModel();
|
||||||
|
// Update PieChart
|
||||||
|
emit dataChanged(QModelIndex(), QModelIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
SectionsProxyModel::SectionsProxyModel(SectionsModel *sourceModel, QObject *parent)
|
||||||
|
: QSortFilterProxyModel(parent)
|
||||||
|
{
|
||||||
|
setSourceModel(sourceModel);
|
||||||
|
setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||||
|
setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||||
|
connect(sourceModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
|
||||||
|
this, SLOT(onSourceModelDataChanged(QModelIndex,QModelIndex,QVector<int>)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SectionsProxyModel::onSourceModelDataChanged(const QModelIndex &topLeft,
|
||||||
|
const QModelIndex &bottomRight,
|
||||||
|
const QVector<int> &roles)
|
||||||
|
{
|
||||||
|
// Pass the signal further to update PieChart
|
||||||
|
emit dataChanged(topLeft, bottomRight, roles);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SectionsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
||||||
|
{
|
||||||
|
auto leftSection = left.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>();
|
||||||
|
auto rightSection = right.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>();
|
||||||
|
|
||||||
|
switch (left.column()) {
|
||||||
|
case SectionsModel::NameColumn:
|
||||||
|
return leftSection.name < rightSection.name;
|
||||||
|
case SectionsModel::SizeColumn:
|
||||||
|
return leftSection.size < rightSection.size;
|
||||||
|
case SectionsModel::AddressColumn:
|
||||||
|
case SectionsModel::EndAddressColumn:
|
||||||
|
return leftSection.vaddr < rightSection.vaddr;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SectionsWidget::SectionsWidget(MainWindow *main, QAction *action) :
|
||||||
|
CutterDockWidget(main, action),
|
||||||
|
ui(new Ui::SectionsWidget),
|
||||||
|
main(main)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
sectionsModel = new SectionsModel(§ions, this);
|
||||||
|
sectionsProxyModel = new SectionsProxyModel(sectionsModel, this);
|
||||||
|
|
||||||
|
setupViews();
|
||||||
|
|
||||||
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||||
|
|
||||||
|
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)),
|
||||||
|
this, SLOT(showSectionsContextMenu(const QPoint &)));
|
||||||
|
|
||||||
|
connect(Core(), SIGNAL(refreshAll()), this, SLOT(refreshSections()));
|
||||||
|
}
|
||||||
|
|
||||||
|
SectionsWidget::~SectionsWidget() {}
|
||||||
|
|
||||||
|
void SectionsWidget::resizeEvent(QResizeEvent *event)
|
||||||
|
{
|
||||||
|
if (main->responsive && isVisible()) {
|
||||||
|
if (event->size().width() >= event->size().height()) {
|
||||||
|
on_actionHorizontal_triggered();
|
||||||
|
} else {
|
||||||
|
on_actionVertical_triggered();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QWidget::resizeEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SectionsWidget::showSectionsContextMenu(const QPoint &pt)
|
||||||
|
{
|
||||||
|
// Set functions popup menu
|
||||||
|
QMenu *menu = new QMenu(this);
|
||||||
|
menu->clear();
|
||||||
|
menu->addAction(ui->actionHorizontal);
|
||||||
|
menu->addAction(ui->actionVertical);
|
||||||
|
|
||||||
|
if (splitter->orientation() == 1) {
|
||||||
|
ui->actionHorizontal->setChecked(true);
|
||||||
|
ui->actionVertical->setChecked(false);
|
||||||
|
} else {
|
||||||
|
ui->actionVertical->setChecked(true);
|
||||||
|
ui->actionHorizontal->setChecked(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
menu->exec(mapToGlobal(pt));
|
||||||
|
delete menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SectionsWidget::refreshSections()
|
||||||
|
{
|
||||||
|
sectionsModel->beginReloadSections();
|
||||||
|
sections = Core()->getAllSections();
|
||||||
|
sectionsModel->endReloadSections();
|
||||||
|
|
||||||
|
qhelpers::adjustColumns(sectionsTable, SectionsModel::ColumnCount, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SectionsWidget::setupViews()
|
||||||
|
{
|
||||||
|
splitter = new QSplitter;
|
||||||
|
sectionsTable = new QTreeView;
|
||||||
|
sectionsPieChart = new PieView;
|
||||||
|
|
||||||
|
splitter->addWidget(sectionsTable);
|
||||||
|
splitter->addWidget(sectionsPieChart);
|
||||||
|
//splitter->setStretchFactor(0, 4);
|
||||||
|
|
||||||
|
sectionsTable->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
|
sectionsTable->setIndentation(10);
|
||||||
|
sectionsTable->setFrameShape(QFrame::NoFrame);
|
||||||
|
sectionsTable->setSortingEnabled(true);
|
||||||
|
sectionsTable->sortByColumn(SectionsModel::NameColumn, Qt::AscendingOrder);
|
||||||
|
connect(sectionsTable, SIGNAL(doubleClicked(const QModelIndex &)),
|
||||||
|
this, SLOT(onSectionsDoubleClicked(const QModelIndex &)));
|
||||||
|
|
||||||
|
sectionsPieChart->setFrameShape(QFrame::NoFrame);
|
||||||
|
sectionsPieChart->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
|
|
||||||
|
sectionsTable->setModel(sectionsProxyModel);
|
||||||
|
sectionsPieChart->setModel(sectionsProxyModel);
|
||||||
|
|
||||||
|
QItemSelectionModel *selectionModel = new QItemSelectionModel(sectionsProxyModel);
|
||||||
|
sectionsTable->setSelectionModel(selectionModel);
|
||||||
|
sectionsPieChart->setSelectionModel(selectionModel);
|
||||||
|
|
||||||
|
setWidget(splitter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SectionsWidget::onSectionsDoubleClicked(const QModelIndex &index)
|
void SectionsWidget::onSectionsDoubleClicked(const QModelIndex &index)
|
||||||
@ -98,7 +243,16 @@ void SectionsWidget::onSectionsDoubleClicked(const QModelIndex &index)
|
|||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QTreeWidgetItem *section = tree->topLevelItem(index.row());
|
auto section = index.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>();
|
||||||
auto addr = section->text(2);
|
Core()->seek(section.vaddr);
|
||||||
Core()->seek(addr);
|
}
|
||||||
|
|
||||||
|
void SectionsWidget::on_actionVertical_triggered()
|
||||||
|
{
|
||||||
|
splitter->setOrientation(Qt::Vertical);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SectionsWidget::on_actionHorizontal_triggered()
|
||||||
|
{
|
||||||
|
splitter->setOrientation(Qt::Horizontal);
|
||||||
}
|
}
|
||||||
|
@ -1,41 +1,92 @@
|
|||||||
#ifndef SECTIONSWIDGET_H
|
#ifndef SECTIONSWIDGET_H
|
||||||
#define SECTIONSWIDGET_H
|
#define SECTIONSWIDGET_H
|
||||||
|
|
||||||
#include <QSplitter>
|
#include <memory>
|
||||||
|
|
||||||
class MainWindow;
|
#include <QAbstractListModel>
|
||||||
class QTreeWidget;
|
#include <QSortFilterProxyModel>
|
||||||
class QAbstractItemModel;
|
|
||||||
|
#include "Cutter.h"
|
||||||
|
#include "CutterDockWidget.h"
|
||||||
|
|
||||||
|
class QSplitter;
|
||||||
|
class QTreeView;
|
||||||
class QAbstractItemView;
|
class QAbstractItemView;
|
||||||
class QItemSelectionModel;
|
class QResizeEvent;
|
||||||
|
class MainWindow;
|
||||||
struct SectionDescription;
|
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class SectionsWidget;
|
class SectionsWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
class SectionsWidget : public QSplitter
|
class SectionsModel : public QAbstractListModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<SectionDescription> *sections;
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum Column { NameColumn = 0, SizeColumn, AddressColumn, EndAddressColumn, ColumnCount };
|
||||||
|
enum Role { SectionDescriptionRole = Qt::UserRole };
|
||||||
|
|
||||||
|
SectionsModel(QList<SectionDescription> *sections, QObject *parent = Q_NULLPTR);
|
||||||
|
|
||||||
|
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 beginReloadSections();
|
||||||
|
void endReloadSections();
|
||||||
|
};
|
||||||
|
|
||||||
|
class SectionsProxyModel : public QSortFilterProxyModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit SectionsWidget(MainWindow *main, QWidget *parent = 0);
|
SectionsProxyModel(SectionsModel *sourceModel, QObject *parent = Q_NULLPTR);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onSourceModelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight,
|
||||||
|
const QVector<int>& roles);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SectionsWidget : public CutterDockWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SectionsWidget(MainWindow *main, QAction *action = Q_NULLPTR);
|
||||||
|
~SectionsWidget();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void resizeEvent(QResizeEvent *event) override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void refreshSections();
|
void refreshSections();
|
||||||
|
void showSectionsContextMenu(const QPoint &pt);
|
||||||
|
void on_actionVertical_triggered();
|
||||||
|
void on_actionHorizontal_triggered();
|
||||||
void onSectionsDoubleClicked(const QModelIndex &index);
|
void onSectionsDoubleClicked(const QModelIndex &index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QAbstractItemView *pieChart;
|
std::unique_ptr<Ui::SectionsWidget> ui;
|
||||||
QItemSelectionModel *selectionModel;
|
|
||||||
MainWindow *main;
|
QList<SectionDescription> sections;
|
||||||
QTreeWidget *tree;
|
SectionsModel *sectionsModel;
|
||||||
|
SectionsProxyModel *sectionsProxyModel;
|
||||||
|
QSplitter *splitter;
|
||||||
|
QTreeView *sectionsTable;
|
||||||
|
QAbstractItemView *sectionsPieChart;
|
||||||
|
MainWindow *main;
|
||||||
|
|
||||||
void setupViews();
|
void setupViews();
|
||||||
|
|
||||||
void fillSections(int row, const SectionDescription §ion);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SECTIONSWIDGET_H
|
#endif // SECTIONSWIDGET_H
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<ui version="4.0">
|
<ui version="4.0">
|
||||||
<class>SectionsDock</class>
|
<class>SectionsWidget</class>
|
||||||
<widget class="QDockWidget" name="SectionsDock">
|
<widget class="QDockWidget" name="SectionsWidget">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
@ -13,7 +13,6 @@
|
|||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Sections</string>
|
<string>Sections</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="dockWidgetContents"/>
|
|
||||||
<action name="actionVertical">
|
<action name="actionVertical">
|
||||||
<property name="checkable">
|
<property name="checkable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
Loading…
Reference in New Issue
Block a user