1
0
Fork 0
This commit is contained in:
Duncan Ogilvie 2019-01-20 20:46:16 +01:00
parent 661360bc68
commit 406b9349a1
No known key found for this signature in database
GPG Key ID: FC89E0AAA0C1AAD8
8 changed files with 100 additions and 9 deletions

View File

@ -385,7 +385,7 @@ void CPUDisassembly::setupRightClickContextMenu()
return DbgMemIsValidReadPtr(addr);
});
mMenuBuilder->addMenu(makeMenu(DIcon("label.png"), tr("Label")), labelMenu);
mMenuBuilder->addMenu(makeClickableMenu(DIcon("label.png"), tr("Label"), SLOT(setLabelSlot())), labelMenu);
QAction* traceRecordDisable = makeAction(DIcon("close-all-tabs.png"), tr("Disable"), SLOT(ActionTraceRecordDisableSlot()));
QAction* traceRecordEnableBit = makeAction(DIcon("bit.png"), tr("Bit"), SLOT(ActionTraceRecordBitSlot()));

View File

@ -13,6 +13,7 @@
#include "SelectFields.h"
#include "MiscUtil.h"
#include "ldconvert.h"
#include "ClickableMenuFilter.h"
int RegistersView::getEstimateHeight()
{
@ -2886,6 +2887,7 @@ void RegistersView::displayCustomContextMenuSlot(QPoint pos)
if(!DbgIsDebugging())
return;
QMenu wMenu(this);
wMenu.installEventFilter(new ClickableMenuFilter(&wMenu));
QMenu* followInDumpNMenu = nullptr;
const QAction* selectedAction = nullptr;
switch(wSIMDRegDispMode)
@ -2957,8 +2959,13 @@ void RegistersView::displayCustomContextMenuSlot(QPoint pos)
duint addr = (* ((duint*) registerValue(&wRegDumpStruct, mSelected)));
if(DbgMemIsValidReadPtr(addr))
{
wMenu.addAction(wCM_FollowInDump);
followInDumpNMenu = new QMenu(tr("Follow in &Dump"), &wMenu);
followInDumpNMenu->setProperty("clickable", QVariant(true));
connect(followInDumpNMenu->menuAction(), &QAction::triggered, [&](bool)
{
onFollowInDump();
//wMenu.close();
});
CreateDumpNMenu(followInDumpNMenu);
wMenu.addMenu(followInDumpNMenu);
wMenu.addAction(wCM_FollowInDisassembly);

View File

@ -61,17 +61,18 @@ public:
}
private:
inline QAction* connectAction(QAction* action, const char* slot)
template<class T> // lambda or base member pointer
inline QAction* connectAction(QAction* action, T slot)
{
QObject::connect(action, SIGNAL(triggered(bool)), getBase(), slot);
//in case of a lambda getBase() is used as the 'context' object and not the 'receiver'
QObject::connect(action, &QAction::triggered, getBase(), slot);
return action;
}
template<class T> // lambda or base member pointer
inline QAction* connectAction(QAction* action, T callback)
template<>
inline QAction* connectAction(QAction* action, const char* slot)
{
//in case of a lambda getBase() is used as the 'context' object and not the 'receiver'
QObject::connect(action, &QAction::triggered, getBase(), callback);
QObject::connect(action, SIGNAL(triggered(bool)), getBase(), slot);
return action;
}
@ -90,6 +91,21 @@ private:
return action;
}
template<class T> // lambda or base member pointer
inline QMenu* connectClickableMenu(QMenu* menu, T slot)
{
//in case of a lambda getBase() is used as the 'context' object and not the 'receiver'
QObject::connect(menu->menuAction(), &QAction::triggered, getBase(), slot);
return menu;
}
template<>
inline QMenu* connectClickableMenu(QMenu* menu, const char* slot)
{
QObject::connect(menu->menuAction(), SIGNAL(triggered(bool)), getBase(), slot);
return menu;
}
protected:
inline ActionHelperFuncs getActionHelperFuncs()
{
@ -149,6 +165,20 @@ protected:
return menu;
}
template<typename T>
inline QMenu* makeClickableMenu(const QString & title, T slot)
{
return connectClickableMenu(new QMenu(title, getBase()), slot);
}
template<typename T>
inline QMenu* makeClickableMenu(const QIcon & icon, const QString & title, T slot)
{
QMenu* menu = new QMenu(title, getBase());
menu->setIcon(icon);
return connectClickableMenu(menu, slot);
}
template<typename T>
inline QAction* makeAction(const QString & text, T slot)
{

View File

@ -0,0 +1,31 @@
#include "ClickableMenuFilter.h"
#include <QEvent>
#include <QMouseEvent>
#include <QMenu>
#include <QTimer>
ClickableMenuFilter::ClickableMenuFilter(QObject* parent)
: QObject(parent)
{
}
bool ClickableMenuFilter::eventFilter(QObject* watched, QEvent* event)
{
if(event->type() == QEvent::MouseButtonRelease)
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
if(mouseEvent->button() == Qt::LeftButton)
{
QMenu* menu = qobject_cast<QMenu*>(watched);
QAction* action = menu->actionAt(mouseEvent->pos());
QMenu* actionMenu = action->menu();
if(action && actionMenu && !actionMenu->property("clickable").isNull())
{
action->trigger();
menu->close();
return true;
}
}
}
return QObject::eventFilter(watched, event);
}

View File

@ -0,0 +1,17 @@
#ifndef CLICKABLEMENUFILTER_H
#define CLICKABLEMENUFILTER_H
#include <QObject>
class ClickableMenuFilter : public QObject
{
Q_OBJECT
public:
explicit ClickableMenuFilter(QObject* parent = nullptr);
protected:
bool eventFilter(QObject* watched, QEvent* event) override;
};
#endif //CLICKABLEMENUFILTER_H

View File

@ -65,6 +65,7 @@ QString MenuBuilder::getText(size_t id) const
*/
bool MenuBuilder::build(QMenu* menu) const
{
menu->installEventFilter(_clickableMenuFilter);
if(_callback && !_callback(menu))
return false;
QMenu* submenu;

View File

@ -4,6 +4,7 @@
#include <QAction>
#include <QMenu>
#include <functional>
#include "ClickableMenuFilter.h"
/**
* @brief The MenuBuilder class implements the dynamic context menu system for many views.
@ -16,7 +17,8 @@ public:
inline MenuBuilder(QObject* parent, BuildCallback callback = nullptr)
: QObject(parent),
_callback(callback)
_callback(callback),
_clickableMenuFilter(new ClickableMenuFilter(this))
{
}
@ -116,6 +118,7 @@ private:
BuildCallback _callback;
QString id;
std::vector<Container> _containers;
ClickableMenuFilter* _clickableMenuFilter;
};
#endif // MENUBUILDER

View File

@ -170,6 +170,7 @@ SOURCES += \
Src/Gui/LogStatusLabel.cpp \
Src/Gui/DebugStatusLabel.cpp \
Src/Utils/MenuBuilder.cpp \
Src/Utils/ClickableMenuFilter.cpp \
Src/Gui/StructWidget.cpp \
Src/Gui/CustomizeMenuDialog.cpp \
Src/Gui/SimpleTraceDialog.cpp \
@ -263,6 +264,7 @@ HEADERS += \
Src/Gui/NotesManager.h \
Src/Gui/NotepadView.h \
Src/Utils/MenuBuilder.h \
Src/Utils/ClickableMenuFilter.h \
Src/Gui/CPUMultiDump.h \
Src/Gui/AssembleDialog.h \
Src/Gui/SEHChainView.h \