1
0
Fork 0

GUI: context menu in graph

This commit is contained in:
Mr. eXoDia 2016-07-17 23:18:20 +02:00
parent 2361077011
commit 9101501b0e
6 changed files with 140 additions and 104 deletions

View File

@ -228,109 +228,8 @@ protected:
void invalidateCachedFont();
//action helpers
private:
struct ActionShortcut
{
QAction* action;
QString shortcut;
ActionShortcut(QAction* action, const char* shortcut)
: action(action),
shortcut(shortcut)
{
}
};
std::vector<ActionShortcut> actionShortcutPairs;
inline QAction* connectAction(QAction* action, const char* slot)
{
connect(action, SIGNAL(triggered(bool)), this, slot);
return action;
}
inline QAction* connectAction(QAction* action, QActionLambda::TriggerCallback callback)
{
auto lambda = new QActionLambda(action->parent(), callback);
connect(action, SIGNAL(triggered(bool)), lambda, SLOT(triggeredSlot()));
return action;
}
inline QAction* connectShortcutAction(QAction* action, const char* shortcut)
{
actionShortcutPairs.push_back(ActionShortcut(action, shortcut));
action->setShortcut(ConfigShortcut(shortcut));
action->setShortcutContext(Qt::WidgetShortcut);
addAction(action);
return action;
}
inline QAction* connectMenuAction(QMenu* menu, QAction* action)
{
menu->addAction(action);
return action;
}
protected:
inline QMenu* makeMenu(const QString & title)
{
return new QMenu(title, this);
}
inline QMenu* makeMenu(const QIcon & icon, const QString & title)
{
QMenu* menu = new QMenu(title, this);
menu->setIcon(icon);
return menu;
}
template<typename T>
inline QAction* makeAction(const QString & text, T slot)
{
return connectAction(new QAction(text, this), slot);
}
template<typename T>
inline QAction* makeAction(const QIcon & icon, const QString & text, T slot)
{
return connectAction(new QAction(icon, text, this), slot);
}
template<typename T>
inline QAction* makeShortcutAction(const QString & text, T slot, const char* shortcut)
{
return connectShortcutAction(makeAction(text, slot), shortcut);
}
template<typename T>
inline QAction* makeShortcutAction(const QIcon & icon, const QString & text, T slot, const char* shortcut)
{
return connectShortcutAction(makeAction(icon, text, slot), shortcut);
}
template<typename T>
inline QAction* makeMenuAction(QMenu* menu, const QString & text, T slot)
{
return connectMenuAction(menu, makeAction(text, slot));
}
template<typename T>
inline QAction* makeMenuAction(QMenu* menu, const QIcon & icon, const QString & text, T slot)
{
return connectMenuAction(menu, makeAction(icon, text, slot));
}
template<typename T>
inline QAction* makeShortcutMenuAction(QMenu* menu, const QString & text, T slot, const char* shortcut)
{
return connectShortcutAction(makeMenuAction(menu, text, slot), shortcut);
}
template<typename T>
inline QAction* makeShortcutMenuAction(QMenu* menu, const QIcon & icon, const QString & text, T slot, const char* shortcut)
{
return connectShortcutAction(makeMenuAction(menu, icon, text, slot), shortcut);
}
#include "ActionHelpers.h"
};
#endif // ABSTRACTTABLEVIEW_H

View File

@ -48,6 +48,9 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget* parent)
QSize areaSize = this->viewport()->size();
this->adjustSize(areaSize.width(), areaSize.height());
//Setup context menu
setupContextMenu();
//Connect to bridge
connect(Bridge::getBridge(), SIGNAL(loadGraph(BridgeCFGraphList*)), this, SLOT(loadGraphSlot(BridgeCFGraphList*)));
connect(Bridge::getBridge(), SIGNAL(graphAt(duint)), this, SLOT(graphAtSlot(duint)));
@ -459,7 +462,9 @@ void DisassemblerGraphView::mousePressEvent(QMouseEvent* event)
if((instr != 0) && (event->button() == Qt::RightButton))
{
//TODO: context menu
QMenu wMenu(this);
mMenuBuilder->build(&wMenu);
wMenu.exec(event->globalPos()); //execute context menu
}
}
@ -1235,3 +1240,22 @@ void DisassemblerGraphView::updateGraphSlot()
{
this->viewport()->update();
}
void DisassemblerGraphView::setupContextMenu()
{
mMenuBuilder = new MenuBuilder(this, [](QMenu*)
{
return DbgIsDebugging();
});
mMenuBuilder->addAction(makeAction(DIcon(QString("processor%1.png").arg(ArchValue("32", "64"))), tr("Follow in &Disassembler"), SLOT(followDisassemblerSlot())), [this](QMenu*)
{
return this->cur_instr != 0;
});
}
void DisassemblerGraphView::followDisassemblerSlot()
{
DbgCmdExec(QString("disasm %1").arg(ToPtrString(this->cur_instr)).toUtf8().constData());
emit showCpu();
}

View File

@ -17,6 +17,7 @@
#include "Bridge.h"
#include "QBeaEngine.h"
#include "CachedFontMetrics.h"
#include "MenuBuilder.h"
class DisassemblerGraphView : public QAbstractScrollArea
{
@ -227,6 +228,7 @@ public:
void prepareGraphNode(DisassemblerBlock & block);
void adjustGraphLayout(DisassemblerBlock & block, int col, int row);
void computeGraphLayout(DisassemblerBlock & block);
void setupContextMenu();
template<typename T>
using Matrix = std::vector<std::vector<T>>;
@ -246,6 +248,10 @@ public slots:
void loadGraphSlot(BridgeCFGraphList* graph);
void graphAtSlot(duint addr);
void updateGraphSlot();
void followDisassemblerSlot();
signals:
void showCpu();
private:
QString status;
@ -274,6 +280,10 @@ private:
std::vector<int> col_edge_x;
std::vector<int> row_edge_y;
CachedFontMetrics* mFontMetrics;
MenuBuilder* mMenuBuilder;
protected:
#include "ActionHelpers.h"
};
#endif // DISASSEMBLERGRAPHVIEW_H

View File

@ -260,6 +260,7 @@ MainWindow::MainWindow(QWidget* parent)
connect(mSymbolView, SIGNAL(showCpu()), this, SLOT(displayCpuWidget()));
connect(mSymbolView, SIGNAL(showReferences()), this, SLOT(displayReferencesWidget()));
connect(mReferenceManager, SIGNAL(showCpu()), this, SLOT(displayCpuWidget()));
connect(mGraphView, SIGNAL(showCpu()), this, SLOT(displayCpuWidget()));
connect(ui->actionReferences, SIGNAL(triggered()), this, SLOT(displayReferencesWidget()));
connect(ui->actionThreads, SIGNAL(triggered()), this, SLOT(displayThreadsWidget()));
connect(ui->actionSettings, SIGNAL(triggered()), this, SLOT(openSettings()));

View File

@ -0,0 +1,101 @@
struct ActionShortcut
{
QAction* action;
QString shortcut;
ActionShortcut(QAction* action, const char* shortcut)
: action(action),
shortcut(shortcut)
{
}
};
std::vector<ActionShortcut> actionShortcutPairs;
inline QAction* connectAction(QAction* action, const char* slot)
{
connect(action, SIGNAL(triggered(bool)), this, slot);
return action;
}
inline QAction* connectAction(QAction* action, QActionLambda::TriggerCallback callback)
{
auto lambda = new QActionLambda(action->parent(), callback);
connect(action, SIGNAL(triggered(bool)), lambda, SLOT(triggeredSlot()));
return action;
}
inline QAction* connectShortcutAction(QAction* action, const char* shortcut)
{
actionShortcutPairs.push_back(ActionShortcut(action, shortcut));
action->setShortcut(ConfigShortcut(shortcut));
action->setShortcutContext(Qt::WidgetShortcut);
addAction(action);
return action;
}
inline QAction* connectMenuAction(QMenu* menu, QAction* action)
{
menu->addAction(action);
return action;
}
inline QMenu* makeMenu(const QString & title)
{
return new QMenu(title, this);
}
inline QMenu* makeMenu(const QIcon & icon, const QString & title)
{
QMenu* menu = new QMenu(title, this);
menu->setIcon(icon);
return menu;
}
template<typename T>
inline QAction* makeAction(const QString & text, T slot)
{
return connectAction(new QAction(text, this), slot);
}
template<typename T>
inline QAction* makeAction(const QIcon & icon, const QString & text, T slot)
{
return connectAction(new QAction(icon, text, this), slot);
}
template<typename T>
inline QAction* makeShortcutAction(const QString & text, T slot, const char* shortcut)
{
return connectShortcutAction(makeAction(text, slot), shortcut);
}
template<typename T>
inline QAction* makeShortcutAction(const QIcon & icon, const QString & text, T slot, const char* shortcut)
{
return connectShortcutAction(makeAction(icon, text, slot), shortcut);
}
template<typename T>
inline QAction* makeMenuAction(QMenu* menu, const QString & text, T slot)
{
return connectMenuAction(menu, makeAction(text, slot));
}
template<typename T>
inline QAction* makeMenuAction(QMenu* menu, const QIcon & icon, const QString & text, T slot)
{
return connectMenuAction(menu, makeAction(icon, text, slot));
}
template<typename T>
inline QAction* makeShortcutMenuAction(QMenu* menu, const QString & text, T slot, const char* shortcut)
{
return connectShortcutAction(makeMenuAction(menu, text, slot), shortcut);
}
template<typename T>
inline QAction* makeShortcutMenuAction(QMenu* menu, const QIcon & icon, const QString & text, T slot, const char* shortcut)
{
return connectShortcutAction(makeMenuAction(menu, icon, text, slot), shortcut);
}

View File

@ -268,7 +268,8 @@ HEADERS += \
Src/Gui/WatchView.h \
Src/Gui/FavouriteTools.h \
Src/Gui/BrowseDialog.h \
Src/Gui/DisassemblerGraphView.h
Src/Gui/DisassemblerGraphView.h \
Src/Utils/ActionHelpers.h
FORMS += \