diff options
Diffstat (limited to 'ui')
| -rw-r--r-- | ui/clickablelabel.h | 6 | ||||
| -rw-r--r-- | ui/datatypelist.h | 26 | ||||
| -rw-r--r-- | ui/disassemblyview.h | 20 | ||||
| -rw-r--r-- | ui/featuremap.h | 6 | ||||
| -rw-r--r-- | ui/filecontext.h | 20 | ||||
| -rw-r--r-- | ui/flowgraphwidget.h | 20 | ||||
| -rw-r--r-- | ui/globalarea.h | 4 | ||||
| -rw-r--r-- | ui/hexeditor.h | 16 | ||||
| -rw-r--r-- | ui/ilchooser.h | 34 | ||||
| -rw-r--r-- | ui/linearview.h | 28 | ||||
| -rw-r--r-- | ui/minigraph.h | 20 | ||||
| -rw-r--r-- | ui/pane.h | 356 | ||||
| -rw-r--r-- | ui/reflectionview.h | 49 | ||||
| -rw-r--r-- | ui/searchresult.h | 19 | ||||
| -rw-r--r-- | ui/sidebar.h | 18 | ||||
| -rw-r--r-- | ui/syncgroup.h | 39 | ||||
| -rw-r--r-- | ui/uicontext.h | 27 | ||||
| -rw-r--r-- | ui/viewframe.h | 51 | ||||
| -rw-r--r-- | ui/viewlist.h | 31 | ||||
| -rw-r--r-- | ui/xreflist.h | 13 |
20 files changed, 692 insertions, 111 deletions
diff --git a/ui/clickablelabel.h b/ui/clickablelabel.h index 606ec369..0b373d6b 100644 --- a/ui/clickablelabel.h +++ b/ui/clickablelabel.h @@ -29,6 +29,7 @@ Q_SIGNALS: void clicked(); protected: + void mousePressEvent(QMouseEvent*) override {} void mouseReleaseEvent(QMouseEvent* event) override { if (event->button() == Qt::LeftButton) Q_EMIT clicked(); } }; @@ -50,6 +51,8 @@ public: void setActive(bool state); bool active() const { return m_active; } + void setImage(const QImage& icon); + Q_SIGNALS: void clicked(); void toggle(bool newState); @@ -62,7 +65,8 @@ protected: void enterEvent(QEnterEvent* event) override; void leaveEvent(QEvent* event) override; void paintEvent(QPaintEvent* event) override; - void mouseReleaseEvent(QMouseEvent* event) override { if (event->button() == Qt::LeftButton) Q_EMIT clicked(); } + void mousePressEvent(QMouseEvent*) override {} + void mouseReleaseEvent(QMouseEvent* event) override; }; diff --git a/ui/datatypelist.h b/ui/datatypelist.h new file mode 100644 index 00000000..be0fc5e9 --- /dev/null +++ b/ui/datatypelist.h @@ -0,0 +1,26 @@ +#pragma once + +#include <QtWidgets/QLabel> +#include <string> +#include "viewframe.h" +#include "menus.h" + +class BINARYNINJAUIAPI DataTypeList: public MenuHelper +{ + Q_OBJECT + + FileContext* m_context = nullptr; + QString m_currentType; + std::string m_currentDataType; + +public: + DataTypeList(QWidget* parent); + + void setCurrentViewType(ViewFrame* view, const QString& type); + +protected: + virtual void showMenu(); + +Q_SIGNALS: + void viewChanged(QString type); +}; diff --git a/ui/disassemblyview.h b/ui/disassemblyview.h index 4f200c54..035eec37 100644 --- a/ui/disassemblyview.h +++ b/ui/disassemblyview.h @@ -14,6 +14,7 @@ #include "menus.h" #include "statusbarwidget.h" #include "flowgraphwidget.h" +#include "ilchooser.h" #define FUNCTION_UPDATE_CHECK_INTERVAL 100 @@ -45,12 +46,14 @@ public: virtual bool navigate(uint64_t pos) override; virtual bool navigateToFunction(FunctionRef func, uint64_t pos) override; - virtual bool navigateToViewLocation(const ViewLocation& viewLocation) override; + virtual bool navigateToViewLocation(const ViewLocation& viewLocation, bool center = false) override; virtual BinaryNinja::Ref<HistoryEntry> getHistoryEntry() override; virtual void navigateToHistoryEntry(BinaryNinja::Ref<HistoryEntry> entry) override; virtual StatusBarWidget* getStatusBarWidget() override; + virtual ViewPaneHeaderSubtypeWidget* getHeaderSubtypeWidget() override; + virtual QWidget* getHeaderOptionsWidget() override; virtual BNFunctionGraphType getILViewType() override { return m_ilViewType; }; virtual void setILViewType(BNFunctionGraphType ilViewType) override; @@ -80,6 +83,19 @@ private: DisassemblyView* m_view; }; + class DisassemblyViewOptionsIconWidget: public QWidget + { + public: + DisassemblyViewOptionsIconWidget(DisassemblyView* parent); + + private: + DisassemblyView* m_view; + ContextMenuManager* m_contextMenuManager; + Menu m_menu; + + void showMenu(); + }; + class DisassemblyViewStatusBarWidget: public StatusBarWidget { public: @@ -88,10 +104,12 @@ private: private: DisassemblyView* m_view; + ILChooserWidget* m_chooser; DisassemblyViewOptionsWidget* m_options; }; void bindActions(); + static void addOptionsMenuActions(Menu& menu); BNFunctionGraphType m_ilViewType; std::set<BNDisassemblyOption> m_options; diff --git a/ui/featuremap.h b/ui/featuremap.h index ec597038..68fcab0a 100644 --- a/ui/featuremap.h +++ b/ui/featuremap.h @@ -25,7 +25,7 @@ class ContextMenuManager; class Menu; class View; -class ViewFrame; +class SplitPaneWidget; class BINARYNINJAUIAPI FeatureMap: public QWidget, public BinaryNinja::BinaryDataNotification { @@ -35,7 +35,7 @@ class BINARYNINJAUIAPI FeatureMap: public QWidget, public BinaryNinja::BinaryDat QImage* m_staticImage = nullptr; std::vector<std::pair<uint64_t, uint64_t>> m_regions; - ViewFrame* m_frame = nullptr; + SplitPaneWidget* m_owner = nullptr; BinaryViewRef m_data; bool m_updatesPending = false; @@ -75,7 +75,7 @@ class BINARYNINJAUIAPI FeatureMap: public QWidget, public BinaryNinja::BinaryDat void updateCoordinates(); public: - FeatureMap(ViewFrame* frame, BinaryViewRef data, bool vertical = true); + FeatureMap(SplitPaneWidget* owner, BinaryViewRef data, bool vertical = true); virtual ~FeatureMap(); View* getBinaryDataNavigableView(bool preferGraphView = false); diff --git a/ui/filecontext.h b/ui/filecontext.h index b58413b6..54861591 100644 --- a/ui/filecontext.h +++ b/ui/filecontext.h @@ -7,8 +7,10 @@ #include "binaryninjaapi.h" #include "uicontext.h" +class View; class ViewFrame; class ViewType; +class SyncGroup; // This base class is required for building the Python bindings. The other base classes of FileContext are // ignored (as they have no functions that should be exported to Python), but this would leave the binding @@ -31,6 +33,10 @@ class BINARYNINJAUIAPI FileContext: public FileContextBase, public BinaryNinja:: ViewFrame* m_currentViewFrame; std::set<QObject*> m_refs; + std::vector<SyncGroup*> m_syncGroups; + std::map<ViewFrame*, std::pair<View*, ViewLocation>> m_syncLastLocation; + bool m_suspendSync = false; + static std::set<FileContext*> m_openFiles; void createBinaryViews(); @@ -49,6 +55,8 @@ public: QString getFilename() const { return m_filename; } void setFilename(QString newName) {m_filename = newName;} ViewFrame* getCurrentViewFrame() const { return m_currentViewFrame; } + QString getTabName(QWidget* widget); + QString getShortFileName(QWidget* widget); bool isValidSaveFilename() const { return m_isValidSaveFilename; } void markAsSaved(const QString& filename); @@ -74,6 +82,18 @@ public: void updateAnalysis(); + SyncGroup* newSyncGroup(); + SyncGroup* syncGroupById(int id); + void deleteSyncGroup(SyncGroup* syncGroup); + SyncGroup* syncGroupForFrame(ViewFrame* frame); + void removeFrame(ViewFrame* frame); + const std::vector<SyncGroup*>& allSyncGroups() const { return m_syncGroups; } + + void forceLocationSyncForFrame(ViewFrame* frame); + bool syncLocation(ViewFrame* frame, View* view, const ViewLocation& location); + void suspendSync() { m_suspendSync = true; } + void resumeSync() { m_suspendSync = false; } + static FileContext* newFile(); static FileContext* openFilename(const QString& path); static const std::set<FileContext*>& getOpenFileContexts(); diff --git a/ui/flowgraphwidget.h b/ui/flowgraphwidget.h index 367e0174..2f294320 100644 --- a/ui/flowgraphwidget.h +++ b/ui/flowgraphwidget.h @@ -94,7 +94,6 @@ class BINARYNINJAUIAPI FlowGraphWidget: public QAbstractScrollArea, public View, int m_renderXOfs, m_renderYOfs, m_renderWidth, m_renderHeight; float m_scale; QRect m_renderRect; - QRect m_miniRenderRect; bool m_scrollMode; int m_scrollBaseX, m_scrollBaseY; @@ -216,14 +215,14 @@ public: virtual void setSelectionOffsets(BNAddressRange range) override; virtual bool navigate(uint64_t pos) override; virtual bool navigateToFunction(FunctionRef func, uint64_t pos) override; - virtual bool navigateToViewLocation(const ViewLocation& viewLocation) override; + virtual bool navigateToViewLocation(const ViewLocation& viewLocation, bool center = false) override; bool navigateWithHistoryEntry(uint64_t addr, BinaryNinja::Ref<FlowGraphHistoryEntry> entry); bool navigateWithHistoryEntry(FunctionRef func, uint64_t addr, BinaryNinja::Ref<FlowGraphHistoryEntry> entry); void setNavigationTarget(View* target) { m_navigationTarget = target; } - virtual void clearRelatedHighlights(); - virtual void setRelatedIndexHighlights(const std::set<size_t>& related); - virtual void setRelatedInstructionHighlights(const std::set<uint64_t>& related); + virtual void clearRelatedHighlights() override; + virtual void setRelatedIndexHighlights(FunctionRef func, const std::set<size_t>& related) override; + virtual void setRelatedInstructionHighlights(FunctionRef func, const std::set<uint64_t>& related) override; virtual void zoom(bool direction); virtual void zoomActual(); @@ -254,22 +253,21 @@ public: virtual HighLevelILFunctionRef getCurrentHighLevelILFunction() override; virtual size_t getCurrentILInstructionIndex() override; - void scrollToCursor(); + void scrollToCursor(bool center = false); bool isUpdating(); QFont getFont() override { return m_render.getFont(); } virtual HighlightTokenState getHighlightTokenState() override { return m_highlight; } - QRect getMiniRenderRect() const { return m_miniRenderRect; } - void paintMiniGraphAndViewport(QWidget* owner); - bool paintMiniGraph(QWidget* owner, QPainter& p); + void paintMiniGraphAndViewport(QWidget* owner, QRect& miniRenderRect); + bool paintMiniGraph(QWidget* owner, QPainter& p, QRect& miniRenderRect); void paintNode(QPainter& p, FlowGraphNodeRef& node, int minY, int maxY); void paintHighlight(QPainter& p, const std::vector<BinaryNinja::DisassemblyTextLine>& lines, int nodeX, int nodeWidth, int x, int y, size_t line, int tagIndent); void paintEdge(QPainter& p, const FlowGraphNodeRef& node, const BinaryNinja::FlowGraphEdge& edge); - void showAddress(uint64_t addr, bool select = false); - void showIndex(size_t index); + void showAddress(uint64_t addr, bool select = false, bool center = false); + void showIndex(size_t index, bool center = false); void showTopNode(); void showNode(FlowGraphNodeRef node); void showLineInNode(FlowGraphNodeRef node, size_t lineIndex); diff --git a/ui/globalarea.h b/ui/globalarea.h index 94b0b715..2dffe3b0 100644 --- a/ui/globalarea.h +++ b/ui/globalarea.h @@ -44,7 +44,7 @@ public: virtual DockableTabStyle* duplicate() override; }; -class BINARYNINJAUIAPI GlobalAreaHideButton: public QWidget +class BINARYNINJAUIAPI CloseButton: public QWidget { Q_OBJECT @@ -53,7 +53,7 @@ class BINARYNINJAUIAPI GlobalAreaHideButton: public QWidget QTimer* m_timer; public: - GlobalAreaHideButton(); + CloseButton(); virtual QSize sizeHint() const override; protected: diff --git a/ui/hexeditor.h b/ui/hexeditor.h index 08baf21d..0374f51d 100644 --- a/ui/hexeditor.h +++ b/ui/hexeditor.h @@ -41,6 +41,7 @@ public: virtual void updateFonts() override; virtual StatusBarWidget* getStatusBarWidget() override; + virtual QWidget* getHeaderOptionsWidget() override; virtual void followPointer(); @@ -67,6 +68,19 @@ private: HexEditor* m_editor; }; + class HexEditorOptionsIconWidget: public QWidget + { + public: + HexEditorOptionsIconWidget(HexEditor* parent); + + private: + HexEditor* m_view; + ContextMenuManager* m_contextMenuManager; + Menu m_menu; + + void showMenu(); + }; + class HexEditorStatusBarWidget: public StatusBarWidget { public: @@ -108,7 +122,9 @@ private: void setCursorPos(uint64_t pos); void repositionCaret(); void updateCaret(); + void bindActions(); + static void addOptionsMenuActions(Menu& menu); std::pair<uint64_t, uint64_t> getSelectionRange(); bool isSelectionActive(); diff --git a/ui/ilchooser.h b/ui/ilchooser.h new file mode 100644 index 00000000..acf1bd22 --- /dev/null +++ b/ui/ilchooser.h @@ -0,0 +1,34 @@ +#pragma once + +#include "pane.h" +#include "menus.h" + +class BINARYNINJAUIAPI ILChooserWidget: public MenuHelper +{ + Q_OBJECT + + UIActionHandler* m_handler; + bool m_longDescription; + +public: + ILChooserWidget(QWidget* parent, UIActionHandler* handler, bool longDescription); + void updateStatus(BNFunctionGraphType current); + + static QString shortNameForILType(BNFunctionGraphType type); + static QString longNameForILType(BNFunctionGraphType type); + +protected: + virtual void showMenu() override; +}; + +class BINARYNINJAUIAPI ViewPaneHeaderILChooserWidget: public ViewPaneHeaderSubtypeWidget +{ + Q_OBJECT + + View* m_view; + ILChooserWidget* m_widget; + +public: + ViewPaneHeaderILChooserWidget(View* view, UIActionHandler* handler); + virtual void updateStatus(); +}; diff --git a/ui/linearview.h b/ui/linearview.h index bca85e1b..6a319443 100644 --- a/ui/linearview.h +++ b/ui/linearview.h @@ -10,6 +10,7 @@ #include "statusbarwidget.h" #include "uicontext.h" #include "instructionedit.h" +#include "ilchooser.h" #include <assembledialog.h> #define LINEAR_VIEW_UPDATE_CHECK_INTERVAL 200 @@ -107,6 +108,19 @@ class BINARYNINJAUIAPI LinearView: public QAbstractScrollArea, public View, publ LinearView* m_view; }; + class LinearViewOptionsIconWidget: public QWidget + { + public: + LinearViewOptionsIconWidget(LinearView* parent); + + private: + LinearView* m_view; + ContextMenuManager* m_contextMenuManager; + Menu m_menu; + + void showMenu(); + }; + class LinearViewStatusBarWidget: public StatusBarWidget { public: @@ -116,6 +130,7 @@ class BINARYNINJAUIAPI LinearView: public QAbstractScrollArea, public View, publ private: LinearView* m_view; LinearViewOptionsWidget* m_options; + ILChooserWidget* m_chooser; }; BinaryViewRef m_data; @@ -138,6 +153,9 @@ class BINARYNINJAUIAPI LinearView: public QAbstractScrollArea, public View, publ uint64_t m_navByRefTarget; bool m_navByRef = false; bool m_doubleClickLatch = false; + FunctionRef m_relatedHighlightFunction; + std::set<size_t> m_relatedIndexHighlights; + std::set<uint64_t> m_relatedInstructionHighlights; SettingsRef m_settings; DisassemblySettingsRef m_options; @@ -177,6 +195,8 @@ class BINARYNINJAUIAPI LinearView: public QAbstractScrollArea, public View, publ void scrollLines(int count); void bindActions(); + static void addOptionsMenuActions(Menu& menu); + void getHexDumpLineBytes(const BinaryNinja::LinearDisassemblyLine& line, size_t& skippedBytes, size_t& totalBytes, size_t& totalCols); @@ -330,7 +350,7 @@ public: virtual size_t getCurrentILInstructionIndex() override; virtual bool navigate(uint64_t offset) override; virtual bool navigateToFunction(FunctionRef func, uint64_t offset) override; - virtual bool navigateToViewLocation(const ViewLocation& viewLocation) override; + virtual bool navigateToViewLocation(const ViewLocation& viewLocation, bool center = false) override; virtual std::string getNavigationMode() override; virtual void setNavigationMode(std::string mode) override; @@ -356,6 +376,8 @@ public: virtual void updateFonts() override; virtual StatusBarWidget* getStatusBarWidget() override; + virtual ViewPaneHeaderSubtypeWidget* getHeaderSubtypeWidget() override; + virtual QWidget* getHeaderOptionsWidget() override; virtual void followPointer(); @@ -379,6 +401,10 @@ public: virtual bool goToReference(FunctionRef func, uint64_t source, uint64_t target) override; QFont getFont() override { return m_render.getFont(); } + virtual void clearRelatedHighlights() override; + virtual void setRelatedIndexHighlights(FunctionRef func, const std::set<size_t>& related) override; + virtual void setRelatedInstructionHighlights(FunctionRef func, const std::set<uint64_t>& related) override; + static void registerActions(); protected: diff --git a/ui/minigraph.h b/ui/minigraph.h index 90a0c318..69b59768 100644 --- a/ui/minigraph.h +++ b/ui/minigraph.h @@ -13,19 +13,31 @@ class FlowGraphWidget; class Menu; class ViewFrame; -class BINARYNINJAUIAPI MiniGraph: public SidebarWidget +class BINARYNINJAUIAPI MiniGraph: public SidebarWidget, public UIContextNotification { Q_OBJECT - ViewFrame* m_frame; + ViewFrame* m_frame = nullptr; FlowGraphWidget* m_flowGraphWidget = nullptr; + QWidget* m_header = nullptr; + bool m_popout; + QRect m_miniRenderRect; public: - MiniGraph(ViewFrame* frame); + MiniGraph(bool popout = false); ~MiniGraph(); + // Called when used in sidebar virtual void notifyViewChanged(ViewFrame* frame) override; + // Called when popped out of sidebar + virtual void OnViewChange(UIContext* context, ViewFrame* frame, const QString& type) override; + + virtual QWidget* headerWidget() override { return m_header; } + virtual QSize sizeHint() const override { return QSize(200, 200); } + + void setSource(ViewFrame* frame, FlowGraphWidget* graphView); + protected: virtual void contextMenuEvent(QContextMenuEvent* event) override; virtual void mouseMoveEvent(QMouseEvent* event) override; @@ -35,6 +47,8 @@ protected: public Q_SLOTS: void notifyUpdate(); + void graphDestroyed(); + void newPane(); }; diff --git a/ui/pane.h b/ui/pane.h new file mode 100644 index 00000000..dfda17a4 --- /dev/null +++ b/ui/pane.h @@ -0,0 +1,356 @@ +#pragma once + +#include <QtWidgets/QWidget> +#include <QtWidgets/QSplitter> +#include <QtWidgets/QStackedWidget> +#include <QtWidgets/QVBoxLayout> +#include <QtWidgets/QRubberBand> +#include "uicontext.h" +#include "clickablelabel.h" + +class ViewFrame; +class FeatureMap; +class PaneHeader; +class CloseButton; +class TabDragIndicator; + +class BINARYNINJAUIAPI Pane: public QWidget +{ + Q_OBJECT + + QWidget* m_widget; + QWidget* m_headerContainer = nullptr; + PaneHeader* m_header = nullptr; + CloseButton* m_closeButton = nullptr; + bool m_active = false; + +public: + Pane(QWidget* widget); + + QWidget* widget() const { return m_widget; } + virtual bool canSplitPane() const { return false; } + virtual Pane* createSplitPane() { return nullptr; } + virtual void updateStatus(); + virtual void focus(); + virtual QString title() = 0; + void closePane(); + void splitPane(Qt::Orientation orientation); + + virtual void setIsSinglePane(bool isSinglePane); + virtual void setIsActivePane(bool active); + virtual Qt::Orientation defaultSplitDirection() const { return Qt::Horizontal; } + virtual void setDefaultSplitDirection(Qt::Orientation orientation); + +protected: + void init(PaneHeader* header); + +Q_SIGNALS: + void paneCloseRequested(); + void paneSplitRequested(Pane* newPane, Qt::Edge edge); + void movePane(Pane* target, Qt::Edge edge); + void newWindowForPane(QScreen* screen, QPoint pos); + void notifyViewChanged(ViewFrame* frame); + +public Q_SLOTS: + void splitButtonClicked(Qt::Orientation orientation); + void closeButtonClicked(); + void headerClicked(); + void movePaneRequested(Pane* target, Qt::Edge edge); + void newWindowForPaneRequested(QScreen* screen, QPoint pos); +}; + +class BINARYNINJAUIAPI SplitButton: public ClickableIcon +{ + Q_OBJECT + + Qt::Orientation m_defaultOrientation; + bool m_mouseInside = false; + bool m_inverted = false; + + void setIconForOrientation(Qt::Orientation orientation); + +public: + SplitButton(); + + void setDefaultOrientation(Qt::Orientation orientation); + Qt::Orientation orientation() const; + Qt::Orientation defaultOrientation() const { return m_defaultOrientation; } + +protected: + virtual void enterEvent(QEnterEvent* event) override; + virtual void leaveEvent(QEvent* event) override; + virtual bool eventFilter(QObject* obj, QEvent* event) override; +}; + +class BINARYNINJAUIAPI PaneHeader: public QWidget +{ + Q_OBJECT + + Pane* m_owner = nullptr; + std::optional<QPoint> m_dragStart; + TabDragIndicator* m_dragIndicator = nullptr; + bool m_dragNewWindow = false; + Pane* m_dropTarget = nullptr; + Qt::Edge m_dropEdge = Qt::RightEdge; + QRubberBand* m_dropIndicator = nullptr; + +public: + PaneHeader(); + + void setOwner(Pane* pane) { m_owner = pane; } + +protected: + virtual void mousePressEvent(QMouseEvent* event) override; + virtual void mouseMoveEvent(QMouseEvent* event) override; + virtual void mouseReleaseEvent(QMouseEvent* event) override; + +Q_SIGNALS: + void paneCloseRequested(); + void paneSplitRequested(Qt::Orientation orientation); + void movePane(Pane* target, Qt::Edge edge); + void newWindowForPane(QScreen* screen, QPoint pos); + void headerClicked(); +}; + +class ViewFrame; +class ViewPaneHeader; + +class BINARYNINJAUIAPI ViewPane: public Pane +{ + Q_OBJECT + + ViewFrame* m_frame; + UIActionHandler m_actionHandler; + ViewPaneHeader* m_header; + +public: + ViewPane(ViewFrame* frame); + + ViewFrame* viewFrame() const { return m_frame; } + virtual bool canSplitPane() const override { return true; } + virtual Pane* createSplitPane() override; + virtual void updateStatus() override; + virtual Qt::Orientation defaultSplitDirection() const override; + virtual void setDefaultSplitDirection(Qt::Orientation orientation) override; + virtual void focus() override; + virtual QString title() override; + +private Q_SLOTS: + void viewChanged(ViewFrame* frame); + void viewChangeRequested(QString type); +}; + +class DataTypeList; +class ViewList; +class SyncGroupWidget; + +class BINARYNINJAUIAPI ViewPaneHeaderSubtypeWidget: public QWidget +{ + Q_OBJECT + +public: + ViewPaneHeaderSubtypeWidget() {} + virtual void updateStatus() = 0; +}; + +class BINARYNINJAUIAPI ViewPaneHeader: public PaneHeader +{ + Q_OBJECT + + ViewPane* m_owner; + DataTypeList* m_dataTypeList; + ViewList* m_viewList; + SyncGroupWidget* m_syncGroup; + + View* m_subtypeView = nullptr; + ViewPaneHeaderSubtypeWidget* m_subtypeWidget = nullptr; + QWidget* m_optionsWidget = nullptr; + QStackedWidget* m_subtypeWidgetContainer; + QStackedWidget* m_optionsWidgetContainer; + + SplitButton* m_splitButton; + +public: + ViewPaneHeader(ViewPane* owner, UIActionHandler* handler); + + void updateStatus(); + Qt::Orientation defaultSplitDirection() const; + void setDefaultSplitDirection(Qt::Orientation orientation); + +Q_SIGNALS: + void viewChanged(QString type); + +private Q_SLOTS: + void splitButtonClicked(); + void viewChangeRequested(QString type); + void updateViewType(ViewFrame* frame); +}; + +class BINARYNINJAUIAPI WidgetPane: public Pane +{ + Q_OBJECT + + QString m_title; + +public: + WidgetPane(QWidget* widget, QString title); + virtual QString title() override { return m_title; } + virtual void updateStatus() override; + +Q_SIGNALS: + void updateWidgetStatus(); +}; + +class BINARYNINJAUIAPI WidgetPaneHeader: public PaneHeader +{ + Q_OBJECT + + QString m_title; + +public: + WidgetPaneHeader(const QString& title); + +protected: + virtual void paintEvent(QPaintEvent* event) override; +}; + +class SplitPaneWidget; + +class BINARYNINJAUIAPI SplitPaneContainer: public QWidget +{ + Q_OBJECT + + Pane* m_pane = nullptr; + QSplitter* m_splitter = nullptr; + SplitPaneContainer* m_parent = nullptr; + std::vector<SplitPaneContainer*> m_children; + Pane* m_currentChild = nullptr; + ViewPane* m_currentViewPane = nullptr; + QVBoxLayout* m_layout; + FileContext* m_fileContext = nullptr; + + SplitPaneContainer(const std::vector<SplitPaneContainer*>& children, Qt::Orientation orientation); + + void removeChild(SplitPaneContainer* child); + void promoteChild(SplitPaneContainer* child); + void updateDefaultSplitDirectionForColumnCount(uint64_t count); + void removePaneForRelocation(); + void emitNewWindowForPane(SplitPaneWidget* paneWidget, QRect rect); + void openForColumnCount(Pane* pane, Qt::Orientation primaryDirection, uint64_t count); + void deactivateIfCurrent(Pane* pane); + void notifyCurrentChanged(Pane* pane); + +public: + SplitPaneContainer(Pane* initial); + Pane* currentPane() const { return m_currentChild; } + ViewPane* currentViewPane() const { return m_currentViewPane; } + void notifyFocused(); + void updateStatus(); + + void enumeratePanes(const std::function<void(Pane*)>& func); + void enumerateViewPanes(const std::function<void(ViewPane*)>& func); + + bool isSinglePane(); + bool canSplitCurrentPane(); + void closeCurrentPane(); + void splitCurrentPane(Qt::Orientation orientation); + Qt::Orientation defaultSplitDirection() const; + void nextPane(); + void prevPane(); + void focusPaneForEdge(Qt::Edge edge); + + SplitPaneContainer* root(); + static SplitPaneContainer* containerForWidget(QWidget* widget); + + FileContext* fileContext() const { return m_fileContext; } + void setFileContext(FileContext* fileContext) { m_fileContext = fileContext; } + + void open(Pane* pane, Qt::Orientation primaryDirection = Qt::Vertical); + +Q_SIGNALS: + void paneClosed(Pane* pane); + void currentChanged(Pane* pane); + void layoutChanged(); + void notifyViewChanged(ViewFrame* frame); + void lastPaneClosed(); + void newWindowForPane(SplitPaneWidget* paneWidget, QRect rect); + +private Q_SLOTS: + void paneCloseRequested(); + void paneSplitRequested(Pane* newPane, Qt::Edge edge); + void movePane(Pane* target, Qt::Edge edge); + void newWindowForPaneRequested(QScreen* screen, QPoint pos); + void paneViewChanged(ViewFrame* frame); + void childPaneClosed(Pane* pane); + void childLayoutChanged(); + void childViewChanged(ViewFrame* frame); +}; + +class BINARYNINJAUIAPI SplitPaneWidget: public QWidget +{ + Q_OBJECT + + SplitPaneContainer* m_container; + + QStackedWidget* m_featureMapContainer; + std::map<BinaryViewRef, FeatureMap*> m_featureMaps; + QSplitter* m_featureMapSplitter; + bool m_rightSideFeatureMap = true; + + UIActionHandler m_actionHandler; + + void bindActions(); + +public: + SplitPaneWidget(Pane* initial, FileContext* fileContext); + Pane* currentPane() const; + ViewPane* currentViewPane() const; + ViewFrame* currentViewFrame() const; + SplitPaneContainer* container() const { return m_container; } + FileContext* fileContext() const { return m_container->fileContext(); } + + void enumeratePanes(const std::function<void(Pane*)>& func); + void enumerateViewPanes(const std::function<void(ViewPane*)>& func); + + void createFeatureMap(); + void recreateFeatureMaps(); + void refreshFeatureMap(); + void updateFeatureMapLocation(const ViewLocation& location); + BinaryViewRef getCurrentBinaryView(); + + void updateStatus(); + + bool isSinglePane(); + bool canSplitCurrentPane(); + void closeCurrentPane(); + void splitCurrentPane(Qt::Orientation orientation); + Qt::Orientation defaultSplitDirection() const; + void nextPane(); + void prevPane(); + void focusPaneForEdge(Qt::Edge edge); + + QString getTabName(); + + void open(Pane* pane, Qt::Orientation primaryDirection = Qt::Vertical); + + bool closeRequest(); + void closing(); + + static void registerActions(); + +Q_SIGNALS: + void paneClosed(Pane* pane); + void currentChanged(Pane* pane); + void layoutChanged(); + void notifyViewChanged(ViewFrame* frame); + void newWindowForPane(SplitPaneWidget* paneWidget, QRect rect); + +private Q_SLOTS: + void containerPaneClosed(Pane* pane); + void containerCurrentChanged(Pane* pane); + void containerLayoutChanged(); + void containerNotifyViewChanged(ViewFrame* frame); + void containerLastPaneClosed(); + void containerNewWindowForPane(SplitPaneWidget* paneWidget, QRect rect); + void featureMapSplitterMoved(int pos, int idx); +}; diff --git a/ui/reflectionview.h b/ui/reflectionview.h deleted file mode 100644 index 1be8cc50..00000000 --- a/ui/reflectionview.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include <QtGui/QMouseEvent> -#include <QtGui/QPaintEvent> -#include <QtWidgets/QWidget> - -#include "binaryninjaapi.h" -#include "dockhandler.h" -#include "uitypes.h" - -class ContextMenuManager; -class DisassemblyContainer; -class FlowGraphWidget; -class Menu; -class ViewFrame; - -class BINARYNINJAUIAPI ReflectionView: public QWidget, public DockContextHandler -{ - Q_OBJECT - Q_INTERFACES(DockContextHandler) - - ViewFrame* m_frame; - BinaryViewRef m_data; - DisassemblyContainer* m_disassemblyContainer; - std::map<BNFunctionGraphType, BNFunctionGraphType> m_ilMap; - bool m_ilSync; - bool m_locationSync; - - BNFunctionGraphType m_lastSrcILViewType = NormalFunctionGraph; - BNFunctionGraphType m_lastTgtILViewType = NormalFunctionGraph; - bool m_ilSyncOverride = false; - -public: - ReflectionView(ViewFrame* frame, BinaryViewRef data); - ~ReflectionView(); - - FlowGraphWidget* getFlowGraphWidget(); - - void toggleILSync(); - void toggleLocationSync(); - - virtual void notifyFontChanged() override; - virtual void notifyViewLocationChanged(View* view, const ViewLocation& viewLocation) override; - virtual void notifyVisibilityChanged(bool visible) override; - virtual bool shouldBeVisible(ViewFrame* frame) override; - -protected: - virtual void contextMenuEvent(QContextMenuEvent* event) override; -}; diff --git a/ui/searchresult.h b/ui/searchresult.h index 5905ae0d..fe2d075e 100644 --- a/ui/searchresult.h +++ b/ui/searchresult.h @@ -13,7 +13,6 @@ #include <QtWidgets/QToolButton> #include "binaryninjaapi.h" #include "dockhandler.h" -#include "viewframe.h" #include "filter.h" #include "expandablegroup.h" @@ -72,7 +71,6 @@ class BINARYNINJAUIAPI SearchResultModel: public QAbstractTableModel protected: QWidget* m_owner; BinaryViewRef m_data; - ViewFrame* m_view; BinaryNinja::FindParameters m_params; std::vector<SearchResultItem> m_refs; mutable size_t m_columnWidths[4]; @@ -93,7 +91,7 @@ public: EndOfColumn = 4 }; - SearchResultModel(QWidget* parent, BinaryViewRef data, ViewFrame* view); + SearchResultModel(QWidget* parent, BinaryViewRef data); virtual ~SearchResultModel(); virtual QModelIndex index(int row, int col, const QModelIndex& parent = QModelIndex()) const override; @@ -150,7 +148,6 @@ class BINARYNINJAUIAPI SearchResultTable: public QTableView { Q_OBJECT - ViewFrame* m_view; SearchResultModel* m_table; SearchResultFilterProxyModel* m_model; SearchResultItemDelegate* m_itemDelegate; @@ -164,7 +161,7 @@ class BINARYNINJAUIAPI SearchResultTable: public QTableView bool m_cacheThreadShouldExit; public: - SearchResultTable(SearchResultWidget* parent, ViewFrame* view, BinaryViewRef data); + SearchResultTable(SearchResultWidget* parent, BinaryViewRef data); virtual ~SearchResultTable(); void addSearchResult(const SearchResultItem& addr); @@ -203,12 +200,14 @@ Q_SIGNALS: }; class SearchProgressBar; -class BINARYNINJAUIAPI SearchResultWidget: public QWidget, public DockContextHandler +class BINARYNINJAUIAPI SearchResultWidget: public QWidget { Q_OBJECT - Q_INTERFACES(DockContextHandler) - ViewFrame* m_view; + UIActionHandler m_actionHandler; + ContextMenuManager* m_contextMenuManager = nullptr; + Menu* m_menu = nullptr; + BinaryViewRef m_data; SearchResultTable* m_table; QLabel* m_label; @@ -221,10 +220,10 @@ class BINARYNINJAUIAPI SearchResultWidget: public QWidget, public DockContextHan virtual void contextMenuEvent(QContextMenuEvent* event) override; public: - SearchResultWidget(ViewFrame* frame, BinaryViewRef data); + SearchResultWidget(BinaryViewRef data); ~SearchResultWidget(); - virtual void notifyFontChanged() override; + void notifyFontChanged(); void startNewFind(const BinaryNinja::FindParameters& params); virtual QString getHeaderText(); diff --git a/ui/sidebar.h b/ui/sidebar.h index 7d8d1b02..52ea38de 100644 --- a/ui/sidebar.h +++ b/ui/sidebar.h @@ -11,6 +11,7 @@ class SidebarEntry; class MainWindow; class ContextMenuManager; +class SplitPaneWidget; struct SidebarIcon { @@ -125,6 +126,7 @@ class BINARYNINJAUIAPI SidebarWidgetContainer: public QWidget QSplitter* m_contentSplitter; QStackedWidget* m_contentStackedWidget; QStackedWidget* m_referenceStackedWidget; + SplitPaneWidget* m_panes; ViewFrame* m_frame; QString m_dataType; BinaryViewRef m_data; @@ -133,9 +135,9 @@ class BINARYNINJAUIAPI SidebarWidgetContainer: public QWidget SidebarWidgetType* m_referenceActive = nullptr; SidebarWidgetType* m_pendingReferenceType = nullptr; std::map<ViewFrame*, std::map<QString, std::map<SidebarWidgetType*, SidebarWidgetAndHeader*>>> m_widgets; - std::map<ViewFrame*, std::map<QString, std::pair<SidebarWidgetType*, SidebarWidgetType*>>> m_priorWidgets; - std::map<ViewFrame*, std::map<QString, QList<int>>> m_priorContentSplitterSizes; - std::map<ViewFrame*, std::map<QString, QList<int>>> m_priorParentSplitterSizes; + std::map<SplitPaneWidget*, std::map<QString, std::pair<SidebarWidgetType*, SidebarWidgetType*>>> m_priorWidgets; + std::map<SplitPaneWidget*, std::map<QString, QList<int>>> m_priorContentSplitterSizes; + std::map<SplitPaneWidget*, std::map<QString, QList<int>>> m_priorParentSplitterSizes; std::optional<QList<int>> m_pendingContentSplitterSizes; std::optional<QList<int>> m_pendingParentSplitterSizes; std::map<ViewFrame*, std::map<QString, std::pair<View*, ViewLocation>>> m_currentViewLocation; @@ -150,8 +152,9 @@ public: SidebarWidgetContainer(); void setSplitter(QSplitter* splitter); - void setActiveContext(ViewFrame* frame, const QString& dataType, BinaryViewRef data); + void setActiveContext(SplitPaneWidget* panes, ViewFrame* frame, const QString& dataType, BinaryViewRef data); void destroyContext(ViewFrame* frame); + void destroyContext(SplitPaneWidget* panes); bool isContentActive() const { return m_contentActive != nullptr; } bool isActive(SidebarWidgetType* type) const { return m_contentActive == type || m_referenceActive == type; } @@ -178,7 +181,8 @@ public: void toggleSidebar(); - void moveContextToContainer(ViewFrame* frame, SidebarWidgetContainer* target); + void moveContextToContainer(SplitPaneWidget* panes, const std::vector<ViewFrame*>& frames, + SidebarWidgetContainer* target); Q_SIGNALS: void showContents(); @@ -208,13 +212,15 @@ public: SidebarWidgetContainer* container() const { return m_currentContainer; } void setContainer(SidebarWidgetContainer* container); - void setActiveContext(ViewFrame* frame, const QString& dataType, BinaryViewRef data); + void setActiveContext(SplitPaneWidget* panes, ViewFrame* frame, const QString& dataType, BinaryViewRef data); SidebarWidget* widget(SidebarWidgetType* type); SidebarWidget* widget(const QString& name); void activate(SidebarWidgetType* type); void activate(const QString& name); + void deactivate(SidebarWidgetType* type); + void deactivate(const QString& name); void updateTheme(); void updateFonts(); diff --git a/ui/syncgroup.h b/ui/syncgroup.h new file mode 100644 index 00000000..5a9828f9 --- /dev/null +++ b/ui/syncgroup.h @@ -0,0 +1,39 @@ +#pragma once + +#include "viewframe.h" +#include "clickablelabel.h" + +class BINARYNINJAUIAPI SyncGroup +{ + std::set<ViewFrame*> m_members; + int m_id; + +public: + SyncGroup(int id); + + void addMember(ViewFrame* frame); + void removeMember(ViewFrame* frame); + bool isEmpty() const; + int identifier() const { return m_id; } + bool contains(ViewFrame* frame) const; + const std::set<ViewFrame*>& members() const { return m_members; } + + void syncLocation(ViewFrame* frame, View* view, const ViewLocation& location); + + static void syncToTarget(View* srcView, ViewFrame* targetFrame, const ViewLocation& location); +}; + +class BINARYNINJAUIAPI SyncGroupWidget: public ClickableIcon +{ + Q_OBJECT + + ViewFrame* m_frame; + +public: + SyncGroupWidget(ViewFrame* frame); + + void updateStatus(); + +private Q_SLOTS: + void handleClick(); +}; diff --git a/ui/uicontext.h b/ui/uicontext.h index de58a74b..4c2a5853 100644 --- a/ui/uicontext.h +++ b/ui/uicontext.h @@ -21,6 +21,7 @@ class ViewLocation; class Sidebar; class SidebarWidgetContainer; class GlobalArea; +class Pane; struct SelectionInfoForXref; /*! @@ -214,6 +215,12 @@ public: */ virtual void createTabForWidget(const QString& name, QWidget* widget) = 0; /*! + Open a new pane in the active tab + \param pane Pane widget to open + \param primaryDirection Primary axis for content in pane (determines default split direction) + */ + virtual void openPane(Pane* pane, Qt::Orientation primaryDirection = Qt::Vertical) = 0; + /*! Get a list of all tabs as QWidgets \return All tabs */ @@ -244,8 +251,9 @@ public: /*! Close the tab with the given QWidget \param tab QWidget which is in a tab + \param closeWindowIfLast If false, displays the new tab page if the widget was the last tab */ - virtual void closeTab(QWidget* tab) = 0; + virtual void closeTab(QWidget* tab, bool closeWindowIfLast = false) = 0; /*! Get the QWidget in the currently open tab \return QWidget for current tab. Qt claims "this value is never 0 (but if you try hard enough, it can be)" @@ -259,11 +267,18 @@ public: */ virtual View* getViewForTab(QWidget* tab) = 0; /*! - Get the ViewFrame associated with the given QWidget, if it exists + Get the active ViewFrame associated with the given QWidget, if it exists \param tab QWidget which could be a ViewFrame \return ViewFrame for the QWidget (which is likely itself), or nullptr if the QWidget is not a ViewFrame */ - virtual ViewFrame* getViewFrameForTab(QWidget* tab) = 0; + virtual ViewFrame* getViewFrameForTab(QWidget* tab) const = 0; + + /*! + Get all ViewFrame instances associated with the given QWidget, if they exist + \param tab QWidget which could contain a ViewFrame + \return List of ViewFrame objects for the QWidget + */ + virtual std::vector<ViewFrame*> getAllViewFramesForTab(QWidget* tab) const = 0; virtual bool openFilename(const QString& path, bool openOptions = false); virtual ViewFrame* openFileContext(FileContext* file, const QString& forcedView = "", bool addTab = true); @@ -314,6 +329,12 @@ public: static UIContext* contextForWidget(QWidget* widget); static UIContext* activeContext(); static std::set<UIContext*> allContexts(); + + static QWidget* topLevelAt(const QPoint& pt, QWidget* ignoreWidget = nullptr); + + static QRect placeNewTopLevelWindow(QScreen* screen, const QPoint& pos, QWidget* existingWidget); + + static ViewFrame* currentViewFrameForWidget(QWidget* widget); }; Q_DECLARE_METATYPE(UIContext*) diff --git a/ui/viewframe.h b/ui/viewframe.h index 6681582f..80abb3d5 100644 --- a/ui/viewframe.h +++ b/ui/viewframe.h @@ -94,6 +94,7 @@ class FeatureMap; class StatusBarWidget; class ViewNavigationMode; class TransformParameterDialog; +class ViewPaneHeaderSubtypeWidget; // struct BinaryNinjaCore::LinearDisassemblyLine; @@ -159,7 +160,10 @@ public: virtual bool navigate(uint64_t offset) = 0; virtual bool navigateToFunction(FunctionRef func, uint64_t offset); virtual bool goToReference(FunctionRef func, uint64_t source, uint64_t target); - virtual bool navigateToViewLocation(const ViewLocation& viewLocation) { return false; } + virtual bool navigateToViewLocation(const ViewLocation& viewLocation, bool center = false); + + bool navigateOnOtherPane(uint64_t offset); + bool navigateToFunctionOnOtherPane(FunctionRef func, uint64_t offset); bool isBinaryDataNavigable() { return m_binaryDataNavigable; } void setBinaryDataNavigable(bool navigable) { m_binaryDataNavigable = navigable; } @@ -197,6 +201,8 @@ public: virtual void navigateToHistoryEntry(BinaryNinja::Ref<HistoryEntry> entry); virtual StatusBarWidget* getStatusBarWidget() { return nullptr; } + virtual ViewPaneHeaderSubtypeWidget* getHeaderSubtypeWidget() { return nullptr; } + virtual QWidget* getHeaderOptionsWidget() { return nullptr; } static View* getViewFromWidget(QWidget* widget); @@ -224,6 +230,11 @@ public: QString viewType(); void updateCrossReferenceSelection(ViewFrame* frame = nullptr); + void forceSyncFromView(ViewFrame* frame = nullptr); + + virtual void clearRelatedHighlights() {} + virtual void setRelatedIndexHighlights(FunctionRef func, const std::set<size_t>& related) { (void)func; (void)related; } + virtual void setRelatedInstructionHighlights(FunctionRef func, const std::set<uint64_t>& related) { (void)func; (void)related; } static void registerActions(); }; @@ -297,6 +308,7 @@ public: }; class SymbolsView; +class ViewPane; class BINARYNINJAUIAPI ViewFrame : public QWidget { @@ -305,6 +317,7 @@ class BINARYNINJAUIAPI ViewFrame : public QWidget private: QWidget* createView(const QString& typeName, ViewType* type, BinaryViewRef data, bool createDynamicWidgets = true); BinaryNinja::Ref<HistoryEntry> getHistoryEntry(); + ViewFrame* searchForOtherPane(const std::function<void(const std::function<void(ViewPane*)>&)>& enumerator); FileContext* m_context; bool m_fileContentsLock = true; // file contents protection from accidental modification in the UI @@ -318,10 +331,7 @@ private: std::list<BinaryNinja::Ref<HistoryEntry>> m_back, m_forward; bool m_graphViewPreferred = false; std::vector<QString> m_viewTypePriority; - QStackedWidget* m_featureMapContainer; - std::map<BinaryViewRef, FeatureMap*> m_featureMaps; - QSplitter* m_featureMapSplitter; - bool m_rightSideFeatureMap = true; + int m_preferredSyncGroup = 1; UIActionHandler m_actionHandler; @@ -371,10 +381,6 @@ public: bool isGraphViewPreferred() { return m_graphViewPreferred; } void setGraphViewPreferred(bool graphViewPreferred) { m_graphViewPreferred = graphViewPreferred; } void focus(); - void createFeatureMap(); - void recreateFeatureMaps(); - void refreshFeatureMap(); - void updateFeatureMapLocation(const ViewLocation& location); QWidget* getExtendedView(const QString& name, bool create = false); @@ -398,7 +404,7 @@ public: bool navigateToFunction(FunctionRef func, uint64_t offset, bool updateInfo = true, bool addHistoryEntry = true); bool goToReference(BinaryViewRef data, FunctionRef func, uint64_t source, uint64_t target, bool addHistoryEntry = true); bool navigateToViewLocation(BinaryViewRef data, const ViewLocation& viewLocation, - bool addHistoryEntry = true); + bool addHistoryEntry = true, bool center = false); bool navigateToHistoryEntry(BinaryNinja::Ref<HistoryEntry> entry); QString getTypeForView(QWidget* view) const; QString getDataTypeForView(const QString& type) const; @@ -436,7 +442,6 @@ public: void setCurrentFunction(FunctionRef func); void updateCrossReferences(); void updateCrossReferenceSelection(); - void showPinnedCrossReferences(); void nextCrossReference(); void prevCrossReference(); @@ -448,13 +453,6 @@ public: void nextTag(); void prevTag(); - void startNewFind(const BinaryNinja::FindParameters& params); - bool updateSearchProgress(uint64_t cur, uint64_t total); - void notifySearchCompleted(); - void addSearchResult(uint64_t addr, const BinaryNinja::DataBuffer& match); - void addSearchResult(uint64_t addr, const BinaryNinja::DataBuffer& match, - const BinaryNinja::LinearDisassemblyLine& line); - virtual UIActionContext actionContext(); void bindActions(); static void registerActions(); @@ -463,13 +461,24 @@ public: static bool lineHasInstructionToken(const BinaryNinja::DisassemblyTextLine& line); static QString getDisassemblyText(const std::vector<BinaryNinja::DisassemblyTextLine>& lines); + int preferredSyncGroup() const { return m_preferredSyncGroup; } + void setPreferredSyncGroup(int syncGroup) { m_preferredSyncGroup = syncGroup; } + void disableSync(); + void enableSync(); + void enableSync(int id); + void newSyncGroup(); + void toggleSync(); + SyncGroup* syncGroup(); + + void syncToOtherViews(); + void forceSyncFromView(); + + ViewFrame* getOtherPane(); + public Q_SLOTS: virtual void assemble(); virtual void compile(); -private Q_SLOTS: - void splitterMoved(int pos, int idx); - Q_SIGNALS: void notifyCloseFeatureMap(bool recreate); void notifyViewChanged(ViewFrame* frame); diff --git a/ui/viewlist.h b/ui/viewlist.h new file mode 100644 index 00000000..c1926106 --- /dev/null +++ b/ui/viewlist.h @@ -0,0 +1,31 @@ +#pragma once + +#include <QtWidgets/QLabel> +#include <string> +#include "viewframe.h" +#include "menus.h" +#include "action.h" + +class BINARYNINJAUIAPI ViewList: public MenuHelper +{ + Q_OBJECT + + FileContext* m_context = nullptr; + QString m_currentType; + std::string m_currentDataType; + + UIActionHandler* m_handler; + +public: + ViewList(QWidget* parent); + + void bindActions(UIActionHandler* handler); + void addMenuActions(Menu* menu, const QString& group); + void setCurrentViewType(ViewFrame* view, const QString& type); + +protected: + virtual void showMenu(); + +Q_SIGNALS: + void viewChanged(QString type); +}; diff --git a/ui/xreflist.h b/ui/xreflist.h index 403178f2..73ae48ef 100644 --- a/ui/xreflist.h +++ b/ui/xreflist.h @@ -236,6 +236,7 @@ class BINARYNINJAUIAPI CrossReferenceTreeModel : public QAbstractItemModel ViewFrame* m_view; std::vector<XrefItem> m_refs; size_t m_maxUIItems; + std::optional<BNFunctionGraphType> m_graphType; public: CrossReferenceTreeModel(QWidget* parent, BinaryViewRef data, ViewFrame* view); @@ -257,6 +258,7 @@ public: ViewFrame* getView() const { return m_view; } virtual void updateMaxUIItems(size_t value) { m_maxUIItems = value; } size_t getMaxUIItems() const { return m_maxUIItems; } + void setGraphType(BNFunctionGraphType type) { m_graphType = type; } }; @@ -269,6 +271,7 @@ class BINARYNINJAUIAPI CrossReferenceTableModel : public QAbstractTableModel ViewFrame* m_view; std::vector<XrefItem> m_refs; size_t m_maxUIItems; + std::optional<BNFunctionGraphType> m_graphType; public: enum ColumnHeaders @@ -295,6 +298,7 @@ public: ViewFrame* getView() const { return m_view; } virtual void updateMaxUIItems(size_t value) { m_maxUIItems = value; } size_t getMaxUIItems() const { return m_maxUIItems; } + void setGraphType(BNFunctionGraphType type) { m_graphType = type; } }; @@ -409,6 +413,7 @@ public: virtual int filteredCount() const override; void updateTextFilter(const QString& filterText); virtual void updateMaxUIItems(size_t count) override; + void setGraphType(BNFunctionGraphType type) { m_tree->setGraphType(type); } Q_SIGNALS: void newSelection(); @@ -443,6 +448,7 @@ public: virtual int leafCount() const override; virtual int filteredCount() const override; virtual void updateMaxUIItems(size_t count) override; + void setGraphType(BNFunctionGraphType type) { m_table->setGraphType(type); } public Q_SLOTS: void updateTextFilter(const QString& filterText); @@ -466,6 +472,7 @@ class BINARYNINJAUIAPI CrossReferenceWidget: public SidebarWidget, public UICont CrossReferenceTree* m_tree; CrossReferenceContainer* m_container; bool m_useTableView; + std::optional<BNFunctionGraphType> m_graphType; QTimer* m_hoverTimer; QPoint m_hoverPos; @@ -482,6 +489,8 @@ class BINARYNINJAUIAPI CrossReferenceWidget: public SidebarWidget, public UICont bool m_pinned; bool m_uiMaxItemsExceeded = false; + QWidget* m_header = nullptr; + virtual void contextMenuEvent(QContextMenuEvent* event) override; virtual void wheelEvent(QWheelEvent* e) override; @@ -509,14 +518,18 @@ public: bool tableView() const { return m_useTableView; } bool uiMaxItemsExceeded() const { return m_uiMaxItemsExceeded; } void setUIMaxItemsExceeded(bool value) { m_uiMaxItemsExceeded = value; } + void setGraphType(BNFunctionGraphType type); virtual void focus() override; virtual void OnNewSelectionForXref(UIContext* context, ViewFrame* frame, View* view, const SelectionInfoForXref& selection) override; + virtual QWidget* headerWidget() override { return m_header; } + private Q_SLOTS: void hoverTimerEvent(); + void newPinnedPane(); public Q_SLOTS: void referenceActivated(const QModelIndex& idx); |
