Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 52 additions & 4 deletions gui/qt/debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include <QtWidgets/QToolTip>
#include <QtCore/QFileInfo>
#include <QtCore/QStringList>
#include <QtCore/QRegularExpression>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QInputDialog>
Expand All @@ -41,6 +42,7 @@
#include <QtGui/QScreen>
#include <algorithm>
#include <array>
#include <ranges>

#ifdef _MSC_VER
#include <direct.h>
Expand Down Expand Up @@ -222,6 +224,7 @@ void MainWindow::debugImportFile(const QString &file) {

disasm.map.clear();
disasm.reverse.clear();
markDisasmGotoCompletionsDirty();
for (QString &equFile : m_equateFiles) {
equatesAddFile(equFile);
}
Expand Down Expand Up @@ -1887,6 +1890,7 @@ void MainWindow::updateLabels() {
void MainWindow::equatesRefresh() {
disasm.map.clear();
disasm.reverse.clear();
markDisasmGotoCompletionsDirty();
for (QString &file : m_equateFiles) {
equatesAddFile(file);
}
Expand Down Expand Up @@ -1984,11 +1988,14 @@ void MainWindow::equatesAddEquate(const QString &name, uint32_t address) {
if (!equatesAddEquateInternal(name, address)) {
return;
}
markDisasmGotoCompletionsDirty();
uint8_t *ptr = static_cast<uint8_t *>(phys_mem_ptr(address - 4, 9));
if (ptr && ptr[4] == 0xC3 && (ptr[0] == 0xC3 || ptr[8] == 0xC3)) { // jump table?
uint32_t address2 = ptr[5] | ptr[6] << 8 | ptr[7] << 16;
if (phys_mem_ptr(address2, 1)) {
equatesAddEquateInternal(QStringLiteral("_") + name, address2);
if (equatesAddEquateInternal(QStringLiteral("_") + name, address2)) {
markDisasmGotoCompletionsDirty();
}
}
}
}
Expand Down Expand Up @@ -2148,14 +2155,15 @@ void MainWindow::gotoPressed() {
m_gotoAddr = m_disasm->getSelectedAddr();
}

GotoDialog dlg(m_gotoAddr, m_disasmGotoHistory, this);
GotoDialog dlg(m_gotoAddr, m_disasmGotoHistory, disasmGotoCompletions(), this);
if (dlg.exec() == QDialog::Accepted) {
QString typed = dlg.text().trimmed();
bool ok = false;
QString resolved = resolveAddressOrEquate(typed, &ok);
if (ok) {
m_gotoAddr = typed;
disasmUpdateAddr(hex2int(resolved), false);
// changes are routed through here to make sure history is updated for fwd and back
gotoDisasmAddr(static_cast<uint32_t>(hex2int(resolved)));

auto &hist = m_disasmGotoHistory;
std::erase_if(hist, [&](const QString &s){ return s.compare(typed, Qt::CaseInsensitive) == 0; });
Expand Down Expand Up @@ -2226,6 +2234,46 @@ QAction *MainWindow::gotoMemAction(QMenu *menu, bool vat) const {
return gotoMem;
}

const QStringList &MainWindow::disasmGotoCompletions() {
if (!m_disasmGotoCompletionsDirty) {
return m_disasmGotoCompletions;
}

m_disasmGotoCompletionsDirty = false;

QStringList completions;
static constexpr std::array kRegisterAliases = {
"AF"_L1, "HL"_L1, "DE"_L1, "BC"_L1, "IX"_L1, "IY"_L1,
"AF'"_L1, "HL'"_L1, "DE'"_L1, "BC'"_L1, "SPL"_L1, "SPS"_L1, "PC"_L1
};

completions.reserve(static_cast<int>(disasm.map.size() + kRegisterAliases.size()));

for (const auto &name : disasm.map | std::views::values) {
const auto qname = QString::fromStdString(name);
if (!completions.contains(qname, Qt::CaseInsensitive)) {
completions.append(qname);
}
}

for (const auto alias : kRegisterAliases) {
if (!completions.contains(alias)) {
completions.append(QString(alias));
}
}

std::ranges::sort(completions, [](const QString &lhs, const QString &rhs) {
return lhs.localeAwareCompare(rhs) < 0;
});

m_disasmGotoCompletions = std::move(completions);
return m_disasmGotoCompletions;
}

void MainWindow::markDisasmGotoCompletionsDirty() {
m_disasmGotoCompletionsDirty = true;
}

void MainWindow::handleCtrlClickText(QPlainTextEdit *edit) {
if (QApplication::keyboardModifiers().testFlag(Qt::ControlModifier)) {
bool ok = true;
Expand Down Expand Up @@ -2352,7 +2400,7 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *e) {
return true;
}
}

// Mouse back/forward in Disassembly view
if (obj == m_disasm && e->type() == QEvent::MouseButtonPress) {
auto *me = static_cast<QMouseEvent*>(e);
Expand Down
17 changes: 17 additions & 0 deletions gui/qt/gotodialog.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
#include "gotodialog.h"

#include <QtWidgets/QComboBox>
#include <QtWidgets/QCompleter>
#include <QtWidgets/QDialogButtonBox>
#include <QtWidgets/QLabel>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QSizePolicy>
#include <QtWidgets/QLineEdit>
#include <QtCore/Qt>

GotoDialog::GotoDialog(const QString &seed,
const std::vector<QString> &history,
const QStringList &completions,
QWidget *parent)
: QDialog(parent) {
setWindowTitle(tr("Goto"));
Expand All @@ -18,6 +22,19 @@ GotoDialog::GotoDialog(const QString &seed,

m_combo = new QComboBox(this); // NOLINT: Qt parent-ownership handles deletion
m_combo->setEditable(true);
m_combo->setInsertPolicy(QComboBox::NoInsert);

if (!completions.isEmpty()) {
auto *completer = new QCompleter(completions, m_combo); // NOLINT: Qt parent-ownership handles deletion
completer->setCaseSensitivity(Qt::CaseInsensitive);
completer->setFilterMode(Qt::MatchContains);
completer->setCompletionMode(QCompleter::PopupCompletion);
if (auto *lineEdit = m_combo->lineEdit()) {
lineEdit->setCompleter(completer);
} else {
m_combo->setCompleter(completer);
}
}

for (const QString &h : history) {
m_combo->addItem(h);
Expand Down
2 changes: 2 additions & 0 deletions gui/qt/gotodialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <QtWidgets/QDialog>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <vector>

QT_BEGIN_NAMESPACE
Expand All @@ -14,6 +15,7 @@ class GotoDialog : public QDialog {
public:
explicit GotoDialog(const QString &seed,
const std::vector<QString> &history,
const QStringList &completions = {},
QWidget *parent = nullptr);

[[nodiscard]] QString text() const;
Expand Down
6 changes: 6 additions & 0 deletions gui/qt/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <QtWidgets/QTableWidgetItem>
#include <QtWidgets/QPlainTextEdit>
#include <QtWidgets/QFileDialog>
#include <QtCore/QStringList>
#include <QtCore/QSettings>
#include <QtCore/QThread>
#include <QtCore/QTimer>
Expand Down Expand Up @@ -366,6 +367,8 @@ private slots:
void gotoMemAddr(uint32_t addr);
HexWidget *gotoMemAddrNoRaise(uint32_t addr);
QAction *gotoMemAction(QMenu *menu, bool vat = false) const;
const QStringList &disasmGotoCompletions();
void markDisasmGotoCompletionsDirty();

void handleCtrlClickText(QPlainTextEdit *edit);
void handleCtrlClickLine(QLineEdit *edit);
Expand Down Expand Up @@ -736,6 +739,9 @@ private slots:

std::vector<QString> m_memGotoHistory;

QStringList m_disasmGotoCompletions;
bool m_disasmGotoCompletionsDirty = true;

QString m_pathConfig;
QMenu *m_menuDocks;
QMenu *m_menuDebug;
Expand Down
7 changes: 4 additions & 3 deletions gui/qt/memorywidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <QtGui/QClipboard>
#include <QtCore/QFileInfo>
#include <QtCore/QRegularExpression>
#include <QtCore/QStringList>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QInputDialog>
#include <algorithm>
Expand Down Expand Up @@ -107,7 +108,7 @@ void MainWindow::memUpdateEdit(HexWidget *edit, bool force) {
}

void MainWindow::flashGotoPressed() {
if (GotoDialog dlg(m_flashGotoAddr, m_memGotoHistory, this); dlg.exec() == QDialog::Accepted) {
if (GotoDialog dlg(m_flashGotoAddr, m_memGotoHistory, QStringList(), this); dlg.exec() == QDialog::Accepted) {
const QString typed = dlg.text().trimmed();
bool ok = false;
const QString resolved = resolveAddressOrEquate(typed, &ok);
Expand All @@ -127,7 +128,7 @@ void MainWindow::flashGotoPressed() {
}

void MainWindow::ramGotoPressed() {
GotoDialog dlg(m_RamGotoAddr, m_memGotoHistory, this);
GotoDialog dlg(m_RamGotoAddr, m_memGotoHistory, QStringList(), this);
if (dlg.exec() == QDialog::Accepted) {
const QString typed = dlg.text().trimmed();
bool ok = false;
Expand Down Expand Up @@ -216,7 +217,7 @@ void MainWindow::memGotoEdit(HexWidget *edit) {
return;
}

GotoDialog dlg(m_memGotoAddr, m_memGotoHistory, this);
GotoDialog dlg(m_memGotoAddr, m_memGotoHistory, QStringList(), this);
if (dlg.exec() == QDialog::Accepted) {
QString typed = dlg.text().trimmed();
bool ok = false;
Expand Down
Loading