diff --git a/Source/GUI/MemWatcher/Dialogs/DlgAddWatchEntry.cpp b/Source/GUI/MemWatcher/Dialogs/DlgAddWatchEntry.cpp index e017e57..337509d 100644 --- a/Source/GUI/MemWatcher/Dialogs/DlgAddWatchEntry.cpp +++ b/Source/GUI/MemWatcher/Dialogs/DlgAddWatchEntry.cpp @@ -1,9 +1,12 @@ #include "DlgAddWatchEntry.h" +#include +#include #include #include #include #include +#include #include #include #include @@ -167,6 +170,10 @@ void DlgAddWatchEntry::fillFields(MemWatchEntry* entry) QLabel* lblAddressOfPath = new QLabel(); lblAddressOfPath->setText( QString::fromStdString(" -> " + m_entry->getAddressStringForPointerLevel(i + 1))); + lblAddressOfPath->setProperty("addr", m_entry->getAddressForPointerLevel(i + 1)); + lblAddressOfPath->setContextMenuPolicy(Qt::CustomContextMenu); + connect(lblAddressOfPath, &QWidget::customContextMenuRequested, this, + &DlgAddWatchEntry::onPointerOffsetContextMenuRequested); m_addressPath.append(lblAddressOfPath); m_offsetsLayout->addWidget(lblLevel, i, 0); m_offsetsLayout->addWidget(txbOffset, i, 1); @@ -190,6 +197,12 @@ void DlgAddWatchEntry::addPointerOffset() QLineEdit* txbOffset = new QLineEdit(); m_offsets.append(txbOffset); QLabel* lblAddressOfPath = new QLabel(" -> "); + lblAddressOfPath->setText( + QString::fromStdString(" -> " + m_entry->getAddressStringForPointerLevel(level + 1))); + lblAddressOfPath->setProperty("addr", m_entry->getAddressForPointerLevel(level + 1)); + lblAddressOfPath->setContextMenuPolicy(Qt::CustomContextMenu); + connect(lblAddressOfPath, &QWidget::customContextMenuRequested, this, + &DlgAddWatchEntry::onPointerOffsetContextMenuRequested); m_addressPath.append(lblAddressOfPath); m_offsetsLayout->addWidget(lblLevel, level, 0); m_offsetsLayout->addWidget(txbOffset, level, 1); @@ -385,9 +398,10 @@ void DlgAddWatchEntry::updatePreview() for (int i = 0; i < level; ++i) { QLabel* lblAddressOfPath = - static_cast(m_offsetsLayout->itemAtPosition(i, 2)->widget()); + qobject_cast(m_offsetsLayout->itemAtPosition(i, 2)->widget()); lblAddressOfPath->setText( QString::fromStdString(" -> " + m_entry->getAddressStringForPointerLevel(i + 1))); + lblAddressOfPath->setProperty("addr", m_entry->getAddressForPointerLevel(i + 1)); } } } @@ -424,3 +438,23 @@ MemWatchEntry* DlgAddWatchEntry::stealEntry() m_entry = nullptr; return entry; } + +void DlgAddWatchEntry::onPointerOffsetContextMenuRequested(const QPoint& pos) +{ + QLabel* const lbl = qobject_cast(sender()); + + QMenu* const contextMenu = new QMenu(this); + QAction* const copyAddr = new QAction(tr("&Copy Address"), this); + + const QString text{QString::number(lbl->property("addr").toUInt(), 16).toUpper()}; + connect(copyAddr, &QAction::triggered, this, + [text] { QApplication::clipboard()->setText(text); }); + contextMenu->addAction(copyAddr); + + if (!lbl->property("addr").toUInt()) + { + copyAddr->setEnabled(false); + } + + contextMenu->popup(lbl->mapToGlobal(pos)); +} diff --git a/Source/GUI/MemWatcher/Dialogs/DlgAddWatchEntry.h b/Source/GUI/MemWatcher/Dialogs/DlgAddWatchEntry.h index b271ace..d5d940c 100644 --- a/Source/GUI/MemWatcher/Dialogs/DlgAddWatchEntry.h +++ b/Source/GUI/MemWatcher/Dialogs/DlgAddWatchEntry.h @@ -44,6 +44,7 @@ class DlgAddWatchEntry : public QDialog void addPointerOffset(); void removePointerOffset(); void removeAllPointerOffset(); + void onPointerOffsetContextMenuRequested(const QPoint& pos); MemWatchEntry* m_entry{}; AddressInputWidget* m_txbAddress{}; diff --git a/Source/GUI/MemWatcher/MemWatchWidget.cpp b/Source/GUI/MemWatcher/MemWatchWidget.cpp index 47397fb..0d9b08f 100644 --- a/Source/GUI/MemWatcher/MemWatchWidget.cpp +++ b/Source/GUI/MemWatcher/MemWatchWidget.cpp @@ -273,6 +273,40 @@ void MemWatchWidget::onMemWatchContextMenuRequested(const QPoint& pos) connect(copy, &QAction::triggered, this, [this] { copySelectedWatchesToClipBoard(); }); contextMenu->addAction(copy); + if (index.isValid()) + { + MemWatchEntry* const entry = m_watchModel->getEntryFromIndex(index); + if (entry->isBoundToPointer()) + { + QMenu* const copyAddrSubmenu = contextMenu->addMenu(tr("Copy add&ress...")); + QAction* const copyPointer = new QAction(tr("Copy &base address..."), this); + const QString addrString{QString::number(entry->getConsoleAddress(), 16).toUpper()}; + connect(copyPointer, &QAction::triggered, this, + [addrString] { QApplication::clipboard()->setText(addrString); }); + copyAddrSubmenu->addAction(copyPointer); + for (int i = 0; i < static_cast(entry->getPointerLevel()); ++i) + { + if (!entry->getAddressForPointerLevel(i + 1)) + break; + QAction* const copyAddrOfPointer = + new QAction(tr("Copy pointed address at &level %1...").arg(i + 1), this); + const QString addrString{ + QString::number(entry->getAddressForPointerLevel(i + 1), 16).toUpper()}; + connect(copyAddrOfPointer, &QAction::triggered, this, + [addrString] { QApplication::clipboard()->setText(addrString); }); + copyAddrSubmenu->addAction(copyAddrOfPointer); + } + } + else + { + QAction* const copyPointer = new QAction(tr("Copy add&ress"), this); + const QString addrString{QString::number(entry->getConsoleAddress(), 16).toUpper()}; + connect(copyPointer, &QAction::triggered, this, + [addrString] { QApplication::clipboard()->setText(addrString); }); + contextMenu->addAction(copyPointer); + } + } + QAction* paste = new QAction(tr("&Paste"), this); connect(paste, &QAction::triggered, this, [this, index] { pasteWatchFromClipBoard(index); }); contextMenu->addAction(paste);