summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binaryninjaapi.h38
-rw-r--r--binaryninjacore.h48
-rw-r--r--database.cpp28
-rw-r--r--filemetadata.cpp94
-rw-r--r--ui/historyview.h54
-rw-r--r--ui/uitypes.h2
-rw-r--r--undoaction.cpp62
7 files changed, 187 insertions, 139 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index a9aba0af..791acf07 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -2330,7 +2330,7 @@ namespace BinaryNinja {
const BNInstructionTextToken* tokens, size_t count);
};
- struct UndoEntry;
+ class UndoEntry;
/*!
@@ -2399,8 +2399,8 @@ namespace BinaryNinja {
DataBuffer GetFileContents();
DataBuffer GetFileContentsHash();
DataBuffer GetUndoData();
- std::vector<UndoEntry> GetUndoEntries();
- std::vector<UndoEntry> GetUndoEntries(const std::function<bool(size_t, size_t)>& progress);
+ std::vector<Ref<UndoEntry>> GetUndoEntries();
+ std::vector<Ref<UndoEntry>> GetUndoEntries(const std::function<bool(size_t, size_t)>& progress);
Ref<KeyValueStore> ReadData();
Ref<KeyValueStore> ReadData(const std::function<bool(size_t, size_t)>& progress);
bool StoreData(const Ref<KeyValueStore>& data, const std::function<bool(size_t, size_t)>& progress);
@@ -2744,31 +2744,31 @@ namespace BinaryNinja {
void EndBulkOperation();
};
-
/*!
\ingroup undo
*/
- struct UndoAction
+ class UndoAction : public CoreRefCountObject<BNUndoAction, BNNewUndoActionReference, BNFreeUndoAction>
{
- BNActionType actionType;
- std::string summaryText;
- std::vector<InstructionTextToken> summaryTokens;
+ public:
+ UndoAction(BNUndoAction* action);
- UndoAction() {};
- UndoAction(const BNUndoAction& action);
+ std::string GetSummaryText();
+ std::vector<InstructionTextToken> GetSummary();
};
/*!
\ingroup undo
*/
- struct UndoEntry
+ class UndoEntry : public CoreRefCountObject<BNUndoEntry, BNNewUndoEntryReference, BNFreeUndoEntry>
{
- Ref<User> user;
- std::string id;
- std::vector<UndoAction> actions;
- uint64_t timestamp;
+ public:
+ UndoEntry(BNUndoEntry* entry);
+
+ std::string GetId();
+ std::vector<Ref<UndoAction>> GetActions();
+ uint64_t GetTimestamp();
};
/*!
@@ -2995,10 +2995,10 @@ namespace BinaryNinja {
bool Redo();
std::vector<Ref<User>> GetUsers();
- std::vector<UndoEntry> GetUndoEntries();
- std::vector<UndoEntry> GetRedoEntries();
- std::optional<UndoEntry> GetLastUndoEntry();
- std::optional<UndoEntry> GetLastRedoEntry();
+ std::vector<Ref<UndoEntry>> GetUndoEntries();
+ std::vector<Ref<UndoEntry>> GetRedoEntries();
+ Ref<UndoEntry> GetLastUndoEntry();
+ Ref<UndoEntry> GetLastRedoEntry();
std::optional<std::string> GetLastUndoEntryTitle();
std::optional<std::string> GetLastRedoEntryTitle();
void ClearUndoEntries();
diff --git a/binaryninjacore.h b/binaryninjacore.h
index 2eee74e9..04612d43 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -293,6 +293,8 @@ extern "C"
typedef struct BNAnalysisMergeConflict BNAnalysisMergeConflict;
typedef struct BNTypeArchiveMergeConflict BNTypeArchiveMergeConflict;
typedef struct BNCollaborationLazyT BNCollaborationLazyT;
+ typedef struct BNUndoAction BNUndoAction;
+ typedef struct BNUndoEntry BNUndoEntry;
//! Console log levels
typedef enum BNLogLevel
@@ -2193,24 +2195,6 @@ extern "C"
uint64_t addr;
} BNTagReference;
- typedef struct BNUndoAction
- {
- BNActionType actionType;
- char* summaryText;
- BNInstructionTextToken* summaryTokens;
- size_t summaryTokenCount;
- } BNUndoAction;
-
- typedef struct BNUndoEntry
- {
- bool valid;
- BNUser* user;
- char* id;
- BNUndoAction* actions;
- uint64_t actionCount;
- uint64_t timestamp;
- } BNUndoEntry;
-
typedef struct BNCallingConventionWithConfidence
{
BNCallingConvention* convention;
@@ -3649,13 +3633,27 @@ extern "C"
BINARYNINJACOREAPI BNKeyValueStore* BNReadSnapshotDataWithProgress(
BNSnapshot* snapshot, void* ctxt, bool (*progress)(void* ctxt, size_t progress, size_t total));
BINARYNINJACOREAPI BNDataBuffer* BNGetSnapshotUndoData(BNSnapshot* snapshot);
- BINARYNINJACOREAPI BNUndoEntry* BNGetSnapshotUndoEntries(BNSnapshot* snapshot, size_t* count);
- BINARYNINJACOREAPI BNUndoEntry* BNGetSnapshotUndoEntriesWithProgress(
+ BINARYNINJACOREAPI BNUndoEntry** BNGetSnapshotUndoEntries(BNSnapshot* snapshot, size_t* count);
+ BINARYNINJACOREAPI BNUndoEntry** BNGetSnapshotUndoEntriesWithProgress(
BNSnapshot* snapshot, void* ctxt, bool (*progress)(void* ctxt, size_t progress, size_t total), size_t* count);
BINARYNINJACOREAPI bool BNSnapshotHasAncestor(BNSnapshot* snapshot, BNSnapshot* other);
BINARYNINJACOREAPI bool BNSnapshotStoreData(BNSnapshot* snapshot, BNKeyValueStore* data,
void* ctxt, BNProgressFunction progress);
+ // Undo actions
+ BINARYNINJACOREAPI BNUndoAction* BNNewUndoActionReference(BNUndoAction* action);
+ BINARYNINJACOREAPI void BNFreeUndoAction(BNUndoAction* action);
+ BINARYNINJACOREAPI void BNFreeUndoActionList(BNUndoAction** actions, size_t count);
+ BINARYNINJACOREAPI char* BNUndoActionGetSummaryText(BNUndoAction* action);
+ BINARYNINJACOREAPI BNInstructionTextToken* BNUndoActionGetSummary(BNUndoAction* action, size_t* tokenCount);
+
+ // Undo entries
+ BINARYNINJACOREAPI BNUndoEntry* BNNewUndoEntryReference(BNUndoEntry* entry);
+ BINARYNINJACOREAPI void BNFreeUndoEntry(BNUndoEntry* entry);
+ BINARYNINJACOREAPI void BNFreeUndoEntryList(BNUndoEntry** entrys, size_t count);
+ BINARYNINJACOREAPI char* BNUndoEntryGetId(BNUndoEntry* entry);
+ BINARYNINJACOREAPI BNUndoAction** BNUndoEntryGetActions(BNUndoEntry* entry, size_t* count);
+ BINARYNINJACOREAPI uint64_t BNUndoEntryGetTimestamp(BNUndoEntry* entry);
BINARYNINJACOREAPI bool BNRebase(BNBinaryView* data, uint64_t address);
BINARYNINJACOREAPI bool BNRebaseWithProgress(
@@ -3683,13 +3681,13 @@ extern "C"
BINARYNINJACOREAPI bool BNCanRedo(BNFileMetadata* file);
BINARYNINJACOREAPI bool BNRedo(BNFileMetadata* file);
- BINARYNINJACOREAPI BNUndoEntry* BNGetUndoEntries(BNFileMetadata* file, size_t* count);
- BINARYNINJACOREAPI BNUndoEntry* BNGetRedoEntries(BNFileMetadata* file, size_t* count);
- BINARYNINJACOREAPI BNUndoEntry BNGetLastUndoEntry(BNFileMetadata* file);
- BINARYNINJACOREAPI BNUndoEntry BNGetLastRedoEntry(BNFileMetadata* file);
+ BINARYNINJACOREAPI BNUndoEntry** BNGetUndoEntries(BNFileMetadata* file, size_t* count);
+ BINARYNINJACOREAPI BNUndoEntry** BNGetRedoEntries(BNFileMetadata* file, size_t* count);
+ BINARYNINJACOREAPI BNUndoEntry* BNGetLastUndoEntry(BNFileMetadata* file);
+ BINARYNINJACOREAPI BNUndoEntry* BNGetLastRedoEntry(BNFileMetadata* file);
BINARYNINJACOREAPI char* BNGetLastUndoEntryTitle(BNFileMetadata* file);
BINARYNINJACOREAPI char* BNGetLastRedoEntryTitle(BNFileMetadata* file);
- BINARYNINJACOREAPI void BNFreeUndoEntries(BNUndoEntry* entries, size_t count);
+ BINARYNINJACOREAPI void BNFreeUndoEntries(BNUndoEntry** entries, size_t count);
BINARYNINJACOREAPI void BNClearUndoEntries(BNFileMetadata* file);
BINARYNINJACOREAPI BNUser* BNNewUserReference(BNUser* user);
diff --git a/database.cpp b/database.cpp
index 26802f29..f3a6072f 100644
--- a/database.cpp
+++ b/database.cpp
@@ -298,41 +298,31 @@ DataBuffer Snapshot::GetUndoData()
}
-vector<UndoEntry> Snapshot::GetUndoEntries()
+vector<Ref<UndoEntry>> Snapshot::GetUndoEntries()
{
return GetUndoEntries([](size_t, size_t) { return true; });
}
-vector<UndoEntry> Snapshot::GetUndoEntries(const std::function<bool(size_t, size_t)>& progress)
+vector<Ref<UndoEntry>> Snapshot::GetUndoEntries(const std::function<bool(size_t, size_t)>& progress)
{
ProgressContext pctxt;
pctxt.callback = progress;
- size_t numEntries;
- BNUndoEntry* entries = BNGetSnapshotUndoEntriesWithProgress(m_object, &pctxt, ProgressCallback, &numEntries);
+ size_t count;
+ BNUndoEntry** entries = BNGetSnapshotUndoEntriesWithProgress(m_object, &pctxt, ProgressCallback, &count);
if (entries == nullptr)
{
- throw DatabaseException("BNGetSnapshotUndoEntries");
+ throw DatabaseException("BNGetSnapshotUndoEntriesWithProgress");
}
- vector<UndoEntry> result;
- result.reserve(numEntries);
- for (size_t i = 0; i < numEntries; i++)
+ vector<Ref<UndoEntry>> result;
+ for (size_t i = 0; i < count; i++)
{
- UndoEntry temp;
- temp.timestamp = entries[i].timestamp;
- temp.id = entries[i].id;
- temp.user = new User(BNNewUserReference(entries[i].user));
- size_t actionCount = entries[i].actionCount;
- for (size_t actionIndex = 0; actionIndex < actionCount; actionIndex++)
- {
- temp.actions.emplace_back(entries[i].actions[actionIndex]);
- }
- result.push_back(temp);
+ result.push_back(new UndoEntry(BNNewUndoEntryReference(entries[i])));
}
+ BNFreeUndoEntryList(entries, count);
- BNFreeUndoEntries(entries, numEntries);
return result;
}
diff --git a/filemetadata.cpp b/filemetadata.cpp
index 656fbce7..6aca379c 100644
--- a/filemetadata.cpp
+++ b/filemetadata.cpp
@@ -368,101 +368,55 @@ vector<Ref<User>> FileMetadata::GetUsers()
}
-vector<UndoEntry> FileMetadata::GetUndoEntries()
+vector<Ref<UndoEntry>> FileMetadata::GetUndoEntries()
{
- size_t numEntries;
- BNUndoEntry* entries = BNGetUndoEntries(m_object, &numEntries);
+ size_t count;
+ BNUndoEntry** entries = BNGetUndoEntries(m_object, &count);
- vector<UndoEntry> result;
- result.reserve(numEntries);
- for (size_t i = 0; i < numEntries; i++)
+ vector<Ref<UndoEntry>> result;
+ for (size_t i = 0; i < count; i++)
{
- if (!entries[i].valid)
- continue;
- UndoEntry temp;
- temp.timestamp = entries[i].timestamp;
- temp.id = entries[i].id;
- temp.user = new User(BNNewUserReference(entries[i].user));
- size_t actionCount = entries[i].actionCount;
- for (size_t actionIndex = 0; actionIndex < actionCount; actionIndex++)
- {
- temp.actions.emplace_back(entries[i].actions[actionIndex]);
- }
- result.push_back(temp);
+ result.push_back(new UndoEntry(BNNewUndoEntryReference(entries[i])));
}
-
- // BNFreeUndoEntries(entries, count);
+ BNFreeUndoEntryList(entries, count);
return result;
}
-vector<UndoEntry> FileMetadata::GetRedoEntries()
+vector<Ref<UndoEntry>> FileMetadata::GetRedoEntries()
{
- size_t numEntries;
- BNUndoEntry* entries = BNGetRedoEntries(m_object, &numEntries);
+ size_t count;
+ BNUndoEntry** entries = BNGetRedoEntries(m_object, &count);
- vector<UndoEntry> result;
- result.reserve(numEntries);
- for (size_t i = 0; i < numEntries; i++)
+ vector<Ref<UndoEntry>> result;
+ for (size_t i = 0; i < count; i++)
{
- if (!entries[i].valid)
- continue;
- UndoEntry temp;
- temp.timestamp = entries[i].timestamp;
- temp.id = entries[i].id;
- temp.user = new User(BNNewUserReference(entries[i].user));
- size_t actionCount = entries[i].actionCount;
- for (size_t actionIndex = 0; actionIndex < actionCount; actionIndex++)
- {
- temp.actions.emplace_back(entries[i].actions[actionIndex]);
- }
- result.push_back(temp);
+ result.push_back(new UndoEntry(BNNewUndoEntryReference(entries[i])));
}
-
- // BNFreeUndoEntries(entries, count);
+ BNFreeUndoEntryList(entries, count);
return result;
}
-std::optional<UndoEntry> FileMetadata::GetLastUndoEntry()
+Ref<UndoEntry> FileMetadata::GetLastUndoEntry()
{
- BNUndoEntry bnEntry = BNGetLastUndoEntry(m_object);
-
- if (!bnEntry.valid)
- return {};
+ BNUndoEntry* bnEntry = BNGetLastUndoEntry(m_object);
- UndoEntry entry;
- entry.timestamp = bnEntry.timestamp;
- entry.id = bnEntry.id;
- entry.user = new User(BNNewUserReference(bnEntry.user));
- size_t actionCount = bnEntry.actionCount;
- for (size_t actionIndex = 0; actionIndex < actionCount; actionIndex++)
- {
- entry.actions.emplace_back(bnEntry.actions[actionIndex]);
- }
+ if (bnEntry == nullptr)
+ return nullptr;
- return entry;
+ return new UndoEntry(bnEntry);
}
-std::optional<UndoEntry> FileMetadata::GetLastRedoEntry()
+Ref<UndoEntry> FileMetadata::GetLastRedoEntry()
{
- BNUndoEntry bnEntry = BNGetLastRedoEntry(m_object);
+ BNUndoEntry* bnEntry = BNGetLastRedoEntry(m_object);
- if (!bnEntry.valid)
- return {};
-
- UndoEntry entry;
- entry.timestamp = bnEntry.timestamp;
- entry.id = bnEntry.id;
- entry.user = new User(BNNewUserReference(bnEntry.user));
- size_t actionCount = bnEntry.actionCount;
- for (size_t actionIndex = 0; actionIndex < actionCount; actionIndex++)
- {
- entry.actions.emplace_back(bnEntry.actions[actionIndex]);
- }
+ if (bnEntry == nullptr)
+ return nullptr;
- return entry;
+ return new UndoEntry(bnEntry);
}
diff --git a/ui/historyview.h b/ui/historyview.h
new file mode 100644
index 00000000..06f6561d
--- /dev/null
+++ b/ui/historyview.h
@@ -0,0 +1,54 @@
+#pragma once
+
+#include "filter.h"
+#include "sidebarwidget.h"
+#include <qsortfilterproxymodel.h>
+#include <qstandarditemmodel.h>
+#include <qtreeview.h>
+
+
+class BINARYNINJAUIAPI HistorySidebarWidget : public SidebarWidget, public FilterTarget
+{
+ Q_OBJECT
+ QTreeView* m_tree;
+ QStandardItemModel* m_model;
+ QSortFilterProxyModel* m_proxyModel;
+
+ QWidget* m_header;
+ FilteredView* m_libFilter;
+ BinaryViewRef m_data;
+ ContextMenuManager* m_contextMenuManager;
+ Menu m_contextMenu;
+ bool m_updating = false;
+
+ std::unordered_map<std::string, QPersistentModelIndex> m_idIndices;
+
+ virtual void scrollToFirstItem() override;
+ virtual void scrollToCurrentItem() override;
+ virtual void selectFirstItem() override;
+ virtual void activateFirstItem() override;
+ virtual void setFilter(const std::string& filter) override;
+
+ virtual void contextMenuEvent(QContextMenuEvent*) override;
+
+ void itemDoubleClicked(const QModelIndex& index);
+ void scrollBarRangeChanged(int min, int max);
+
+ void populateTree();
+
+ public:
+ HistorySidebarWidget(BinaryViewRef data);
+
+ void notifyFontChanged() override;
+ QWidget* headerWidget() override { return m_header; }
+};
+
+
+class BINARYNINJAUIAPI HistorySidebarWidgetType : public SidebarWidgetType
+{
+ public:
+ HistorySidebarWidgetType();
+ SidebarWidget* createWidget(ViewFrame* frame, BinaryViewRef data) override;
+ SidebarWidgetLocation defaultLocation() const override { return SidebarWidgetLocation::RightBottom; }
+ SidebarContextSensitivity contextSensitivity() const override { return PerViewTypeSidebarContext; }
+};
diff --git a/ui/uitypes.h b/ui/uitypes.h
index 68022642..511e5aa9 100644
--- a/ui/uitypes.h
+++ b/ui/uitypes.h
@@ -115,6 +115,8 @@ typedef BinaryNinja::Ref<BinaryNinja::RepoPlugin> RepoPluginRef;
typedef BinaryNinja::Ref<BinaryNinja::Repository> RepositoryRef;
typedef BinaryNinja::Ref<BinaryNinja::RepositoryManager> RepositoryManagerRef;
typedef BinaryNinja::Ref<BinaryNinja::Logger> LoggerRef;
+typedef BinaryNinja::Ref<BinaryNinja::UndoAction> UndoActionRef;
+typedef BinaryNinja::Ref<BinaryNinja::UndoEntry> UndoEntryRef;
typedef BinaryNinja::Ref<BinaryNinja::Collaboration::Remote> RemoteRef;
typedef BinaryNinja::Ref<BinaryNinja::Collaboration::RemoteProject> RemoteProjectRef;
diff --git a/undoaction.cpp b/undoaction.cpp
index 5d2e5268..8b596888 100644
--- a/undoaction.cpp
+++ b/undoaction.cpp
@@ -25,13 +25,63 @@ using namespace Json;
using namespace std;
-UndoAction::UndoAction(const BNUndoAction& action)
+UndoAction::UndoAction(BNUndoAction* action)
{
- actionType = action.actionType;
- summaryText = action.summaryText;
- summaryTokens.reserve(action.summaryTokenCount);
- for (size_t i = 0; i < action.summaryTokenCount; i++)
+ m_object = action;
+}
+
+
+std::string UndoAction::GetSummaryText()
+{
+ char* summary = BNUndoActionGetSummaryText(m_object);
+ std::string result = summary;
+ BNFreeString(summary);
+ return result;
+}
+
+
+vector<InstructionTextToken> UndoAction::GetSummary()
+{
+ size_t count = 0;
+ BNInstructionTextToken* result = BNUndoActionGetSummary(m_object, &count);
+ vector<InstructionTextToken> newTokens;
+ return InstructionTextToken::ConvertAndFreeInstructionTextTokenList(result, count);
+}
+
+
+UndoEntry::UndoEntry(BNUndoEntry* entry)
+{
+ m_object = entry;
+}
+
+
+std::string UndoEntry::GetId()
+{
+ char* id = BNUndoEntryGetId(m_object);
+ std::string result = id;
+ BNFreeString(id);
+ return result;
+}
+
+
+std::vector<Ref<UndoAction>> UndoEntry::GetActions()
+{
+ size_t count;
+
+ BNUndoAction** actions = BNUndoEntryGetActions(m_object, &count);
+ std::vector<Ref<UndoAction>> result;
+ result.reserve(count);
+ for (size_t i = 0; i < count; i++)
{
- summaryTokens.push_back(action.summaryTokens[i]);
+ result.push_back(new UndoAction(BNNewUndoActionReference(actions[i])));
}
+
+ BNFreeUndoActionList(actions, count);
+ return result;
+}
+
+
+uint64_t UndoEntry::GetTimestamp()
+{
+ return BNUndoEntryGetTimestamp(m_object);
}