summaryrefslogtreecommitdiff
path: root/Source/Core/DolphinQt/Debugger/MemoryViewWidget.cpp
diff options
context:
space:
mode:
authorTryTwo <taolas@gmail.com>2022-09-30 15:01:56 -0700
committerTryTwo <taolas@gmail.com>2022-10-22 17:52:39 -0700
commit6f4f4e057e58d1720db7a68f80f6dcc24c686a3e (patch)
treede66e41c87b1bbaf6a0dcf443918c49ca99ce47d /Source/Core/DolphinQt/Debugger/MemoryViewWidget.cpp
parent9ca1c0f53349b3a736942ebd1f89f8e70e954a32 (diff)
MemoryViewWidget refactor memory table.
Don't re-create the table on every update.
Diffstat (limited to 'Source/Core/DolphinQt/Debugger/MemoryViewWidget.cpp')
-rw-r--r--Source/Core/DolphinQt/Debugger/MemoryViewWidget.cpp441
1 files changed, 223 insertions, 218 deletions
diff --git a/Source/Core/DolphinQt/Debugger/MemoryViewWidget.cpp b/Source/Core/DolphinQt/Debugger/MemoryViewWidget.cpp
index c12fbf0d3b..81178106af 100644
--- a/Source/Core/DolphinQt/Debugger/MemoryViewWidget.cpp
+++ b/Source/Core/DolphinQt/Debugger/MemoryViewWidget.cpp
@@ -33,6 +33,8 @@
// 120; i.e., 120 units * 1/8 = 15 degrees." (http://doc.qt.io/qt-5/qwheelevent.html#angleDelta)
constexpr double SCROLL_FRACTION_DEGREES = 15.;
+// Number of columns that don't contain the value of a memory address.
+constexpr int MISC_COLUMNS = 2;
constexpr auto USER_ROLE_IS_ROW_BREAKPOINT_CELL = Qt::UserRole;
constexpr auto USER_ROLE_CELL_ADDRESS = Qt::UserRole + 1;
constexpr auto USER_ROLE_VALUE_TYPE = Qt::UserRole + 2;
@@ -55,6 +57,9 @@ public:
setShowGrid(false);
setContextMenuPolicy(Qt::CustomContextMenu);
setSelectionMode(SingleSelection);
+ setTextElideMode(Qt::TextElideMode::ElideNone);
+ setRowCount(30);
+ setColumnCount(8);
connect(this, &MemoryViewTable::customContextMenuRequested, m_view,
&MemoryViewWidget::OnContextMenu);
@@ -64,7 +69,7 @@ public:
void resizeEvent(QResizeEvent* event) override
{
QTableWidget::resizeEvent(event);
- m_view->Update();
+ m_view->CreateTable();
}
void keyPressEvent(QKeyEvent* event) override
@@ -175,11 +180,12 @@ MemoryViewWidget::MemoryViewWidget(QWidget* parent) : QWidget(parent)
this->setLayout(layout);
connect(&Settings::Instance(), &Settings::DebugFontChanged, this, &MemoryViewWidget::UpdateFont);
- connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, [this] { Update(); });
- connect(Host::GetInstance(), &Host::UpdateDisasmDialog, this, &MemoryViewWidget::Update);
+ connect(&Settings::Instance(), &Settings::EmulationStateChanged, this,
+ &MemoryViewWidget::UpdateColumns);
+ connect(Host::GetInstance(), &Host::UpdateDisasmDialog, this, &MemoryViewWidget::UpdateColumns);
connect(&Settings::Instance(), &Settings::ThemeChanged, this, &MemoryViewWidget::Update);
- // Also calls update.
+ // Also calls create table.
UpdateFont();
}
@@ -196,7 +202,8 @@ void MemoryViewWidget::UpdateFont()
m_font_width = fm.width(QLatin1Char('0'));
#endif
m_table->setFont(Settings::Instance().GetDebugFont());
- Update();
+
+ CreateTable();
}
constexpr int GetTypeSize(MemoryViewWidget::Type type)
@@ -258,269 +265,265 @@ constexpr int GetCharacterCount(MemoryViewWidget::Type type)
}
}
-void MemoryViewWidget::Update()
+void MemoryViewWidget::CreateTable()
{
- const QSignalBlocker blocker(m_table);
-
- m_table->clearSelection();
-
- u32 address = m_address;
- address = Common::AlignDown(address, m_alignment);
-
- const int data_columns = m_bytes_per_row / GetTypeSize(m_type);
-
- if (m_dual_view)
- m_table->setColumnCount(2 + 2 * data_columns);
- else
- m_table->setColumnCount(2 + data_columns);
-
- if (m_table->rowCount() == 0)
- m_table->setRowCount(1);
+ m_table->clearContents();
// This sets all row heights and determines horizontal ascii spacing.
+ // Could be placed in UpdateFont() but doesn't apply correctly unless called more.
m_table->verticalHeader()->setDefaultSectionSize(m_font_vspace - 1);
m_table->verticalHeader()->setMinimumSectionSize(m_font_vspace - 1);
m_table->horizontalHeader()->setMinimumSectionSize(m_font_width * 2);
- m_table->setTextElideMode(Qt::TextElideMode::ElideNone);
- const AddressSpace::Accessors* accessors = AddressSpace::GetAccessors(m_address_space);
+ const QSignalBlocker blocker(m_table);
+
+ // Set column and row parameters.
+ // Span is the number of unique memory values covered in one row.
+ const int data_span = m_bytes_per_row / GetTypeSize(m_type);
+ m_data_columns = m_dual_view ? data_span * 2 : data_span;
+ const int total_columns = MISC_COLUMNS + m_data_columns;
- // Calculate (roughly) how many rows will fit in our table
const int rows =
std::round((m_table->height() / static_cast<float>(m_table->rowHeight(0))) - 0.25);
+ m_table->setColumnCount(total_columns);
m_table->setRowCount(rows);
+ m_table->setColumnWidth(0, m_table->rowHeight(0));
- for (int i = 0; i < rows; i++)
- {
- u32 row_address = address - ((m_table->rowCount() / 2) * m_bytes_per_row) + i * m_bytes_per_row;
-
- auto* bp_item = new QTableWidgetItem;
- bp_item->setFlags(Qt::ItemIsEnabled);
- bp_item->setData(USER_ROLE_IS_ROW_BREAKPOINT_CELL, true);
- bp_item->setData(USER_ROLE_CELL_ADDRESS, row_address);
- bp_item->setData(USER_ROLE_VALUE_TYPE, static_cast<int>(Type::Null));
+ // Get optional dual-view type
+ std::optional<Type> left_type = std::nullopt;
- m_table->setItem(i, 0, bp_item);
+ if (m_dual_view)
+ {
+ if (GetTypeSize(m_type) == 1)
+ left_type = Type::Hex8;
+ else if (GetTypeSize(m_type) == 2)
+ left_type = Type::Hex16;
+ else if (GetTypeSize(m_type) == 8)
+ left_type = Type::Hex64;
+ else
+ left_type = Type::Hex32;
+ }
- auto* row_item =
- new QTableWidgetItem(QStringLiteral("%1").arg(row_address, 8, 16, QLatin1Char('0')));
+ // Create cells and add data that won't be changing.
+ // Breakpoint buttons
+ auto* bp_item = new QTableWidgetItem;
+ bp_item->setFlags(Qt::ItemIsEnabled);
+ bp_item->setData(USER_ROLE_IS_ROW_BREAKPOINT_CELL, true);
+ bp_item->setData(USER_ROLE_VALUE_TYPE, static_cast<int>(Type::Null));
- row_item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
- row_item->setData(USER_ROLE_IS_ROW_BREAKPOINT_CELL, false);
- row_item->setData(USER_ROLE_CELL_ADDRESS, row_address);
- row_item->setData(USER_ROLE_VALUE_TYPE, static_cast<int>(Type::Null));
+ // Row Addresses
+ auto* row_item = new QTableWidgetItem(QStringLiteral("-"));
+ row_item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
+ row_item->setData(USER_ROLE_IS_ROW_BREAKPOINT_CELL, false);
+ row_item->setData(USER_ROLE_VALUE_TYPE, static_cast<int>(Type::Null));
- m_table->setItem(i, 1, row_item);
+ // Data item
+ auto* item = new QTableWidgetItem(QStringLiteral("-"));
+ item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable);
+ item->setData(USER_ROLE_IS_ROW_BREAKPOINT_CELL, false);
- if (row_address == address)
- row_item->setSelected(true);
+ for (int i = 0; i < rows; i++)
+ {
+ m_table->setItem(i, 0, bp_item->clone());
+ m_table->setItem(i, 1, row_item->clone());
- if (Core::GetState() != Core::State::Paused || !accessors->IsValidAddress(row_address))
+ for (int c = 0; c < m_data_columns; c++)
{
- for (int c = 2; c < m_table->columnCount(); c++)
+ if (left_type && c < data_span)
+ {
+ item->setData(USER_ROLE_VALUE_TYPE, static_cast<int>(left_type.value()));
+ }
+ else
{
- auto* item = new QTableWidgetItem(QStringLiteral("-"));
- item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
- item->setData(USER_ROLE_IS_ROW_BREAKPOINT_CELL, false);
- item->setData(USER_ROLE_CELL_ADDRESS, row_address);
- item->setData(USER_ROLE_VALUE_TYPE, static_cast<int>(Type::Null));
+ item->setData(USER_ROLE_VALUE_TYPE, static_cast<int>(m_type));
- m_table->setItem(i, c, item);
+ // Left type will never be these.
+ auto text_alignment = Qt::AlignLeft;
+ if (m_type == Type::Signed32 || m_type == Type::Unsigned32 || m_type == Type::Signed16 ||
+ m_type == Type::Unsigned16 || m_type == Type::Signed8 || m_type == Type::Unsigned8)
+ {
+ text_alignment = Qt::AlignRight;
+ }
+ item->setTextAlignment(text_alignment | Qt::AlignVCenter);
}
- continue;
+ m_table->setItem(i, c + MISC_COLUMNS, item->clone());
}
}
- int starting_column = 2;
+ // Update column width
+ int start_fill = MISC_COLUMNS;
+ if (left_type)
+ {
+ const int width_left = m_font_width * GetCharacterCount(left_type.value());
- if (m_dual_view)
+ for (int i = 0; i < data_span - 1; i++)
+ m_table->setColumnWidth(i + start_fill, width_left);
+
+ // Extra spacing between dual views.
+ m_table->setColumnWidth(start_fill + data_span - 1, width_left + m_font_width * 2);
+
+ start_fill += data_span;
+ }
+
+ // If dual-view, updates the right-side columns only.
+ const int width = m_font_width * GetCharacterCount(m_type);
+ for (int i = start_fill; i < total_columns; i++)
+ m_table->setColumnWidth(i, width);
+
+ Update();
+}
+
+void MemoryViewWidget::Update()
+{
+ // Check if table is created
+ if (m_table->item(1, 1) == nullptr)
+ return;
+
+ const QSignalBlocker blocker(m_table);
+ m_table->clearSelection();
+
+ // Update addresses
+ const u32 address = Common::AlignDown(m_address, m_alignment);
+ u32 row_address = address - (m_table->rowCount() / 2) * m_bytes_per_row;
+ const int data_span = m_bytes_per_row / GetTypeSize(m_type);
+
+ for (int i = 0; i < m_table->rowCount(); i++, row_address += m_bytes_per_row)
{
- // Match left columns to number of right columns.
- Type left_type = Type::Hex32;
- if (GetTypeSize(m_type) == 1)
- left_type = Type::Hex8;
- else if (GetTypeSize(m_type) == 2)
- left_type = Type::Hex16;
- else if (GetTypeSize(m_type) == 8)
- left_type = Type::Hex64;
+ auto* bp_item = m_table->item(i, 0);
+ bp_item->setData(USER_ROLE_CELL_ADDRESS, row_address);
- UpdateColumns(left_type, starting_column);
+ auto* row_item = m_table->item(i, 1);
+ row_item->setText(QStringLiteral("%1").arg(row_address, 8, 16, QLatin1Char('0')));
+ row_item->setData(USER_ROLE_CELL_ADDRESS, row_address);
- const int column_count = m_bytes_per_row / GetTypeSize(left_type);
+ if (row_address == address)
+ row_item->setSelected(true);
- // Update column width
- for (int i = starting_column; i < starting_column + column_count - 1; i++)
- m_table->setColumnWidth(i, m_font_width * GetCharacterCount(left_type));
+ for (int c = 0; c < m_data_columns; c++)
+ {
+ auto* item = m_table->item(i, c + MISC_COLUMNS);
- // Extra spacing between dual views.
- m_table->setColumnWidth(starting_column + column_count - 1,
- m_font_width * (GetCharacterCount(left_type) + 2));
+ u32 item_address;
+ if (m_dual_view && c >= data_span)
+ item_address = row_address + (c - data_span) * GetTypeSize(m_type);
+ else
+ item_address = row_address + c * GetTypeSize(m_type);
- starting_column += column_count;
+ item->setData(USER_ROLE_CELL_ADDRESS, item_address);
+ }
}
- UpdateColumns(m_type, starting_column);
+ UpdateColumns();
UpdateBreakpointTags();
- m_table->setColumnWidth(0, m_table->rowHeight(0));
-
- for (int i = starting_column; i <= m_table->columnCount(); i++)
- m_table->setColumnWidth(i, m_font_width * GetCharacterCount(m_type));
-
m_table->viewport()->update();
m_table->update();
update();
}
-void MemoryViewWidget::UpdateColumns(Type type, int first_column)
+void MemoryViewWidget::UpdateColumns()
{
- if (Core::GetState() != Core::State::Paused)
+ // Check if table is created
+ if (m_table->item(1, 1) == nullptr)
return;
- const int data_columns = m_bytes_per_row / GetTypeSize(type);
- const AddressSpace::Accessors* accessors = AddressSpace::GetAccessors(m_address_space);
-
- auto text_alignment = Qt::AlignLeft;
- if (type == Type::Signed32 || type == Type::Unsigned32 || type == Type::Signed16 ||
- type == Type::Unsigned16 || type == Type::Signed8 || type == Type::Unsigned8)
- {
- text_alignment = Qt::AlignRight;
- }
+ const QSignalBlocker blocker(m_table);
for (int i = 0; i < m_table->rowCount(); i++)
{
- u32 row_address = m_table->item(i, 1)->data(USER_ROLE_CELL_ADDRESS).toUInt();
- if (!accessors->IsValidAddress(row_address))
- continue;
+ for (int c = 0; c < m_data_columns; c++)
+ {
+ auto* cell_item = m_table->item(i, c + MISC_COLUMNS);
+ const u32 cell_address = cell_item->data(USER_ROLE_CELL_ADDRESS).toUInt();
+ const Type type = static_cast<Type>(cell_item->data(USER_ROLE_VALUE_TYPE).toInt());
- auto update_values = [&](auto value_to_string) {
- for (int c = 0; c < data_columns; c++)
- {
- auto* cell_item = new QTableWidgetItem;
- cell_item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable);
- cell_item->setTextAlignment(text_alignment);
+ cell_item->setText(ValueToString(cell_address, type));
+ }
+ }
+}
- const u32 cell_address = row_address + c * GetTypeSize(type);
+QString MemoryViewWidget::ValueToString(u32 address, Type type)
+{
+ const AddressSpace::Accessors* accessors = AddressSpace::GetAccessors(m_address_space);
+ if (!accessors->IsValidAddress(address) || Core::GetState() != Core::State::Paused)
+ return QStringLiteral("-");
- m_table->setItem(i, first_column + c, cell_item);
+ switch (type)
+ {
+ case Type::Hex8:
+ {
+ const u8 value = accessors->ReadU8(address);
+ return QStringLiteral("%1").arg(value, 2, 16, QLatin1Char('0'));
+ }
+ case Type::ASCII:
+ {
+ const char value = accessors->ReadU8(address);
+ return IsPrintableCharacter(value) ? QString{QChar::fromLatin1(value)} :
+ QString{QChar::fromLatin1('.')};
+ }
+ case Type::Hex16:
+ {
+ const u16 value = accessors->ReadU16(address);
+ return QStringLiteral("%1").arg(value, 4, 16, QLatin1Char('0'));
+ }
+ case Type::Hex32:
+ {
+ const u32 value = accessors->ReadU32(address);
+ return QStringLiteral("%1").arg(value, 8, 16, QLatin1Char('0'));
+ }
+ case Type::Hex64:
+ {
+ const u64 value = accessors->ReadU64(address);
+ return QStringLiteral("%1").arg(value, 16, 16, QLatin1Char('0'));
+ }
+ case Type::Unsigned8:
+ return QString::number(accessors->ReadU8(address));
+ case Type::Unsigned16:
+ return QString::number(accessors->ReadU16(address));
+ case Type::Unsigned32:
+ return QString::number(accessors->ReadU32(address));
+ case Type::Signed8:
+ return QString::number(Common::BitCast<s8>(accessors->ReadU8(address)));
+ case Type::Signed16:
+ return QString::number(Common::BitCast<s16>(accessors->ReadU16(address)));
+ case Type::Signed32:
+ return QString::number(Common::BitCast<s32>(accessors->ReadU32(address)));
+ case Type::Float32:
+ {
+ QString string = QString::number(accessors->ReadF32(address), 'g', 4);
+ // Align to first digit.
+ if (!string.startsWith(QLatin1Char('-')))
+ string.prepend(QLatin1Char(' '));
- if (accessors->IsValidAddress(cell_address))
- {
- cell_item->setText(value_to_string(cell_address));
- cell_item->setData(USER_ROLE_IS_ROW_BREAKPOINT_CELL, false);
- cell_item->setData(USER_ROLE_CELL_ADDRESS, cell_address);
- cell_item->setData(USER_ROLE_VALUE_TYPE, static_cast<int>(type));
- }
- else
- {
- cell_item->setText(QStringLiteral("-"));
- cell_item->setData(USER_ROLE_IS_ROW_BREAKPOINT_CELL, false);
- cell_item->setData(USER_ROLE_CELL_ADDRESS, cell_address);
- cell_item->setData(USER_ROLE_VALUE_TYPE, static_cast<int>(Type::Null));
- }
- }
- };
- switch (type)
- {
- case Type::Hex8:
- update_values([&accessors](u32 address) {
- const u8 value = accessors->ReadU8(address);
- return QStringLiteral("%1").arg(value, 2, 16, QLatin1Char('0'));
- });
- break;
- case Type::ASCII:
- update_values([&accessors](u32 address) {
- const char value = accessors->ReadU8(address);
- return IsPrintableCharacter(value) ? QString{QChar::fromLatin1(value)} :
- QString{QChar::fromLatin1('.')};
- });
- break;
- case Type::Hex16:
- update_values([&accessors](u32 address) {
- const u16 value = accessors->ReadU16(address);
- return QStringLiteral("%1").arg(value, 4, 16, QLatin1Char('0'));
- });
- break;
- case Type::Hex32:
- update_values([&accessors](u32 address) {
- const u32 value = accessors->ReadU32(address);
- return QStringLiteral("%1").arg(value, 8, 16, QLatin1Char('0'));
- });
- break;
- case Type::Hex64:
- update_values([&accessors](u32 address) {
- const u64 value = accessors->ReadU64(address);
- return QStringLiteral("%1").arg(value, 16, 16, QLatin1Char('0'));
- });
- break;
- case Type::Unsigned8:
- update_values(
- [&accessors](u32 address) { return QString::number(accessors->ReadU8(address)); });
- break;
- case Type::Unsigned16:
- update_values(
- [&accessors](u32 address) { return QString::number(accessors->ReadU16(address)); });
- break;
- case Type::Unsigned32:
- update_values(
- [&accessors](u32 address) { return QString::number(accessors->ReadU32(address)); });
- break;
- case Type::Signed8:
- update_values([&accessors](u32 address) {
- return QString::number(Common::BitCast<s8>(accessors->ReadU8(address)));
- });
- break;
- case Type::Signed16:
- update_values([&accessors](u32 address) {
- return QString::number(Common::BitCast<s16>(accessors->ReadU16(address)));
- });
- break;
- case Type::Signed32:
- update_values([&accessors](u32 address) {
- return QString::number(Common::BitCast<s32>(accessors->ReadU32(address)));
- });
- break;
- case Type::Float32:
- update_values([&accessors](u32 address) {
- QString string = QString::number(accessors->ReadF32(address), 'g', 4);
- // Align to first digit.
- if (!string.startsWith(QLatin1Char('-')))
- string.prepend(QLatin1Char(' '));
-
- return string;
- });
- break;
- case Type::Double:
- update_values([&accessors](u32 address) {
- QString string =
- QString::number(Common::BitCast<double>(accessors->ReadU64(address)), 'g', 4);
- // Align to first digit.
- if (!string.startsWith(QLatin1Char('-')))
- string.prepend(QLatin1Char(' '));
-
- return string;
- });
- break;
- }
+ return string;
+ }
+ case Type::Double:
+ {
+ QString string = QString::number(Common::BitCast<double>(accessors->ReadU64(address)), 'g', 4);
+ // Align to first digit.
+ if (!string.startsWith(QLatin1Char('-')))
+ string.prepend(QLatin1Char(' '));
+
+ return string;
+ }
+ default:
+ return QStringLiteral("-");
}
}
void MemoryViewWidget::UpdateBreakpointTags()
{
- if (Core::GetState() != Core::State::Paused)
- return;
-
for (int i = 0; i < m_table->rowCount(); i++)
{
bool row_breakpoint = false;
- for (int c = 2; c < m_table->columnCount(); c++)
+ for (int c = 0; c < m_data_columns; c++)
{
// Pull address from cell itself, helpful for dual column view.
- auto cell = m_table->item(i, c);
- u32 address = cell->data(USER_ROLE_CELL_ADDRESS).toUInt();
+ auto cell = m_table->item(i, c + MISC_COLUMNS);
+ const u32 address = cell->data(USER_ROLE_CELL_ADDRESS).toUInt();
if (address == 0)
{
@@ -528,14 +531,16 @@ void MemoryViewWidget::UpdateBreakpointTags()
continue;
}
- // In dual view the only sizes that dont match up on both left and right views are for
- // Double, which uses two or four columns of hex32.
if (m_address_space == AddressSpace::Type::Effective &&
PowerPC::memchecks.GetMemCheck(address, GetTypeSize(m_type)) != nullptr)
{
row_breakpoint = true;
cell->setBackground(Qt::red);
}
+ else
+ {
+ cell->setBackground(Qt::white);
+ }
}
if (row_breakpoint)
@@ -545,6 +550,10 @@ void MemoryViewWidget::UpdateBreakpointTags()
Resources::GetScaledThemeIcon("debugger_breakpoint")
.pixmap(QSize(m_table->rowHeight(0) - 3, m_table->rowHeight(0) - 3)));
}
+ else
+ {
+ m_table->item(i, 0)->setData(Qt::DecorationRole, QIcon());
+ }
}
}
@@ -724,7 +733,7 @@ void MemoryViewWidget::SetDisplay(Type type, int bytes_per_row, int alignment, b
else
m_alignment = alignment;
- Update();
+ CreateTable();
}
void MemoryViewWidget::SetBPType(BPType type)
@@ -815,25 +824,21 @@ void MemoryViewWidget::OnContextMenu(const QPoint& pos)
if (!item_selected || item_selected->data(USER_ROLE_IS_ROW_BREAKPOINT_CELL).toBool())
return;
- const bool item_has_value =
- item_selected->data(USER_ROLE_VALUE_TYPE).toInt() != static_cast<int>(Type::Null);
const u32 addr = item_selected->data(USER_ROLE_CELL_ADDRESS).toUInt();
+ const AddressSpace::Accessors* accessors = AddressSpace::GetAccessors(m_address_space);
+ const bool item_has_value =
+ item_selected->data(USER_ROLE_VALUE_TYPE).toInt() != static_cast<int>(Type::Null) &&
+ accessors->IsValidAddress(addr);
auto* menu = new QMenu(this);
menu->addAction(tr("Copy Address"), this, [this, addr] { OnCopyAddress(addr); });
auto* copy_hex = menu->addAction(tr("Copy Hex"), this, [this, addr] { OnCopyHex(addr); });
+ copy_hex->setEnabled(item_has_value);
- const AddressSpace::Accessors* accessors = AddressSpace::GetAccessors(m_address_space);
- copy_hex->setEnabled(item_has_value && Core::GetState() != Core::State::Uninitialized &&
- accessors->IsValidAddress(addr));
-
- auto* copy_value = menu->addAction(tr("Copy Value"), this, [this, &pos] {
- // Re-fetch the item in case the underlying table has refreshed since the menu was opened.
- auto* item = m_table->itemAt(pos);
- if (item && item->data(USER_ROLE_VALUE_TYPE).toInt() != static_cast<int>(Type::Null))
- QApplication::clipboard()->setText(item->text());
+ auto* copy_value = menu->addAction(tr("Copy Value"), this, [this, item_selected] {
+ QApplication::clipboard()->setText(item_selected->text());
});
copy_value->setEnabled(item_has_value);