summaryrefslogtreecommitdiff
path: root/examples/triage/exports.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/exports.cpp
parent93438ca338adccada9fbb973f09ffd44275ca334 (diff)
Make Triage Summary tables multi-select + copyable.
Closes #6562.
Diffstat (limited to 'examples/triage/exports.cpp')
-rw-r--r--examples/triage/exports.cpp50
1 files changed, 50 insertions, 0 deletions
diff --git a/examples/triage/exports.cpp b/examples/triage/exports.cpp
index 04547144..ad315384 100644
--- a/examples/triage/exports.cpp
+++ b/examples/triage/exports.cpp
@@ -1,4 +1,7 @@
#include <QtWidgets/QScrollBar>
+#include <QtGui/QClipboard>
+#include <QtGui/QGuiApplication>
+#include <QtCore/QStringList>
#include <algorithm>
#include "exports.h"
#include "view.h"
@@ -319,6 +322,9 @@ ExportsTreeView::ExportsTreeView(ExportsWidget* parent, TriageView* view, Binary
setRootIsDecorated(false);
setUniformRowHeights(true);
setSortingEnabled(true);
+ setSelectionMode(QAbstractItemView::ExtendedSelection);
+ setSelectionBehavior(QAbstractItemView::SelectRows);
+ setAllColumnsShowFocus(true);
sortByColumn(AddressColumn, Qt::AscendingOrder);
setColumnWidth(OrdinalColumn, 55);
@@ -342,6 +348,44 @@ ExportsTreeView::ExportsTreeView(ExportsWidget* parent, TriageView* view, Binary
}
verticalScrollBar()->setValue(m_scroll);
});
+
+ m_actionHandler.bindAction("Copy", UIAction([this]() { copySelection(); }, [this]() { return canCopySelection(); }));
+}
+
+void ExportsTreeView::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 ExportsTreeView::canCopySelection() const
+{
+ return !selectionModel()->selectedRows().isEmpty();
}
@@ -425,6 +469,12 @@ void ExportsTreeView::keyPressEvent(QKeyEvent* event)
if (sel.size() != 0)
exportDoubleClicked(sel[0]);
}
+ else if (event->matches(QKeySequence::Copy))
+ {
+ copySelection();
+ event->accept();
+ return;
+ }
QTreeView::keyPressEvent(event);
}