cutter/src/widgets/SectionsWidget.h

202 lines
5.0 KiB
C++

#ifndef SECTIONSWIDGET_H
#define SECTIONSWIDGET_H
#include <memory>
#include <map>
#include <QtWidgets/QToolButton>
#include <QAbstractListModel>
#include <QSortFilterProxyModel>
#include <QGraphicsScene>
#include <QLabel>
#include <QHash>
#include "core/Cutter.h"
#include "CutterDockWidget.h"
#include "widgets/ListDockWidget.h"
class QAbstractItemView;
class SectionsWidget;
class AbstractAddrDock;
class AddrDockScene;
class QGraphicsSceneMouseEvent;
class RawAddrDock;
class VirtualAddrDock;
class QuickFilterView;
class QGraphicsView;
class QGraphicsRectItem;
class SectionsModel : public AddressableItemModel<QAbstractListModel>
{
Q_OBJECT
friend SectionsWidget;
private:
QList<SectionDescription> *sections;
public:
enum Column { NameColumn = 0, SizeColumn, AddressColumn, EndAddressColumn, PermissionsColumn, EntropyColumn, ColumnCount };
enum Role { SectionDescriptionRole = Qt::UserRole };
SectionsModel(QList<SectionDescription> *sections, QObject *parent = 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;
RVA address(const QModelIndex &index) const override;
QString name(const QModelIndex &index) const override;
};
class SectionsProxyModel : public AddressableFilterProxyModel
{
Q_OBJECT
public:
SectionsProxyModel(SectionsModel *sourceModel, QObject *parent = nullptr);
protected:
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
};
class SectionsWidget : public ListDockWidget
{
Q_OBJECT
public:
explicit SectionsWidget(MainWindow *main, QAction *action = nullptr);
~SectionsWidget();
private slots:
void refreshSections();
void refreshDocks();
protected:
void resizeEvent(QResizeEvent *event) override;
private:
QList<SectionDescription> sections;
SectionsModel *sectionsModel;
SectionsProxyModel *proxyModel;
QWidget *addrDockWidget;
RawAddrDock *rawAddrDock;
VirtualAddrDock *virtualAddrDock;
QToolButton *toggleButton;
/**
* RefreshDeferrer for loading the section data
*/
RefreshDeferrer *sectionsRefreshDeferrer;
/**
* RefreshDeferrer for updating the visualization docks
*/
RefreshDeferrer *dockRefreshDeferrer;
void initSectionsTable();
void initQuickFilter();
void initConnects();
void initAddrMapDocks();
void drawIndicatorOnAddrDocks();
void updateToggle();
};
class AbstractAddrDock : public QDockWidget
{
Q_OBJECT
friend SectionsWidget;
public:
explicit AbstractAddrDock(SectionsModel *model, QWidget *parent = nullptr);
~AbstractAddrDock();
virtual void updateDock();
protected:
int indicatorHeight;
int indicatorParamPosY;
float heightThreshold;
float heightDivisor;
int rectOffset;
int rectWidthMin;
int rectWidthMax;
QColor indicatorColor;
QColor textColor;
AddrDockScene *addrDockScene;
QGraphicsView *graphicsView;
SectionsProxyModel *proxyModel;
void addTextItem(QColor color, QPoint pos, QString string);
int getAdjustedSize(int size, int validMinSize);
int getRectWidth();
int getIndicatorWidth();
int getValidMinSize();
virtual RVA getSizeOfSection(const SectionDescription &section) =0;
virtual RVA getAddressOfSection(const SectionDescription &section) =0;
private:
void drawIndicator(QString name, float ratio);
};
class AddrDockScene : public QGraphicsScene
{
Q_OBJECT
public:
explicit AddrDockScene(QWidget *parent = nullptr);
~AddrDockScene();
bool disableCenterOn;
QHash<QString, RVA> nameAddrMap;
QHash<QString, RVA> nameAddrSizeMap;
QHash<QString, RVA> seekAddrMap;
QHash<QString, RVA> seekAddrSizeMap;
QHash<QString, int> namePosYMap;
QHash<QString, int> nameHeightMap;
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
private:
RVA getAddrFromPos(int posY, bool seek);
};
class RawAddrDock : public AbstractAddrDock
{
Q_OBJECT
public:
explicit RawAddrDock(SectionsModel *model, QWidget *parent = nullptr);
~RawAddrDock() = default;
void updateDock() override;
protected:
RVA getSizeOfSection(const SectionDescription &section) override { return section.size; };
RVA getAddressOfSection(const SectionDescription &section) override { return section.paddr; };
};
class VirtualAddrDock : public AbstractAddrDock
{
Q_OBJECT
public:
explicit VirtualAddrDock(SectionsModel *model, QWidget *parent = nullptr);
~VirtualAddrDock() = default;
void updateDock() override;
protected:
RVA getSizeOfSection(const SectionDescription &section) override { return section.vsize; };
RVA getAddressOfSection(const SectionDescription &section) override { return section.vaddr; };
};
#endif // SECTIONSWIDGET_H