summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authoriwubcode <iwubcode@users.noreply.github.com>2022-12-23 03:11:17 -0600
committeriwubcode <iwubcode@users.noreply.github.com>2022-12-23 12:31:33 -0600
commit190cf5af3085fa3d62575dedb03419fc72a24ffe (patch)
tree998920b08eeace22534428bdad1d95457f28b62b /Source/Core
parentc8a6ff630930c16bb59ec6922a543e41be01e461 (diff)
DolphinQt: add multiselection to WatchWidget
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/DolphinQt/Debugger/WatchWidget.cpp110
-rw-r--r--Source/Core/DolphinQt/Debugger/WatchWidget.h4
2 files changed, 96 insertions, 18 deletions
diff --git a/Source/Core/DolphinQt/Debugger/WatchWidget.cpp b/Source/Core/DolphinQt/Debugger/WatchWidget.cpp
index 2f0df1d72f..2f4ea27598 100644
--- a/Source/Core/DolphinQt/Debugger/WatchWidget.cpp
+++ b/Source/Core/DolphinQt/Debugger/WatchWidget.cpp
@@ -83,7 +83,8 @@ void WatchWidget::CreateWidgets()
m_table->setColumnCount(NUM_COLUMNS);
m_table->verticalHeader()->setHidden(true);
m_table->setContextMenuPolicy(Qt::CustomContextMenu);
- m_table->setSelectionMode(QAbstractItemView::SingleSelection);
+ m_table->setSelectionMode(QAbstractItemView::ExtendedSelection);
+ m_table->setSelectionBehavior(QAbstractItemView::SelectRows);
m_new = m_toolbar->addAction(tr("New"), this, &WatchWidget::OnNewWatch);
m_delete = m_toolbar->addAction(tr("Delete"), this, &WatchWidget::OnDelete);
@@ -239,11 +240,7 @@ void WatchWidget::OnDelete()
if (m_table->selectedItems().empty())
return;
- auto row_variant = m_table->selectedItems()[0]->data(Qt::UserRole);
- if (row_variant.isNull())
- return;
-
- DeleteWatch(row_variant.toInt());
+ DeleteSelectedWatches();
}
void WatchWidget::OnClear()
@@ -310,20 +307,30 @@ void WatchWidget::ShowContextMenu()
if (!m_table->selectedItems().empty())
{
- auto row_variant = m_table->selectedItems()[0]->data(Qt::UserRole);
-
- if (!row_variant.isNull())
+ const std::size_t count = m_table->selectionModel()->selectedRows().count();
+ if (count > 1)
+ {
+ menu->addAction(tr("&Delete Watches"), this, [this] { DeleteSelectedWatches(); });
+ menu->addAction(tr("&Lock Watches"), this, [this] { LockSelectedWatches(); });
+ menu->addAction(tr("&Unlock Watches"), this, [this] { UnlockSelectedWatches(); });
+ }
+ else if (count == 1)
{
- int row = row_variant.toInt();
+ auto row_variant = m_table->selectedItems()[0]->data(Qt::UserRole);
- if (row >= 0)
+ if (!row_variant.isNull())
{
- menu->addAction(tr("Show in Memory"), this, [this, row] { ShowInMemory(row); });
- // i18n: This kind of "watch" is used for watching emulated memory.
- // It's not related to timekeeping devices.
- menu->addAction(tr("&Delete Watch"), this, [this, row] { DeleteWatch(row); });
- menu->addAction(tr("&Add Memory Breakpoint"), this,
- [this, row] { AddWatchBreakpoint(row); });
+ int row = row_variant.toInt();
+
+ if (row >= 0)
+ {
+ menu->addAction(tr("Show in Memory"), this, [this, row] { ShowInMemory(row); });
+ // i18n: This kind of "watch" is used for watching emulated memory.
+ // It's not related to timekeeping devices.
+ menu->addAction(tr("&Delete Watch"), this, [this, row] { DeleteWatchAndUpdate(row); });
+ menu->addAction(tr("&Add Memory Breakpoint"), this,
+ [this, row] { AddWatchBreakpoint(row); });
+ }
}
}
}
@@ -359,7 +366,7 @@ void WatchWidget::OnItemChanged(QTableWidgetItem* item)
{
case COLUMN_INDEX_LABEL:
if (item->text().isEmpty())
- DeleteWatch(row);
+ DeleteWatchAndUpdate(row);
else
PowerPC::debug_interface.UpdateWatchName(row, item->text().toStdString());
break;
@@ -422,10 +429,39 @@ void WatchWidget::LockWatchAddress(u32 address)
PowerPC::debug_interface.SetFramePatch(address, bytes);
}
+void WatchWidget::DeleteSelectedWatches()
+{
+ std::vector<int> row_indices;
+ for (const auto& index : m_table->selectionModel()->selectedRows())
+ {
+ const auto* item = m_table->item(index.row(), index.column());
+ const auto row_variant = item->data(Qt::UserRole);
+ if (row_variant.isNull())
+ continue;
+
+ row_indices.push_back(row_variant.toInt());
+ }
+
+ // Sort greatest to smallest, so we
+ // don't stomp on existing indices
+ std::sort(row_indices.begin(), row_indices.end(), std::greater{});
+ for (const int row : row_indices)
+ {
+ DeleteWatch(row);
+ }
+
+ Update();
+}
+
void WatchWidget::DeleteWatch(int row)
{
PowerPC::debug_interface.UnsetPatch(PowerPC::debug_interface.GetWatch(row).address);
PowerPC::debug_interface.RemoveWatch(row);
+}
+
+void WatchWidget::DeleteWatchAndUpdate(int row)
+{
+ DeleteWatch(row);
Update();
}
@@ -444,3 +480,41 @@ void WatchWidget::AddWatch(QString name, u32 addr)
PowerPC::debug_interface.SetWatch(addr, name.toStdString());
Update();
}
+
+void WatchWidget::LockSelectedWatches()
+{
+ for (const auto& index : m_table->selectionModel()->selectedRows())
+ {
+ const auto* item = m_table->item(index.row(), index.column());
+ const auto row_variant = item->data(Qt::UserRole);
+ if (row_variant.isNull())
+ continue;
+ const int row = row_variant.toInt();
+ const auto& watch = PowerPC::debug_interface.GetWatch(row);
+ if (watch.locked)
+ continue;
+ PowerPC::debug_interface.UpdateWatchLockedState(row, true);
+ LockWatchAddress(watch.address);
+ }
+
+ Update();
+}
+
+void WatchWidget::UnlockSelectedWatches()
+{
+ for (const auto& index : m_table->selectionModel()->selectedRows())
+ {
+ const auto* item = m_table->item(index.row(), index.column());
+ const auto row_variant = item->data(Qt::UserRole);
+ if (row_variant.isNull())
+ continue;
+ const int row = row_variant.toInt();
+ const auto& watch = PowerPC::debug_interface.GetWatch(row);
+ if (!watch.locked)
+ continue;
+ PowerPC::debug_interface.UpdateWatchLockedState(row, false);
+ PowerPC::debug_interface.UnsetPatch(watch.address);
+ }
+
+ Update();
+}
diff --git a/Source/Core/DolphinQt/Debugger/WatchWidget.h b/Source/Core/DolphinQt/Debugger/WatchWidget.h
index bf5bc5f209..22aefb9b0e 100644
--- a/Source/Core/DolphinQt/Debugger/WatchWidget.h
+++ b/Source/Core/DolphinQt/Debugger/WatchWidget.h
@@ -47,10 +47,14 @@ private:
void ShowContextMenu();
void OnItemChanged(QTableWidgetItem* item);
void LockWatchAddress(u32 address);
+ void DeleteSelectedWatches();
void DeleteWatch(int row);
+ void DeleteWatchAndUpdate(int row);
void AddWatchBreakpoint(int row);
void ShowInMemory(int row);
void UpdateIcons();
+ void LockSelectedWatches();
+ void UnlockSelectedWatches();
QAction* m_new;
QAction* m_delete;