mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 06:09:50 -06:00
MemoryViewWidget: Refactor. Remove OnItemChanged signal and QSignalBlocker - replace with a signal that is only sent at the correct time.
This commit is contained in:
@ -10,10 +10,11 @@
|
|||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
|
#include <QLineEdit>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
#include <QSignalBlocker>
|
#include <QStyledItemDelegate>
|
||||||
#include <QTableWidget>
|
#include <QTableWidget>
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
|
||||||
@ -52,6 +53,14 @@ constexpr int SCROLLBAR_CENTER = SCROLLBAR_MAXIMUM / 2;
|
|||||||
|
|
||||||
const QString INVALID_MEMORY = QStringLiteral("-");
|
const QString INVALID_MEMORY = QStringLiteral("-");
|
||||||
|
|
||||||
|
void TableEditDelegate::setModelData(QWidget* editor, QAbstractItemModel* model,
|
||||||
|
const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
// Triggers on placing data into a cell. Editor has the text to be input, index has the location.
|
||||||
|
const QString input = qobject_cast<QLineEdit*>(editor)->text();
|
||||||
|
emit editFinished(index.row(), index.column(), input);
|
||||||
|
}
|
||||||
|
|
||||||
class MemoryViewTable final : public QTableWidget
|
class MemoryViewTable final : public QTableWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -66,6 +75,11 @@ public:
|
|||||||
setSelectionMode(NoSelection);
|
setSelectionMode(NoSelection);
|
||||||
setTextElideMode(Qt::TextElideMode::ElideNone);
|
setTextElideMode(Qt::TextElideMode::ElideNone);
|
||||||
|
|
||||||
|
// Route user's direct cell inputs to an editFinished signal. Much better than an itemChanged
|
||||||
|
// signal and QSignalBlock juggling.
|
||||||
|
TableEditDelegate* table_edit_delegate = new TableEditDelegate(this);
|
||||||
|
setItemDelegate(table_edit_delegate);
|
||||||
|
|
||||||
// Prevent colors from changing based on focus.
|
// Prevent colors from changing based on focus.
|
||||||
QPalette palette(m_view->palette());
|
QPalette palette(m_view->palette());
|
||||||
palette.setBrush(QPalette::Inactive, QPalette::Highlight, palette.brush(QPalette::Highlight));
|
palette.setBrush(QPalette::Inactive, QPalette::Highlight, palette.brush(QPalette::Highlight));
|
||||||
@ -78,7 +92,8 @@ public:
|
|||||||
|
|
||||||
connect(this, &MemoryViewTable::customContextMenuRequested, m_view,
|
connect(this, &MemoryViewTable::customContextMenuRequested, m_view,
|
||||||
&MemoryViewWidget::OnContextMenu);
|
&MemoryViewWidget::OnContextMenu);
|
||||||
connect(this, &MemoryViewTable::itemChanged, this, &MemoryViewTable::OnItemChanged);
|
connect(table_edit_delegate, &TableEditDelegate::editFinished, this,
|
||||||
|
&MemoryViewTable::OnDirectTableEdit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void resizeEvent(QResizeEvent* event) override
|
void resizeEvent(QResizeEvent* event) override
|
||||||
@ -146,9 +161,9 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnItemChanged(QTableWidgetItem* item)
|
void OnDirectTableEdit(const int row, const int column, const QString& text)
|
||||||
{
|
{
|
||||||
QString text = item->text();
|
QTableWidgetItem* item = this->item(row, column);
|
||||||
MemoryViewWidget::Type type =
|
MemoryViewWidget::Type type =
|
||||||
static_cast<MemoryViewWidget::Type>(item->data(USER_ROLE_VALUE_TYPE).toInt());
|
static_cast<MemoryViewWidget::Type>(item->data(USER_ROLE_VALUE_TYPE).toInt());
|
||||||
std::vector<u8> bytes = m_view->ConvertTextToBytes(type, text);
|
std::vector<u8> bytes = m_view->ConvertTextToBytes(type, text);
|
||||||
@ -156,16 +171,16 @@ public:
|
|||||||
u32 address = item->data(USER_ROLE_CELL_ADDRESS).toUInt();
|
u32 address = item->data(USER_ROLE_CELL_ADDRESS).toUInt();
|
||||||
u32 end_address = address + static_cast<u32>(bytes.size()) - 1;
|
u32 end_address = address + static_cast<u32>(bytes.size()) - 1;
|
||||||
AddressSpace::Accessors* accessors = AddressSpace::GetAccessors(m_view->GetAddressSpace());
|
AddressSpace::Accessors* accessors = AddressSpace::GetAccessors(m_view->GetAddressSpace());
|
||||||
|
|
||||||
const Core::CPUThreadGuard guard(m_view->m_system);
|
|
||||||
|
|
||||||
if (!bytes.empty() && accessors->IsValidAddress(guard, address) &&
|
|
||||||
accessors->IsValidAddress(guard, end_address))
|
|
||||||
{
|
{
|
||||||
for (const u8 c : bytes)
|
const Core::CPUThreadGuard guard(m_view->m_system);
|
||||||
accessors->WriteU8(guard, address++, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!bytes.empty() && accessors->IsValidAddress(guard, address) &&
|
||||||
|
accessors->IsValidAddress(guard, end_address))
|
||||||
|
{
|
||||||
|
for (const u8 c : bytes)
|
||||||
|
accessors->WriteU8(guard, address++, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
m_view->Update();
|
m_view->Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,8 +307,6 @@ void MemoryViewWidget::CreateTable()
|
|||||||
m_table->verticalHeader()->setMinimumSectionSize(m_font_vspace);
|
m_table->verticalHeader()->setMinimumSectionSize(m_font_vspace);
|
||||||
m_table->horizontalHeader()->setMinimumSectionSize(m_font_width * 2);
|
m_table->horizontalHeader()->setMinimumSectionSize(m_font_width * 2);
|
||||||
|
|
||||||
const QSignalBlocker blocker(m_table);
|
|
||||||
|
|
||||||
// Set column and row parameters.
|
// Set column and row parameters.
|
||||||
// Span is the number of unique memory values covered in one row.
|
// Span is the number of unique memory values covered in one row.
|
||||||
const int data_span = m_bytes_per_row / GetTypeSize(m_type);
|
const int data_span = m_bytes_per_row / GetTypeSize(m_type);
|
||||||
@ -398,7 +411,6 @@ void MemoryViewWidget::Update()
|
|||||||
if (m_table->item(1, 1) == nullptr)
|
if (m_table->item(1, 1) == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const QSignalBlocker blocker(m_table);
|
|
||||||
m_table->clearSelection();
|
m_table->clearSelection();
|
||||||
|
|
||||||
// Update addresses
|
// Update addresses
|
||||||
@ -464,8 +476,6 @@ void MemoryViewWidget::UpdateColumns(const Core::CPUThreadGuard* guard)
|
|||||||
if (m_table->item(1, 1) == nullptr)
|
if (m_table->item(1, 1) == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const QSignalBlocker blocker(m_table);
|
|
||||||
|
|
||||||
for (int i = 0; i < m_table->rowCount(); i++)
|
for (int i = 0; i < m_table->rowCount(); i++)
|
||||||
{
|
{
|
||||||
for (int c = 0; c < m_data_columns; c++)
|
for (int c = 0; c < m_data_columns; c++)
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
@ -22,6 +23,21 @@ class CPUThreadGuard;
|
|||||||
class System;
|
class System;
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|
||||||
|
// Captures direct editing of the table.
|
||||||
|
class TableEditDelegate : public QStyledItemDelegate
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit TableEditDelegate(QObject* parent) : QStyledItemDelegate(parent) {}
|
||||||
|
|
||||||
|
void setModelData(QWidget* editor, QAbstractItemModel* model,
|
||||||
|
const QModelIndex& index) const override;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void editFinished(const int row, const int column, const QString& text) const;
|
||||||
|
};
|
||||||
|
|
||||||
class MemoryViewTable;
|
class MemoryViewTable;
|
||||||
|
|
||||||
class MemoryViewWidget final : public QWidget
|
class MemoryViewWidget final : public QWidget
|
||||||
|
Reference in New Issue
Block a user