summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Wagner <rusty.wagner@gmail.com>2025-08-06 16:41:26 -0400
committerRusty Wagner <rusty.wagner@gmail.com>2025-08-29 15:42:09 -0400
commit5c4abf48ab4b77555a79777bc37d52c842ee149a (patch)
treea9daf8875c7ed70b55bc730de5a63621801a8019
parent2303f75b080f6dd0c9a5c669a71f64ce830f5650 (diff)
Add a Pinned Cross References tab to hold pinned references
-rw-r--r--ui/sidebarwidget.h5
-rw-r--r--ui/tabwidget.h4
-rw-r--r--ui/uicontext.h6
-rw-r--r--ui/xreflist.h23
-rw-r--r--ui/xrefstate.h30
5 files changed, 63 insertions, 5 deletions
diff --git a/ui/sidebarwidget.h b/ui/sidebarwidget.h
index 2ec0bb57..9567d344 100644
--- a/ui/sidebarwidget.h
+++ b/ui/sidebarwidget.h
@@ -53,6 +53,7 @@ public:
SidebarWidget(const QString& title);
~SidebarWidget();
const QString& title() const { return m_title; }
+ void setTitle(const QString& title) { m_title = title; }
void enableRefreshTimer(int interval);
void setRefreshQuiesce(bool enable);
@@ -103,6 +104,7 @@ public:
~SidebarWidgetAndHeader() override;
SidebarWidget* widget() const { return m_widget; }
+ SidebarWidgetType* type() const { return m_type; }
QWidget* header() const;
void addWidget(SidebarWidget* widget, bool canClose = false);
@@ -110,6 +112,7 @@ public:
SidebarWidget* widgetWithTitle(const QString& title) const;
bool hasWidgetWithTitle(const QString& title) const;
bool activateWidgetWithTitle(const QString& title);
+ bool activateWidget(SidebarWidget* widget);
bool hasContent() const;
void updateTheme();
@@ -284,6 +287,8 @@ public:
return nullptr;
}
+ virtual bool deactivateOnLastTabClose() const { return false; }
+
void updateTheme();
};
diff --git a/ui/tabwidget.h b/ui/tabwidget.h
index 14dc80ec..16f57b7c 100644
--- a/ui/tabwidget.h
+++ b/ui/tabwidget.h
@@ -397,7 +397,9 @@ class BINARYNINJAUIAPI SplitTabWidget : public QWidget
QString savedLayoutString() const;
void restoreLayoutString(const QString& layout);
- Q_SIGNALS:
+ bool isEmpty() const;
+
+Q_SIGNALS:
void tabClosed(QWidget* widget);
void currentChanged(QWidget* widget);
void layoutChanged();
diff --git a/ui/uicontext.h b/ui/uicontext.h
index b59db8b1..5ca5a4e5 100644
--- a/ui/uicontext.h
+++ b/ui/uicontext.h
@@ -595,13 +595,17 @@ public:
void NotifyOnViewChange(ViewFrame* frame, const QString& type);
void NotifyOnAddressChange(ViewFrame* frame, View* view, const ViewLocation& location);
void NotifyOnILViewTypeChange(ViewFrame* frame, View* view, const BinaryNinja::FunctionViewType& viewType);
- void updateCrossReferences(ViewFrame* frame, View* view, const SelectionInfoForXref& selection);
+ virtual void updateCrossReferences(ViewFrame* frame, View* view, const SelectionInfoForXref& selection);
void NotifyOnActionExecuted(UIActionHandler* handler, const QString& name, const UIActionContext& ctx, std::function<void(const UIActionContext&)>& action);
void NotifyOnActionExecutedImmutable(UIActionHandler* handler, const QString& name, const UIActionContext& ctx);
void NotifyOnContextMenuCreated(View* view, Menu& menu);
virtual void findAll(const BinaryNinja::FindParameters& params);
+ virtual void beginNavigationForCrossReference(ViewFrame* frame, const SelectionInfoForXref& selection) = 0;
+ virtual void endNavigationForCrossReference() = 0;
+ virtual bool isNavigatingForCrossReference() = 0;
+
/*!
Register an object to receive notifications of UIContext events
\param notification Object which will receive notifications
diff --git a/ui/xreflist.h b/ui/xreflist.h
index ed29843b..c144da71 100644
--- a/ui/xreflist.h
+++ b/ui/xreflist.h
@@ -25,6 +25,7 @@
#include "viewframe.h"
#include "fontsettings.h"
#include "expandablegroup.h"
+#include "tabwidget.h"
class XrefHeader;
@@ -676,7 +677,6 @@ class BINARYNINJAUIAPI CrossReferenceWidget : public SidebarWidget, public UICon
SelectionInfoForXref m_curRef;
SelectionInfoForXref m_newRef;
std::optional<SelectionInfoForXref> m_pendingSelection;
- bool m_navigating = false;
bool m_navToNextOrPrevStarted = false;
bool m_pinned;
bool m_uiMaxItemsExceeded = false;
@@ -729,11 +729,13 @@ class BINARYNINJAUIAPI CrossReferenceWidget : public SidebarWidget, public UICon
void notifyRefresh() override;
void notifyQuiesce(bool quiesce) override;
+ const SelectionInfoForXref& getCurrentSelection() const { return m_curRef; }
+
private Q_SLOTS:
void hoverTimerEvent();
- void newPinnedPane();
+ void newPinnedTab();
- public Q_SLOTS:
+public Q_SLOTS:
void referenceActivated(const QModelIndex& idx);
void pinnedStateChanged(bool state);
void selectionChanged();
@@ -753,6 +755,21 @@ class BINARYNINJAUIAPI CrossReferenceSidebarWidgetType : public SidebarWidgetTyp
virtual SidebarWidget* createWidget(ViewFrame* frame, BinaryViewRef data) override;
};
+/*!
+ \ingroup xreflist
+*/
+class BINARYNINJAUIAPI PinnedCrossReferenceSidebarWidgetType : public SidebarWidgetType
+{
+public:
+ PinnedCrossReferenceSidebarWidgetType();
+ SidebarWidgetLocation defaultLocation() const override { return SidebarWidgetLocation::RightBottom; }
+ SidebarContextSensitivity contextSensitivity() const override { return PerViewTypeSidebarContext; }
+ bool alwaysShowTabs() const override { return true; }
+ QString noWidgetMessage() const override { return "No pinned cross references"; }
+ DockableTabStyle* tabStyle() const override { return new DefaultDockableTabStyle(); }
+ bool deactivateOnLastTabClose() const override { return true; }
+};
+
// https://github.com/CuriousCrow/QCheckboxCombo
/*! QCheckboxCombo is a combobox widget that contains items with checkboxes.
diff --git a/ui/xrefstate.h b/ui/xrefstate.h
new file mode 100644
index 00000000..e81be4a0
--- /dev/null
+++ b/ui/xrefstate.h
@@ -0,0 +1,30 @@
+#pragma once
+
+#include "binaryninjaapi.h"
+#include "uicontext.h"
+
+class SplitPaneContainer;
+class SplitPaneWidget;
+
+class BINARYNINJAUIAPI CrossReferenceState
+{
+ std::map<SplitPaneContainer*, std::map<QString, SelectionInfoForXref>> m_curXref;
+ SplitPaneContainer* m_currentContainer = nullptr;
+ QString m_currentDataType;
+
+public:
+ CrossReferenceState();
+
+ std::optional<SelectionInfoForXref> getCurrentSelection() const;
+
+ void updateCrossReferences(ViewFrame* frame, const SelectionInfoForXref& selection);
+ void beginNavigationForCrossReference(ViewFrame* frame, const SelectionInfoForXref& selection);
+
+ void setActiveContext(ViewFrame* frame);
+ void destroyContext(SplitPaneWidget* splitPane);
+
+ void newPinnedTab();
+ void newPinnedPane();
+
+ void bindActions(UIContext* context);
+};