summaryrefslogtreecommitdiff
path: root/examples/triage/entry.cpp
diff options
context:
space:
mode:
authorAlexander Taylor <alex@vector35.com>2025-04-30 21:16:54 -0400
committerAlexander Taylor <alex@vector35.com>2025-10-17 21:17:53 -0400
commit715dd78287934c2dcb6de54b0a9be48b2237f9e6 (patch)
tree5c339ec4723db8617b2888096efb5dacaabb66bc /examples/triage/entry.cpp
parent93438ca338adccada9fbb973f09ffd44275ca334 (diff)
Make Triage Summary tables multi-select + copyable.
Closes #6562.
Diffstat (limited to 'examples/triage/entry.cpp')
-rw-r--r--examples/triage/entry.cpp50
1 files changed, 50 insertions, 0 deletions
diff --git a/examples/triage/entry.cpp b/examples/triage/entry.cpp
index f66634f1..c62b9c36 100644
--- a/examples/triage/entry.cpp
+++ b/examples/triage/entry.cpp
@@ -1,5 +1,8 @@
#include <cstring>
#include <algorithm>
+#include <QtGui/QClipboard>
+#include <QtGui/QGuiApplication>
+#include <QtCore/QStringList>
#include "entry.h"
#include "view.h"
#include "fontsettings.h"
@@ -167,6 +170,9 @@ EntryTreeView::EntryTreeView(EntryWidget* parent, TriageView* view, BinaryViewRe
setRootIsDecorated(false);
setUniformRowHeights(true);
setSortingEnabled(true);
+ setSelectionMode(QAbstractItemView::ExtendedSelection);
+ setSelectionBehavior(QAbstractItemView::SelectRows);
+ setAllColumnsShowFocus(true);
sortByColumn(AddressColumn, Qt::AscendingOrder);
setColumnWidth(AddressColumn, 90);
@@ -175,6 +181,44 @@ EntryTreeView::EntryTreeView(EntryWidget* parent, TriageView* view, BinaryViewRe
connect(selectionModel(), &QItemSelectionModel::currentChanged, this, &EntryTreeView::entrySelected);
connect(this, &QTreeView::doubleClicked, this, &EntryTreeView::entryDoubleClicked);
+
+ m_actionHandler.bindAction("Copy", UIAction([this]() { copySelection(); }, [this]() { return canCopySelection(); }));
+}
+
+void EntryTreeView::copySelection()
+{
+ if (!model() || !selectionModel())
+ return;
+
+ QModelIndexList rows = selectionModel()->selectedRows();
+ if (rows.isEmpty())
+ return;
+
+ std::sort(rows.begin(), rows.end(), [](const QModelIndex& a, const QModelIndex& b) { return a.row() < b.row(); });
+
+ QStringList lines;
+ for (const QModelIndex& rowIndex : rows)
+ {
+ QStringList cells;
+ for (int column = 0; column < m_model->columnCount(QModelIndex()); column++)
+ {
+ if (isColumnHidden(column))
+ continue;
+
+ QModelIndex idx = m_model->index(rowIndex.row(), column, QModelIndex());
+ cells << m_model->data(idx, Qt::DisplayRole).toString();
+ }
+ lines << cells.join("\t");
+ }
+
+ if (QClipboard* clipboard = QGuiApplication::clipboard())
+ clipboard->setText(lines.join("\n"));
+}
+
+
+bool EntryTreeView::canCopySelection() const
+{
+ return !selectionModel()->selectedRows().isEmpty();
}
@@ -258,6 +302,12 @@ void EntryTreeView::keyPressEvent(QKeyEvent* event)
if (sel.size() != 0)
entryDoubleClicked(sel[0]);
}
+ else if (event->matches(QKeySequence::Copy))
+ {
+ copySelection();
+ event->accept();
+ return;
+ }
QTreeView::keyPressEvent(event);
}