Implement direct address jumping in memory view
MODIFY
RISC-V-sim.pro
RISC-V-sim.pro
@@ -23,7 +23,9 @@ SOURCES += src/main.cpp \
src/cacheinspector.cpp \
src/memorymodel.cpp \
src/memorydisplaydelegate.cpp \
- src/memoryview.cpp
+ src/memoryview.cpp \
+ src/gotocombobox.cpp \
+ src/addressdialog.cpp
HEADERS += \
src/parser.h \
@@ -43,7 +45,10 @@ HEADERS += \
src/cacheinspector.h \
src/memorymodel.h \
src/memorydisplaydelegate.h \
- src/memoryview.h
+ src/memoryview.h \
+ src/gotocombobox.h \
+ src/addressdialog.h \
+ src/addressdialog.h
FORMS += \
src/mainwindow.ui \
@@ -53,7 +58,8 @@ FORMS += \
src/memorytab.ui \
src/cachetab.ui \
src/cachesetupwidget.ui \
- src/cacheinspector.ui
+ src/cacheinspector.ui \
+ src/addressdialog.ui
# External

ADD
src/addressdialog.cpp
+#include "addressdialog.h"
+#include "ui_addressdialog.h"
+
+#include <QPushButton>
+
+AddressDialog::AddressDialog(QWidget *parent)
+ : QDialog(parent), m_ui(new Ui::AddressDialog) {
+ m_ui->setupUi(this);
+
+ // set input range
+ m_ui->address->setInputMask("hhhhhhhh");
+
+ connect(m_ui->address, &QLineEdit::textChanged, this,
+ &AddressDialog::validateTargetAddress);
+}
+
+AddressDialog::~AddressDialog() { delete m_ui; }
+
+void AddressDialog::validateTargetAddress(const QString &address) {
+ bool ok;
+ uint32_t value = address.toUInt(&ok, 16);
+ if (ok && value >= 0 && value <= (long long)4294967295) {
+ m_address = value;
+ m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
+ } else {
+ m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
+ }
+}

ADD
src/addressdialog.h
+#ifndef ADDRESSDIALOG_H
+#define ADDRESSDIALOG_H
+
+#include <QDialog>
+
+namespace Ui {
+class AddressDialog;
+}
+
+class AddressDialog : public QDialog {
+ Q_OBJECT
+
+public:
+ friend class GoToComboBox;
+ explicit AddressDialog(QWidget *parent = 0);
+ ~AddressDialog();
+
+ uint32_t getAddress() const { return m_address; }
+
+private:
+ Ui::AddressDialog *m_ui;
+ uint32_t m_address = 0;
+ void validateTargetAddress(const QString &address);
+};
+
+#endif // ADDRESSDIALOG_H

ADD
src/addressdialog.ui
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AddressDialog</class>
+ <widget class="QDialog" name="AddressDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>230</width>
+ <height>96</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Enter target address:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="address"/>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>AddressDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>AddressDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>

MODIFY
src/cacheinspector.cpp
src/cacheinspector.cpp
@@ -169,7 +169,7 @@ void CacheInspector::setupTemporalRatioPlot() {
for (int i = 0; i < 3; ++i) {
m_ui->temporalRatioPlot->addGraph();
- QColor color(QRgb(Colors::BerkeleyBlue));
+ QColor color = QColor(QRgb(Colors::BerkeleyBlue));
color.setAlpha(60 + 40 * i);
m_ui->temporalRatioPlot->graph()->setLineStyle(QCPGraph::lsLine);
m_ui->temporalRatioPlot->graph()->setPen(QPen(color.lighter(200)));

ADD
src/gotocombobox.cpp
+#include "gotocombobox.h"
+#include "addressdialog.h"
+
+#include <QAbstractItemView>
+#include <QEvent>
+#include <QLineEdit>
+#include <QMouseEvent>
+
+GoToComboBox::GoToComboBox(QWidget *parent) : QComboBox(parent) {
+ // Add default values to goto combobox. Order matters!
+ addItem("Select", 0);
+ addItem("Address...", 0);
+ addItem("Text", 0);
+ addItem("Stack", 0x7ffffff0);
+
+ // connect to a "signal filter"
+ connect(this, QOverload<int>::of(&GoToComboBox::activated), this,
+ &GoToComboBox::signalFilter);
+}
+
+void GoToComboBox::signalFilter(int index) {
+ // Get modifier keys
+ switch (index) {
+ case 0:
+ return; // "select" has been clicked
+ case 1: {
+ // Create goto-address dialog
+ AddressDialog dialog;
+ if (dialog.exec() == QDialog::Accepted) {
+ emit jumpToAddress(dialog.getAddress());
+ break;
+ }
+ }
+ default:
+ // All other indexes should just emit their data - which is their target
+ // address
+ emit jumpToAddress(itemData(index).toUInt());
+ break;
+ }
+
+ // revert selection to "Select"
+ blockSignals(true);
+ setCurrentIndex(0);
+ blockSignals(false);
+}
+
+ComboboxDelegate::ComboboxDelegate(QWidget *parent) : QItemDelegate(parent) {}
+
+void ComboboxDelegate::mousePressEvent(QMouseEvent *event) {
+ auto modifier = event->modifiers();
+ if (modifier == Qt::ShiftModifier) {
+ }
+}

ADD
src/gotocombobox.h
+#ifndef GOTOCOMBOBOX_H
+#define GOTOCOMBOBOX_H
+
+#include <QComboBox>
+#include <QItemDelegate>
+
+class ComboboxDelegate : public QItemDelegate {
+ Q_OBJECT
+public:
+ explicit ComboboxDelegate(QWidget *parent = nullptr);
+
+ void mousePressEvent(QMouseEvent *event);
+};
+
+class GoToComboBox : public QComboBox {
+ Q_OBJECT
+public:
+ explicit GoToComboBox(QWidget *parent = nullptr);
+
+signals:
+ void indexChanged();
+ void jumpToAddress(uint32_t address);
+
+public slots:
+
+private:
+ void signalFilter(int index);
+
+ // ComboboxDelegate m_delegate;
+};
+
+#endif // GOTOCOMBOBOX_H

MODIFY
src/memorytab.cpp
src/memorytab.cpp
@@ -17,11 +17,6 @@ MemoryTab::MemoryTab(QWidget *parent)
m_ui->memorydisplaytype->insertItem(0, type, displayTypes[type]);
}
- // Add goto values to goto combobox
- m_ui->gotoCombobox->addItem("Select", 0);
- m_ui->gotoCombobox->addItem("Text", 0);
- m_ui->gotoCombobox->addItem("Stack", 0x7ffffff0);
-
m_ui->registerdisplaytype->setCurrentIndex(displayTypeN::Hex);
m_ui->memorydisplaytype->setCurrentIndex(displayTypeN::Hex);
}
@@ -190,13 +185,9 @@ void MemoryTab::initializeMemoryView() {
m_ui->memoryView->setEditTriggers(QAbstractItemView::NoEditTriggers);
// Connect goto combobox
- connect(m_ui->gotoCombobox, &QComboBox::currentTextChanged, [=] {
- m_model->jumpToAddress(m_ui->gotoCombobox->currentData().toUInt());
- // Switch back to "select"
- m_ui->gotoCombobox->blockSignals(true);
- m_ui->gotoCombobox->setCurrentIndex(0);
- m_ui->gotoCombobox->blockSignals(false);
- });
+
+ connect(m_ui->gotoCombobox, &GoToComboBox::jumpToAddress, m_model,
+ &MemoryModel::jumpToAddress);
// Connect save address button
connect(m_ui->save, &QPushButton::clicked, this, &MemoryTab::saveAddress);

MODIFY
src/memorytab.ui
src/memorytab.ui
<x>0</x>
<y>0</y>
<width>298</width>
- <height>335</height>
+ <height>342</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<x>0</x>
<y>0</y>
<width>514</width>
- <height>335</height>
+ <height>342</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_6">
</widget>
</item>
<item>
- <widget class="QComboBox" name="gotoCombobox"/>
+ <widget class="GoToComboBox" name="gotoCombobox"/>
</item>
<item>
<widget class="QPushButton" name="memoryUp">
<extends>QTableView</extends>
<header>memoryview.h</header>
</customwidget>
+ <customwidget>
+ <class>GoToComboBox</class>
+ <extends>QComboBox</extends>
+ <header>gotocombobox.h</header>
+ </customwidget>
</customwidgets>
<resources/>
<connections/>

Implement direct address jumping in memory view