summaryrefslogtreecommitdiff
path: root/ui
diff options
context:
space:
mode:
Diffstat (limited to 'ui')
-rw-r--r--ui/clickablelabel.h6
-rw-r--r--ui/datatypelist.h26
-rw-r--r--ui/disassemblyview.h20
-rw-r--r--ui/featuremap.h6
-rw-r--r--ui/filecontext.h20
-rw-r--r--ui/flowgraphwidget.h20
-rw-r--r--ui/globalarea.h4
-rw-r--r--ui/hexeditor.h16
-rw-r--r--ui/ilchooser.h34
-rw-r--r--ui/linearview.h28
-rw-r--r--ui/minigraph.h20
-rw-r--r--ui/pane.h356
-rw-r--r--ui/reflectionview.h49
-rw-r--r--ui/searchresult.h19
-rw-r--r--ui/sidebar.h18
-rw-r--r--ui/syncgroup.h39
-rw-r--r--ui/uicontext.h27
-rw-r--r--ui/viewframe.h51
-rw-r--r--ui/viewlist.h31
-rw-r--r--ui/xreflist.h13
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);