summaryrefslogtreecommitdiff
path: root/plugins/warp/ui/matched.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/warp/ui/matched.cpp')
-rw-r--r--plugins/warp/ui/matched.cpp83
1 files changed, 83 insertions, 0 deletions
diff --git a/plugins/warp/ui/matched.cpp b/plugins/warp/ui/matched.cpp
new file mode 100644
index 00000000..475e0cdd
--- /dev/null
+++ b/plugins/warp/ui/matched.cpp
@@ -0,0 +1,83 @@
+#include "matched.h"
+
+#include <QGridLayout>
+
+#include "theme.h"
+
+const char *WARP_APPLY_ACTIVITY = "analysis.warp.apply";
+
+WarpMatchedWidget::WarpMatchedWidget(BinaryViewRef current)
+{
+ m_current = current;
+ // Create the QT stuff
+ QGridLayout *layout = new QGridLayout(this);
+ layout->setContentsMargins(2, 2, 2, 2);
+ layout->setSpacing(2);
+ auto newPalette = palette();
+ newPalette.setColor(QPalette::Window, getThemeColor(SidebarWidgetBackgroundColor));
+ setAutoFillBackground(true);
+ setPalette(newPalette);
+
+ // TODO: Split horizontally if the widget is displayed in a sidebar that is vertically challenged.
+ m_splitter = new QSplitter(Qt::Vertical);
+ m_splitter->setContentsMargins(0, 0, 0, 0);
+
+ // Add a widget to display the matches.
+ m_tableWidget = new WarpFunctionTableWidget(this);
+ m_tableWidget->setContentsMargins(0, 0, 0, 0);
+ m_splitter->addWidget(m_tableWidget);
+
+ // Toggle the applying workflow, this workflow sets all the data for the function based on the matched function data.
+ m_tableWidget->RegisterContextMenuAction("Toggle Application",
+ [this](WarpFunctionItem *, std::optional<uint64_t> address) {
+ if (!address.has_value())
+ return;
+ for (const auto &func: m_current->GetAnalysisFunctionsForAddress(
+ *address))
+ {
+ const bool previous = BinaryNinja::Settings::Instance()->Get<bool>(
+ WARP_APPLY_ACTIVITY, func);
+ BinaryNinja::Settings::Instance()->Set(
+ WARP_APPLY_ACTIVITY, !previous, func);
+ func->Reanalyze();
+ }
+ });
+
+ layout->addWidget(m_splitter, 1, 0, 1, 5);
+ setLayout(layout);
+
+ Update();
+
+ connect(m_tableWidget->GetTableView(), &QTableView::clicked, this,
+ [this](const QModelIndex &index) {
+ if (m_current == nullptr)
+ return;
+ if (!index.isValid())
+ return;
+ const QModelIndex sourceIndex = m_tableWidget->GetProxyModel()->mapToSource(index);
+ if (!sourceIndex.isValid())
+ return;
+ auto selectedItem = m_tableWidget->GetModel()->GetAddress(sourceIndex);
+ if (!selectedItem.has_value())
+ return;
+ // Navigate to the address in the view, so the user feels like they are doing something.
+ auto currentView = m_current->GetCurrentView();
+ m_current->Navigate(currentView, selectedItem.value());
+ });
+}
+
+void WarpMatchedWidget::Update()
+{
+ m_tableWidget->GetTableView()->setSortingEnabled(false);
+ m_tableWidget->GetTableView()->setEnabled(false);
+ for (const auto &analysisFunction: m_current->GetAnalysisFunctionList())
+ {
+ if (const auto &matchedFunction = Warp::Function::GetMatched(*analysisFunction))
+ {
+ uint64_t startAddress = analysisFunction->GetStart();
+ m_tableWidget->InsertFunction(startAddress, new WarpFunctionItem(matchedFunction, analysisFunction));
+ }
+ }
+ m_tableWidget->GetTableView()->setEnabled(true);
+ m_tableWidget->GetTableView()->setSortingEnabled(true);
+}