From fc238ab9dae01634990d3875a5e1c6e0f26ca9c7 Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 1 Apr 2024 16:04:58 +0100 Subject: [PATCH] Add a copy entry to the debug messages right-click menu --- qrenderdoc/Widgets/Extended/RDTableView.cpp | 118 +++++++++++--------- qrenderdoc/Widgets/Extended/RDTableView.h | 3 + qrenderdoc/Windows/DebugMessageView.cpp | 6 + 3 files changed, 72 insertions(+), 55 deletions(-) diff --git a/qrenderdoc/Widgets/Extended/RDTableView.cpp b/qrenderdoc/Widgets/Extended/RDTableView.cpp index 64afbffdb..0063d3dc4 100644 --- a/qrenderdoc/Widgets/Extended/RDTableView.cpp +++ b/qrenderdoc/Widgets/Extended/RDTableView.cpp @@ -158,61 +158,7 @@ void RDTableView::keyPressEvent(QKeyEvent *e) { if(e == QKeySequence::Copy) { - QModelIndexList sel = selectionModel()->selectedIndexes(); - - if(!sel.isEmpty()) - { - int stackWidths[16]; - int *heapWidths = NULL; - - int colCount = model()->columnCount(); - - if(colCount >= 16) - heapWidths = new int[colCount]; - - int *widths = heapWidths ? heapWidths : stackWidths; - - for(int i = 0; i < colCount; i++) - widths[i] = 0; - - int top = sel[0].row(), bottom = sel[0].row(); - int left = sel[0].column(), right = sel[0].column(); - - // align the copied data so that each column is the same width - for(QModelIndex idx : sel) - { - QString text = model()->data(idx).toString(); - widths[idx.column()] = qMax(widths[idx.column()], text.count()); - - top = qMin(top, idx.row()); - bottom = qMax(bottom, idx.row()); - left = qMin(left, idx.column()); - right = qMax(right, idx.column()); - } - - // only align up to 50 characters so one really long item doesn't mess up the whole thing - for(int i = 0; i < colCount; i++) - widths[i] = qMin(50, widths[i]); - - QString clipData; - for(int row = top; row <= bottom; row++) - { - for(int col = left; col <= right; col++) - { - QString format = col == left ? lit("%1") : lit(" %1"); - QString text = model()->data(model()->index(row, col)).toString(); - - clipData += format.arg(text, -widths[col]); - } - - clipData += lit("\n"); - } - - QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(clipData.trimmed()); - - delete[] heapWidths; - } + copySelectedIndices(); e->accept(); return; @@ -221,6 +167,68 @@ void RDTableView::keyPressEvent(QKeyEvent *e) return QTableView::keyPressEvent(e); } +void RDTableView::copyIndices(const QModelIndexList &sel) +{ + if(!sel.isEmpty()) + { + int stackWidths[16]; + int *heapWidths = NULL; + + int colCount = model()->columnCount(); + + if(colCount >= 16) + heapWidths = new int[colCount]; + + int *widths = heapWidths ? heapWidths : stackWidths; + + for(int i = 0; i < colCount; i++) + widths[i] = 0; + + int top = sel[0].row(), bottom = sel[0].row(); + int left = sel[0].column(), right = sel[0].column(); + + // align the copied data so that each column is the same width + for(QModelIndex idx : sel) + { + QString text = model()->data(idx).toString(); + widths[idx.column()] = qMax(widths[idx.column()], text.count()); + + top = qMin(top, idx.row()); + bottom = qMax(bottom, idx.row()); + left = qMin(left, idx.column()); + right = qMax(right, idx.column()); + } + + // only align up to 50 characters so one really long item doesn't mess up the whole thing + for(int i = 0; i < colCount; i++) + widths[i] = qMin(50, widths[i]); + + QString clipData; + for(int row = top; row <= bottom; row++) + { + for(int col = left; col <= right; col++) + { + QString format = col == left ? lit("%1") : lit(" %1"); + QString text = model()->data(model()->index(row, col)).toString(); + + clipData += format.arg(text, -widths[col]); + } + + clipData += lit("\n"); + } + + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setText(clipData.trimmed()); + + delete[] heapWidths; + } +} + +void RDTableView::copySelectedIndices() +{ + copyIndices(selectionModel()->selectedIndexes()); +} + void RDTableView::keyboardSearch(const QString &search) { if(m_allowKeyboardSearches) diff --git a/qrenderdoc/Widgets/Extended/RDTableView.h b/qrenderdoc/Widgets/Extended/RDTableView.h index 74348e79d..dc79f682e 100644 --- a/qrenderdoc/Widgets/Extended/RDTableView.h +++ b/qrenderdoc/Widgets/Extended/RDTableView.h @@ -45,6 +45,9 @@ public: void setColumnWidths(const QList &widths); void resizeColumnsToContents(); + void copyIndices(const QModelIndexList &sel); + void copySelectedIndices(); + void setAllowKeyboardSearches(bool allow) { m_allowKeyboardSearches = allow; } bool allowKeyboardSearches() const { return m_allowKeyboardSearches; } void keyboardSearch(const QString &search) override; diff --git a/qrenderdoc/Windows/DebugMessageView.cpp b/qrenderdoc/Windows/DebugMessageView.cpp index 83ac043a2..2aff4aee2 100644 --- a/qrenderdoc/Windows/DebugMessageView.cpp +++ b/qrenderdoc/Windows/DebugMessageView.cpp @@ -26,6 +26,7 @@ #include #include #include "Code/QRDUtils.h" +#include "Code/Resources.h" #include "ui_DebugMessageView.h" static const int EIDRole = Qt::UserRole + 1; @@ -235,6 +236,10 @@ DebugMessageView::DebugMessageView(ICaptureContext &ctx, QWidget *parent) m_ShowHidden->setCheckable(true); + QAction *copy = new QAction(tr("&Copy"), this); + copy->setIcon(Icons::copy()); + m_ContextMenu->addAction(copy); + m_ContextMenu->addSeparator(); m_ContextMenu->addAction(m_ShowHidden); m_ContextMenu->addSeparator(); m_ContextMenu->addAction(m_ToggleSource); @@ -248,6 +253,7 @@ DebugMessageView::DebugMessageView(ICaptureContext &ctx, QWidget *parent) QObject::connect(m_ToggleCategory, &QAction::triggered, this, &DebugMessageView::messages_toggled); QObject::connect(m_ToggleMessageType, &QAction::triggered, this, &DebugMessageView::messages_toggled); + QObject::connect(copy, &QAction::triggered, [this]() { ui->messages->copySelectedIndices(); }); RefreshMessageList();