Rewrite raise memory widget functionality (#1654)

* Seperate seek from seeking and changing focused widget.
* Change memory widget priorities
* Add Show in context menu
This commit is contained in:
karliss 2019-07-19 22:21:12 +03:00 committed by GitHub
parent 914b35e637
commit 6c40191cce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 307 additions and 142 deletions

View File

@ -628,25 +628,38 @@ void CutterCore::seek(ut64 offset)
} }
cmd(QString("s %1").arg(offset)); cmd(QString("s %1").arg(offset));
// cmd already does emit seekChanged(core_->offset); // cmd already does emit seekChanged(core_->offset);
triggerRaisePrioritizedMemoryWidget(); }
void CutterCore::showMemoryWidget()
{
emit showMemoryWidgetRequested();
}
void CutterCore::seekAndShow(ut64 offset)
{
seek(offset);
showMemoryWidget();
}
void CutterCore::seekAndShow(QString offset)
{
seek(offset);
showMemoryWidget();
} }
void CutterCore::seek(QString thing) void CutterCore::seek(QString thing)
{ {
cmdRaw(QString("s %1").arg(thing)); cmdRaw(QString("s %1").arg(thing));
triggerRaisePrioritizedMemoryWidget();
} }
void CutterCore::seekPrev() void CutterCore::seekPrev()
{ {
cmd("s-"); cmd("s-");
triggerRaisePrioritizedMemoryWidget();
} }
void CutterCore::seekNext() void CutterCore::seekNext()
{ {
cmd("s+"); cmd("s+");
triggerRaisePrioritizedMemoryWidget();
} }
void CutterCore::updateSeek() void CutterCore::updateSeek()
@ -1116,7 +1129,7 @@ void CutterCore::attachDebug(int pid)
// attach to process with dbg plugin // attach to process with dbg plugin
cmd("o-*; e cfg.debug = true; o+ dbg://" + QString::number(pid)); cmd("o-*; e cfg.debug = true; o+ dbg://" + QString::number(pid));
QString programCounterValue = cmd("dr?`drn PC`").trimmed(); QString programCounterValue = cmd("dr?`drn PC`").trimmed();
seek(programCounterValue); seekAndShow(programCounterValue);
emit registersChanged(); emit registersChanged();
if (!currentlyDebugging || !currentlyEmulating) { if (!currentlyDebugging || !currentlyEmulating) {
// prevent register flags from appearing during debug/emul // prevent register flags from appearing during debug/emul
@ -1141,7 +1154,7 @@ void CutterCore::stopDebug()
} else { } else {
cmd("dk 9; oo; .ar-"); cmd("dk 9; oo; .ar-");
} }
seek(offsetPriorDebugging); seekAndShow(offsetPriorDebugging);
setConfig("asm.flags", true); setConfig("asm.flags", true);
setConfig("io.cache", false); setConfig("io.cache", false);
currentlyDebugging = false; currentlyDebugging = false;
@ -1185,7 +1198,7 @@ void CutterCore::continueUntilCall()
cmd("dcc"); cmd("dcc");
} }
QString programCounterValue = cmd("dr?`drn PC`").trimmed(); QString programCounterValue = cmd("dr?`drn PC`").trimmed();
seek(programCounterValue); seekAndShow(programCounterValue);
emit registersChanged(); emit registersChanged();
} }
} }
@ -1199,7 +1212,7 @@ void CutterCore::continueUntilSyscall()
cmd("dcs"); cmd("dcs");
} }
QString programCounterValue = cmd("dr?`drn PC`").trimmed(); QString programCounterValue = cmd("dr?`drn PC`").trimmed();
seek(programCounterValue); seekAndShow(programCounterValue);
emit registersChanged(); emit registersChanged();
} }
} }
@ -1209,7 +1222,7 @@ void CutterCore::stepDebug()
if (currentlyDebugging) { if (currentlyDebugging) {
cmdEsil("ds"); cmdEsil("ds");
QString programCounterValue = cmd("dr?`drn PC`").trimmed(); QString programCounterValue = cmd("dr?`drn PC`").trimmed();
seek(programCounterValue); seekAndShow(programCounterValue);
emit registersChanged(); emit registersChanged();
} }
} }
@ -1219,7 +1232,7 @@ void CutterCore::stepOverDebug()
if (currentlyDebugging) { if (currentlyDebugging) {
cmdEsil("dso"); cmdEsil("dso");
QString programCounterValue = cmd("dr?`drn PC`").trimmed(); QString programCounterValue = cmd("dr?`drn PC`").trimmed();
seek(programCounterValue); seekAndShow(programCounterValue);
emit registersChanged(); emit registersChanged();
} }
} }
@ -1229,7 +1242,7 @@ void CutterCore::stepOutDebug()
if (currentlyDebugging) { if (currentlyDebugging) {
cmd("dsf"); cmd("dsf");
QString programCounterValue = cmd("dr?`drn PC`").trimmed(); QString programCounterValue = cmd("dr?`drn PC`").trimmed();
seek(programCounterValue); seekAndShow(programCounterValue);
emit registersChanged(); emit registersChanged();
} }
} }

View File

@ -35,7 +35,6 @@ public:
RCore *operator->() const; RCore *operator->() const;
}; };
class CutterCore: public QObject class CutterCore: public QObject
{ {
Q_OBJECT Q_OBJECT
@ -150,25 +149,25 @@ public:
void seekPrev(); void seekPrev();
void seekNext(); void seekNext();
void updateSeek(); void updateSeek();
/**
* @brief Raise a memory widget showing current offset, prefer last active
* memory widget.
*/
void showMemoryWidget();
/**
* @brief Seek to \p offset and raise a memory widget showing it.
* @param offset
*/
void seekAndShow(ut64 offset);
/**
* @brief \see CutterCore::show(ut64)
* @param thing - addressable expression
*/
void seekAndShow(QString thing);
RVA getOffset(); RVA getOffset();
RVA prevOpAddr(RVA startAddr, int count); RVA prevOpAddr(RVA startAddr, int count);
RVA nextOpAddr(RVA startAddr, int count); RVA nextOpAddr(RVA startAddr, int count);
/* Disassembly/Graph/Hexdump/Pseudocode view priority */
enum class MemoryWidgetType { Disassembly, Graph, Hexdump, Pseudocode };
MemoryWidgetType getMemoryWidgetPriority() const
{
return memoryWidgetPriority;
}
void setMemoryWidgetPriority(MemoryWidgetType type)
{
memoryWidgetPriority = type;
}
void triggerRaisePrioritizedMemoryWidget()
{
emit raisePrioritizedMemoryWidget(memoryWidgetPriority);
}
/* Math functions */ /* Math functions */
ut64 math(const QString &expr); ut64 math(const QString &expr);
ut64 num(const QString &expr); ut64 num(const QString &expr);
@ -444,16 +443,15 @@ signals:
*/ */
void seekChanged(RVA offset); void seekChanged(RVA offset);
void raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType type);
void changeDefinedView(); void changeDefinedView();
void changeDebugView(); void changeDebugView();
void newMessage(const QString &msg); void newMessage(const QString &msg);
void newDebugMessage(const QString &msg); void newDebugMessage(const QString &msg);
private: void showMemoryWidgetRequested();
MemoryWidgetType memoryWidgetPriority;
private:
QString notes; QString notes;
RCore *core_ = nullptr; RCore *core_ = nullptr;
AsyncTaskManager *asyncTaskManager; AsyncTaskManager *asyncTaskManager;

View File

@ -171,6 +171,9 @@ void MainWindow::initUI()
connect(core, SIGNAL(newDebugMessage(const QString &)), connect(core, SIGNAL(newDebugMessage(const QString &)),
this->consoleDock, SLOT(addDebugOutput(const QString &))); this->consoleDock, SLOT(addDebugOutput(const QString &)));
connect(core, &CutterCore::showMemoryWidgetRequested,
this, static_cast<void(MainWindow::*)()>(&MainWindow::showMemoryWidget));
updateTasksIndicator(); updateTasksIndicator();
connect(core->getAsyncTaskManager(), &AsyncTaskManager::tasksChanged, this, connect(core->getAsyncTaskManager(), &AsyncTaskManager::tasksChanged, this,
&MainWindow::updateTasksIndicator); &MainWindow::updateTasksIndicator);
@ -839,6 +842,14 @@ void MainWindow::updateDockActionsChecked()
} }
} }
MemoryWidgetType MainWindow::getMemoryWidgetTypeToRestore()
{
if (lastMemoryWidget) {
return lastMemoryWidget->getType();
}
return MemoryWidgetType::Disassembly;
}
QString MainWindow::getUniqueObjectName(const QString &widgetType) const QString MainWindow::getUniqueObjectName(const QString &widgetType) const
{ {
QStringList docks; QStringList docks;
@ -863,6 +874,90 @@ QString MainWindow::getUniqueObjectName(const QString &widgetType) const
return widgetType + ";" + QString::number(id); return widgetType + ";" + QString::number(id);
} }
void MainWindow::showMemoryWidget()
{
if (lastMemoryWidget) {
if (lastMemoryWidget->tryRaiseMemoryWidget()) {
return;
}
}
showMemoryWidget(MemoryWidgetType::Disassembly);
}
void MainWindow::showMemoryWidget(MemoryWidgetType type)
{
for (auto &dock : dockWidgets) {
if (auto memoryWidget = qobject_cast<MemoryDockWidget *>(dock)) {
if (memoryWidget->getType() == type && memoryWidget->getSeekable()->isSynchronized()) {
memoryWidget->tryRaiseMemoryWidget();
return;
}
}
}
auto memoryDockWidget = addNewMemoryWidget(type, Core()->getOffset());
memoryDockWidget->raiseMemoryWidget();
}
QMenu *MainWindow::createShowInMenu(QWidget *parent, RVA address)
{
QMenu *menu = new QMenu(parent);
for (auto &dock : dockWidgets) {
if (auto memoryWidget = qobject_cast<MemoryDockWidget *>(dock)) {
QAction *action = new QAction(memoryWidget->windowTitle(), menu);
connect(action, &QAction::triggered, this, [this, memoryWidget, address](){
memoryWidget->getSeekable()->seek(address);
memoryWidget->raiseMemoryWidget();
});
menu->addAction(action);
}
}
menu->addSeparator();
auto createAddNewWidgetAction = [this, menu, address](QString label, MemoryWidgetType type) {
QAction *action = new QAction(label, menu);
connect(action, &QAction::triggered, this, [this, address, type](){
addNewMemoryWidget(type, address, true);
});
menu->addAction(action);
};
createAddNewWidgetAction(tr("New disassembly"), MemoryWidgetType::Disassembly);
createAddNewWidgetAction(tr("New graph"), MemoryWidgetType::Graph);
createAddNewWidgetAction(tr("New hexdump"), MemoryWidgetType::Hexdump);
return menu;
}
void MainWindow::setCurrentMemoryWidget(MemoryDockWidget *memoryWidget)
{
if (memoryWidget->getSeekable()->isSynchronized()) {
lastMemoryWidget = memoryWidget;
}
}
MemoryDockWidget *MainWindow::addNewMemoryWidget(MemoryWidgetType type, RVA address,
bool synchronized)
{
MemoryDockWidget *memoryWidget = nullptr;
switch (type) {
case MemoryWidgetType::Graph:
memoryWidget = new GraphWidget(this);
break;
case MemoryWidgetType::Hexdump:
memoryWidget = new HexdumpWidget(this);
break;
case MemoryWidgetType::Disassembly:
memoryWidget = new DisassemblyWidget(this);
break;
case MemoryWidgetType::Pseudocode:
memoryWidget = new PseudocodeWidget(this);
break;
}
auto seekable = memoryWidget->getSeekable();
seekable->setSynchronization(synchronized);
seekable->seek(address);
addExtraWidget(memoryWidget);
return memoryWidget;
}
void MainWindow::initCorners() void MainWindow::initCorners()
{ {
// TODO: Allow the user to select this option visually in the GUI settings // TODO: Allow the user to select this option visually in the GUI settings
@ -892,9 +987,21 @@ void MainWindow::addWidget(QDockWidget* widget)
} }
} }
void MainWindow::addMemoryDockWidget(MemoryDockWidget *widget)
{
connect(widget, &QDockWidget::visibilityChanged, this, [this, widget](bool visibility) {
if (visibility) {
setCurrentMemoryWidget(widget);
}
});
}
void MainWindow::removeWidget(QDockWidget *widget) void MainWindow::removeWidget(QDockWidget *widget)
{ {
dockWidgets.removeAll(widget); dockWidgets.removeAll(widget);
if (lastMemoryWidget == widget) {
lastMemoryWidget = nullptr;
}
} }
void MainWindow::updateDockActionChecked(QAction *action) void MainWindow::updateDockActionChecked(QAction *action)
@ -968,11 +1075,11 @@ void MainWindow::resetToDefaultLayout()
void MainWindow::resetToDebugLayout() void MainWindow::resetToDebugLayout()
{ {
CutterCore::MemoryWidgetType memType = core->getMemoryWidgetPriority(); MemoryWidgetType memType = getMemoryWidgetTypeToRestore();
hideAllDocks(); hideAllDocks();
restoreDocks(); restoreDocks();
showDebugDocks(); showDebugDocks();
core->raisePrioritizedMemoryWidget(memType); showMemoryWidget(memType);
auto restoreStackDock = qhelpers::forceWidth(stackDock->widget(), 400); auto restoreStackDock = qhelpers::forceWidth(stackDock->widget(), 400);
qApp->processEvents(); qApp->processEvents();
@ -981,13 +1088,13 @@ void MainWindow::resetToDebugLayout()
void MainWindow::restoreDebugLayout() void MainWindow::restoreDebugLayout()
{ {
CutterCore::MemoryWidgetType memType = core->getMemoryWidgetPriority(); MemoryWidgetType memType = getMemoryWidgetTypeToRestore();
bool isMaxim = isMaximized(); bool isMaxim = isMaximized();
hideAllDocks(); hideAllDocks();
restoreDocks(); restoreDocks();
showDebugDocks(); showDebugDocks();
readDebugSettings(); readDebugSettings();
core->raisePrioritizedMemoryWidget(memType); showMemoryWidget(memType);
if (isMaxim) { if (isMaxim) {
showMaximized(); showMaximized();
} else { } else {
@ -1319,12 +1426,12 @@ void MainWindow::changeDebugView()
void MainWindow::changeDefinedView() void MainWindow::changeDefinedView()
{ {
saveDebugSettings(); saveDebugSettings();
CutterCore::MemoryWidgetType memType = core->getMemoryWidgetPriority(); MemoryWidgetType memType = getMemoryWidgetTypeToRestore();
hideAllDocks(); hideAllDocks();
restoreDocks(); restoreDocks();
readSettingsOrDefault(); readSettingsOrDefault();
enableDebugWidgetsMenu(false); enableDebugWidgetsMenu(false);
core->raisePrioritizedMemoryWidget(memType); showMemoryWidget(memType);
} }
void MainWindow::mousePressEvent(QMouseEvent *event) void MainWindow::mousePressEvent(QMouseEvent *event)

View File

@ -6,6 +6,7 @@
#include "dialogs/WelcomeDialog.h" #include "dialogs/WelcomeDialog.h"
#include "common/Configuration.h" #include "common/Configuration.h"
#include "common/InitialOptions.h" #include "common/InitialOptions.h"
#include "MemoryDockWidget.h"
#include <memory> #include <memory>
@ -54,7 +55,6 @@ namespace Ui {
class MainWindow; class MainWindow;
} }
class MainWindow : public QMainWindow class MainWindow : public QMainWindow
{ {
Q_OBJECT Q_OBJECT
@ -95,8 +95,11 @@ public:
void refreshOmniBar(const QStringList &flags); void refreshOmniBar(const QStringList &flags);
void addWidget(QDockWidget *widget); void addWidget(QDockWidget *widget);
void addMemoryDockWidget(MemoryDockWidget *widget);
void removeWidget(QDockWidget *widget); void removeWidget(QDockWidget *widget);
void addExtraWidget(CutterDockWidget *extraDock); void addExtraWidget(CutterDockWidget *extraDock);
MemoryDockWidget *addNewMemoryWidget(MemoryWidgetType type, RVA address, bool synchronized = true);
void addPluginDockWidget(QDockWidget *dockWidget, QAction *action); void addPluginDockWidget(QDockWidget *dockWidget, QAction *action);
enum class MenuType { File, Edit, View, Windows, Debug, Help, Plugins }; enum class MenuType { File, Edit, View, Windows, Debug, Help, Plugins };
@ -112,6 +115,11 @@ public:
void messageBoxWarning(QString title, QString message); void messageBoxWarning(QString title, QString message);
QString getUniqueObjectName(const QString &widgetType) const; QString getUniqueObjectName(const QString &widgetType) const;
void showMemoryWidget();
void showMemoryWidget(MemoryWidgetType type);
QMenu *createShowInMenu(QWidget *parent, RVA address);
void setCurrentMemoryWidget(MemoryDockWidget* memoryWidget);
public slots: public slots:
void finalizeOpen(); void finalizeOpen();
@ -271,10 +279,14 @@ private:
void setOverviewData(); void setOverviewData();
bool isOverviewActive(); bool isOverviewActive();
MemoryWidgetType getMemoryWidgetTypeToRestore();
/** /**
* @brief Map from a widget type (e.g. DisassemblyWidget::getWidgetType()) to the respective contructor of the widget * @brief Map from a widget type (e.g. DisassemblyWidget::getWidgetType()) to the respective contructor of the widget
*/ */
QMap<QString, std::function<CutterDockWidget*(MainWindow*, QAction*)>> widgetTypeToConstructorMap; QMap<QString, std::function<CutterDockWidget*(MainWindow*, QAction*)>> widgetTypeToConstructorMap;
MemoryDockWidget* lastMemoryWidget = nullptr;
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H

View File

@ -67,7 +67,7 @@ void LinkTypeDialog::done(int r)
QDialog::done(r); QDialog::done(r);
// Seek to the specified address // Seek to the specified address
Core()->seek(address); Core()->seekAndShow(address);
// Refresh the views // Refresh the views
emit Core()->refreshCodeViews(); emit Core()->refreshCodeViews();

View File

@ -75,7 +75,7 @@ void XrefsDialog::on_fromTreeWidget_itemDoubleClicked(QTreeWidgetItem *item, int
Q_UNUSED(column); Q_UNUSED(column);
XrefDescription xref = item->data(0, Qt::UserRole).value<XrefDescription>(); XrefDescription xref = item->data(0, Qt::UserRole).value<XrefDescription>();
Core()->seek(xref.to); Core()->seekAndShow(xref.to);
this->close(); this->close();
} }
@ -84,7 +84,7 @@ void XrefsDialog::on_toTreeWidget_itemDoubleClicked(QTreeWidgetItem *item, int c
Q_UNUSED(column); Q_UNUSED(column);
XrefDescription xref = item->data(0, Qt::UserRole).value<XrefDescription>(); XrefDescription xref = item->data(0, Qt::UserRole).value<XrefDescription>();
Core()->seek(xref.from); Core()->seekAndShow(xref.from);
this->close(); this->close();
} }

View File

@ -9,6 +9,7 @@
#include "dialogs/SetToDataDialog.h" #include "dialogs/SetToDataDialog.h"
#include "dialogs/EditFunctionDialog.h" #include "dialogs/EditFunctionDialog.h"
#include "dialogs/LinkTypeDialog.h" #include "dialogs/LinkTypeDialog.h"
#include "MainWindow.h"
#include <QtCore> #include <QtCore>
#include <QShortcut> #include <QShortcut>
@ -17,10 +18,11 @@
#include <QApplication> #include <QApplication>
#include <QPushButton> #include <QPushButton>
DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent) DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent, MainWindow* mainWindow)
: QMenu(parent), : QMenu(parent),
offset(0), offset(0),
canCopy(false) canCopy(false),
mainWindow(mainWindow)
{ {
initAction(&actionCopy, tr("Copy"), SLOT(on_actionCopy_triggered()), getCopySequence()); initAction(&actionCopy, tr("Copy"), SLOT(on_actionCopy_triggered()), getCopySequence());
addAction(&actionCopy); addAction(&actionCopy);
@ -28,6 +30,9 @@ DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent)
initAction(&actionCopyAddr, tr("Copy address"), SLOT(on_actionCopyAddr_triggered()), getCopyAddressSequence()); initAction(&actionCopyAddr, tr("Copy address"), SLOT(on_actionCopyAddr_triggered()), getCopyAddressSequence());
addAction(&actionCopyAddr); addAction(&actionCopyAddr);
initAction(&showInSubmenu, tr("Show in"), nullptr);
addAction(&showInSubmenu);
copySeparator = addSeparator(); copySeparator = addSeparator();
initAction(&actionAddComment, tr("Add Comment"), initAction(&actionAddComment, tr("Add Comment"),
@ -379,6 +384,11 @@ void DisassemblyContextMenu::aboutToShowSlot()
// Decide to show Reverse jmp option // Decide to show Reverse jmp option
showReverseJmpQuery(); showReverseJmpQuery();
if (showInSubmenu.menu() != nullptr) {
showInSubmenu.menu()->deleteLater();
}
showInSubmenu.setMenu(mainWindow->createShowInMenu(this, offset));
// Only show debug options if we are currently debugging // Only show debug options if we are currently debugging
debugMenu->menuAction()->setVisible(Core()->currentlyDebugging); debugMenu->menuAction()->setVisible(Core()->currentlyDebugging);
QString progCounterName = Core()->getRegisterName("PC"); QString progCounterName = Core()->getRegisterName("PC");

View File

@ -10,7 +10,7 @@ class DisassemblyContextMenu : public QMenu
Q_OBJECT Q_OBJECT
public: public:
DisassemblyContextMenu(QWidget *parent = nullptr); DisassemblyContextMenu(QWidget *parent, MainWindow* mainWindow);
~DisassemblyContextMenu(); ~DisassemblyContextMenu();
signals: signals:
@ -101,6 +101,7 @@ private:
RVA offset; RVA offset;
bool canCopy; bool canCopy;
QString curHighlightedWord; // The current highlighted word QString curHighlightedWord; // The current highlighted word
MainWindow* mainWindow;
QList<QAction *> anonymousActions; QList<QAction *> anonymousActions;
@ -164,6 +165,8 @@ private:
QAction actionSetToDataDword; QAction actionSetToDataDword;
QAction actionSetToDataQword; QAction actionSetToDataQword;
QAction showInSubmenu;
// For creating anonymous entries (that are always visible) // For creating anonymous entries (that are always visible)
QAction *addAnonymousAction(QString name, const char *slot, QKeySequence shortcut); QAction *addAnonymousAction(QString name, const char *slot, QKeySequence shortcut);

View File

@ -168,7 +168,7 @@ void BreakpointWidget::on_breakpointTreeView_doubleClicked(const QModelIndex &in
{ {
BreakpointDescription item = index.data( BreakpointDescription item = index.data(
BreakpointModel::BreakpointDescriptionRole).value<BreakpointDescription>(); BreakpointModel::BreakpointDescriptionRole).value<BreakpointDescription>();
Core()->seek(item.addr); Core()->seekAndShow(item.addr);
} }
void BreakpointWidget::showBreakpointContextMenu(const QPoint &pt) void BreakpointWidget::showBreakpointContextMenu(const QPoint &pt)

View File

@ -634,7 +634,7 @@ void ClassesWidget::on_classesTreeView_doubleClicked(const QModelIndex &index)
return; return;
} }
RVA offset = offsetData.value<RVA>(); RVA offset = offsetData.value<RVA>();
Core()->seek(offset); Core()->seekAndShow(offset);
} }
void ClassesWidget::showContextMenu(const QPoint &pt) void ClassesWidget::showContextMenu(const QPoint &pt)
@ -696,7 +696,7 @@ void ClassesWidget::on_seekToVTableAction_triggered()
return; return;
} }
Core()->seek(vtables[0].addr + desc.vtableOffset); Core()->seekAndShow(vtables[0].addr + desc.vtableOffset);
} }
void ClassesWidget::on_addMethodAction_triggered() void ClassesWidget::on_addMethodAction_triggered()

View File

@ -272,7 +272,7 @@ void CommentsWidget::on_commentsTreeView_doubleClicked(const QModelIndex &index)
return; return;
auto comment = index.data(CommentsModel::CommentDescriptionRole).value<CommentDescription>(); auto comment = index.data(CommentsModel::CommentDescriptionRole).value<CommentDescription>();
Core()->seek(comment.offset); Core()->seekAndShow(comment.offset);
} }
void CommentsWidget::on_actionHorizontal_triggered() void CommentsWidget::on_actionHorizontal_triggered()

View File

@ -86,3 +86,15 @@ QAction *CutterDockWidget::getBoundAction() const
return action; return action;
} }
QString CutterDockWidget::getDockNumber()
{
auto name = this->objectName();
if (name.contains(';')) {
auto parts = name.split(';');
if (parts.size() >= 2) {
return parts[1];
}
}
return QString();
}

View File

@ -67,9 +67,11 @@ protected:
void closeEvent(QCloseEvent *event) override; void closeEvent(QCloseEvent *event) override;
QAction *getBoundAction() const; QAction *getBoundAction() const;
QString getDockNumber();
MainWindow *mainWindow;
private: private:
MainWindow *mainWindow;
QAction *action; QAction *action;
bool isTransient = false; bool isTransient = false;

View File

@ -29,10 +29,10 @@
#include <cmath> #include <cmath>
DisassemblerGraphView::DisassemblerGraphView(QWidget *parent, CutterSeekable* seekable) DisassemblerGraphView::DisassemblerGraphView(QWidget *parent, CutterSeekable* seekable, MainWindow* mainWindow)
: GraphView(parent), : GraphView(parent),
mFontMetrics(nullptr), mFontMetrics(nullptr),
blockMenu(new DisassemblyContextMenu(this)), blockMenu(new DisassemblyContextMenu(this, mainWindow)),
contextMenu(new QMenu(this)), contextMenu(new QMenu(this)),
seekable(seekable) seekable(seekable)
{ {
@ -55,13 +55,6 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget *parent, CutterSeekable* se
connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(fontsUpdatedSlot())); connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(fontsUpdatedSlot()));
connectSeekChanged(false); connectSeekChanged(false);
// Space to switch to disassembly
QShortcut *shortcut_disassembly = new QShortcut(QKeySequence(Qt::Key_Space), this);
shortcut_disassembly->setContext(Qt::WidgetShortcut);
connect(shortcut_disassembly, &QShortcut::activated, this, [] {
Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Disassembly);
Core()->triggerRaisePrioritizedMemoryWidget();
});
// ESC for previous // ESC for previous
QShortcut *shortcut_escape = new QShortcut(QKeySequence(Qt::Key_Escape), this); QShortcut *shortcut_escape = new QShortcut(QKeySequence(Qt::Key_Escape), this);
shortcut_escape->setContext(Qt::WidgetShortcut); shortcut_escape->setContext(Qt::WidgetShortcut);
@ -95,7 +88,6 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget *parent, CutterSeekable* se
QShortcut *shortcut_prev_instr = new QShortcut(QKeySequence(Qt::Key_K), this); QShortcut *shortcut_prev_instr = new QShortcut(QKeySequence(Qt::Key_K), this);
shortcut_prev_instr->setContext(Qt::WidgetShortcut); shortcut_prev_instr->setContext(Qt::WidgetShortcut);
connect(shortcut_prev_instr, SIGNAL(activated()), this, SLOT(prevInstr())); connect(shortcut_prev_instr, SIGNAL(activated()), this, SLOT(prevInstr()));
shortcuts.append(shortcut_disassembly);
shortcuts.append(shortcut_escape); shortcuts.append(shortcut_escape);
shortcuts.append(shortcut_zoom_in); shortcuts.append(shortcut_zoom_in);
shortcuts.append(shortcut_zoom_out); shortcuts.append(shortcut_zoom_out);

View File

@ -87,7 +87,7 @@ class DisassemblerGraphView : public GraphView
}; };
public: public:
DisassemblerGraphView(QWidget *parent, CutterSeekable* seekable); DisassemblerGraphView(QWidget *parent, CutterSeekable* seekable, MainWindow* mainWindow);
~DisassemblerGraphView() override; ~DisassemblerGraphView() override;
std::unordered_map<ut64, DisassemblyBlock> disassembly_blocks; std::unordered_map<ut64, DisassemblyBlock> disassembly_blocks;
virtual void drawBlock(QPainter &p, GraphView::GraphBlock &block) override; virtual void drawBlock(QPainter &p, GraphView::GraphBlock &block) override;

View File

@ -39,8 +39,8 @@ static DisassemblyTextBlockUserData *getUserData(const QTextBlock &block)
} }
DisassemblyWidget::DisassemblyWidget(MainWindow *main, QAction *action) DisassemblyWidget::DisassemblyWidget(MainWindow *main, QAction *action)
: MemoryDockWidget(CutterCore::MemoryWidgetType::Disassembly, main, action) : MemoryDockWidget(MemoryWidgetType::Disassembly, main, action)
, mCtxMenu(new DisassemblyContextMenu(this)) , mCtxMenu(new DisassemblyContextMenu(this, main))
, mDisasScrollArea(new DisassemblyScrollArea(this)) , mDisasScrollArea(new DisassemblyScrollArea(this))
, mDisasTextEdit(new DisassemblyTextEdit(this)) , mDisasTextEdit(new DisassemblyTextEdit(this))
{ {
@ -161,14 +161,6 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main, QAction *action)
connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(fontsUpdatedSlot())); connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(fontsUpdatedSlot()));
connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(colorsUpdatedSlot())); connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(colorsUpdatedSlot()));
connect(this, &QDockWidget::visibilityChanged, this, [](bool visibility) {
bool emptyGraph = (Core()->getMemoryWidgetPriority() == CutterCore::MemoryWidgetType::Graph
&& Core()->isGraphEmpty());
if (visibility && !emptyGraph) {
Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Disassembly);
}
});
connect(Core(), &CutterCore::refreshAll, this, [this]() { connect(Core(), &CutterCore::refreshAll, this, [this]() {
refreshDisasm(seekable->getOffset()); refreshDisasm(seekable->getOffset());
}); });
@ -192,9 +184,8 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main, QAction *action)
connect(a, &QAction::triggered, this, (slot)); } connect(a, &QAction::triggered, this, (slot)); }
// Space to switch to graph // Space to switch to graph
ADD_ACTION(Qt::Key_Space, Qt::WidgetWithChildrenShortcut, [] { ADD_ACTION(Qt::Key_Space, Qt::WidgetWithChildrenShortcut, [this] {
Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Graph); mainWindow->showMemoryWidget(MemoryWidgetType::Graph);
Core()->triggerRaisePrioritizedMemoryWidget();
}) })
ADD_ACTION(Qt::Key_Escape, Qt::WidgetWithChildrenShortcut, &DisassemblyWidget::seekPrev) ADD_ACTION(Qt::Key_Escape, Qt::WidgetWithChildrenShortcut, &DisassemblyWidget::seekPrev)

View File

@ -51,5 +51,5 @@ void EntrypointWidget::on_entrypointTreeWidget_itemDoubleClicked(QTreeWidgetItem
return; return;
EntrypointDescription ep = item->data(0, Qt::UserRole).value<EntrypointDescription>(); EntrypointDescription ep = item->data(0, Qt::UserRole).value<EntrypointDescription>();
Core()->seek(ep.vaddr); Core()->seekAndShow(ep.vaddr);
} }

View File

@ -183,5 +183,5 @@ void ExportsWidget::on_exportsTreeView_doubleClicked(const QModelIndex &index)
return; return;
ExportDescription exp = index.data(ExportsModel::ExportDescriptionRole).value<ExportDescription>(); ExportDescription exp = index.data(ExportsModel::ExportDescriptionRole).value<ExportDescription>();
Core()->seek(exp.vaddr); Core()->seekAndShow(exp.vaddr);
} }

View File

@ -174,7 +174,7 @@ void FlagsWidget::on_flagsTreeView_doubleClicked(const QModelIndex &index)
return; return;
FlagDescription flag = index.data(FlagsModel::FlagDescriptionRole).value<FlagDescription>(); FlagDescription flag = index.data(FlagsModel::FlagDescriptionRole).value<FlagDescription>();
Core()->seek(flag.offset); Core()->seekAndShow(flag.offset);
} }
void FlagsWidget::on_flagspaceCombo_currentTextChanged(const QString &arg1) void FlagsWidget::on_flagspaceCombo_currentTextChanged(const QString &arg1)

View File

@ -522,7 +522,7 @@ void FunctionsWidget::onFunctionsDoubleClicked(const QModelIndex &index)
FunctionDescription function = index.data( FunctionDescription function = index.data(
FunctionModel::FunctionDescriptionRole).value<FunctionDescription>(); FunctionModel::FunctionDescriptionRole).value<FunctionDescription>();
Core()->seek(function.offset); Core()->seekAndShow(function.offset);
} }
void FunctionsWidget::showFunctionsContextMenu(const QPoint &pt) void FunctionsWidget::showFunctionsContextMenu(const QPoint &pt)
@ -556,7 +556,7 @@ void FunctionsWidget::on_actionDisasAdd_comment_triggered()
// Rename function in r2 core // Rename function in r2 core
Core()->setComment(function.offset, comment); Core()->setComment(function.offset, comment);
// Seek to new renamed function // Seek to new renamed function
Core()->seek(function.offset); Core()->seekAndShow(function.offset);
// TODO: Refresh functions tree widget // TODO: Refresh functions tree widget
} }
} }
@ -581,7 +581,7 @@ void FunctionsWidget::on_actionFunctionsRename_triggered()
Core()->renameFunction(function.name, new_name); Core()->renameFunction(function.name, new_name);
// Seek to new renamed function // Seek to new renamed function
Core()->seek(function.offset); Core()->seekAndShow(function.offset);
} }
} }

View File

@ -5,7 +5,7 @@
#include <QVBoxLayout> #include <QVBoxLayout>
GraphWidget::GraphWidget(MainWindow *main, QAction *action) : GraphWidget::GraphWidget(MainWindow *main, QAction *action) :
MemoryDockWidget(CutterCore::MemoryWidgetType::Graph, main, action) MemoryDockWidget(MemoryWidgetType::Graph, main, action)
{ {
setObjectName(main setObjectName(main
? main->getUniqueObjectName(getWidgetType()) ? main->getUniqueObjectName(getWidgetType())
@ -23,7 +23,7 @@ GraphWidget::GraphWidget(MainWindow *main, QAction *action) :
header->setReadOnly(true); header->setReadOnly(true);
layout->addWidget(header); layout->addWidget(header);
graphView = new DisassemblerGraphView(layoutWidget, seekable); graphView = new DisassemblerGraphView(layoutWidget, seekable, main);
layout->addWidget(graphView); layout->addWidget(graphView);
// getting the name of the class is implementation defined, and cannot be // getting the name of the class is implementation defined, and cannot be
@ -40,16 +40,24 @@ GraphWidget::GraphWidget(MainWindow *main, QAction *action) :
connect(this, &QDockWidget::visibilityChanged, this, [ = ](bool visibility) { connect(this, &QDockWidget::visibilityChanged, this, [ = ](bool visibility) {
main->toggleOverview(visibility, this); main->toggleOverview(visibility, this);
if (visibility) { if (visibility) {
Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Graph);
graphView->onSeekChanged(Core()->getOffset()); graphView->onSeekChanged(Core()->getOffset());
} }
}); });
QAction *switchAction = new QAction(this);
switchAction->setShortcut(Qt::Key_Space);
switchAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
addAction(switchAction);
connect(switchAction, &QAction::triggered, this, [this] {
mainWindow->showMemoryWidget(MemoryWidgetType::Disassembly);
});
connect(graphView, &DisassemblerGraphView::graphMoved, this, [ = ]() { connect(graphView, &DisassemblerGraphView::graphMoved, this, [ = ]() {
main->toggleOverview(true, this); main->toggleOverview(true, this);
}); });
connect(seekable, &CutterSeekable::seekableSeekChanged, this, &GraphWidget::prepareHeader); connect(seekable, &CutterSeekable::seekableSeekChanged, this, &GraphWidget::prepareHeader);
connect(Core(), &CutterCore::functionRenamed, this, &GraphWidget::prepareHeader); connect(Core(), &CutterCore::functionRenamed, this, &GraphWidget::prepareHeader);
graphView->installEventFilter(this);
} }
QWidget *GraphWidget::widgetToFocusOnRaise() QWidget *GraphWidget::widgetToFocusOnRaise()

View File

@ -134,5 +134,5 @@ void HeadersWidget::setScrollMode()
void HeadersWidget::on_headersTreeView_doubleClicked(const QModelIndex &index) void HeadersWidget::on_headersTreeView_doubleClicked(const QModelIndex &index)
{ {
HeaderDescription item = index.data(HeadersModel::HeaderDescriptionRole).value<HeaderDescription>(); HeaderDescription item = index.data(HeadersModel::HeaderDescriptionRole).value<HeaderDescription>();
Core()->seek(item.vaddr); Core()->seekAndShow(item.vaddr);
} }

View File

@ -17,7 +17,7 @@
#include <QShortcut> #include <QShortcut>
HexdumpWidget::HexdumpWidget(MainWindow *main, QAction *action) : HexdumpWidget::HexdumpWidget(MainWindow *main, QAction *action) :
MemoryDockWidget(CutterCore::MemoryWidgetType::Hexdump, main, action), MemoryDockWidget(MemoryWidgetType::Hexdump, main, action),
ui(new Ui::HexdumpWidget) ui(new Ui::HexdumpWidget)
{ {
ui->setupUi(this); ui->setupUi(this);
@ -78,13 +78,6 @@ HexdumpWidget::HexdumpWidget(MainWindow *main, QAction *action) :
this->ui->hexTextView->addAction(&syncAction); this->ui->hexTextView->addAction(&syncAction);
connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(fontsUpdated())); connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(fontsUpdated()));
connect(this, &QDockWidget::visibilityChanged, this, [](bool visibility) {
if (visibility) {
Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Hexdump);
}
});
connect(Core(), &CutterCore::refreshAll, this, [this]() { refresh(); }); connect(Core(), &CutterCore::refreshAll, this, [this]() { refresh(); });
connect(seekable, &CutterSeekable::seekableSeekChanged, this, &HexdumpWidget::onSeekChanged); connect(seekable, &CutterSeekable::seekableSeekChanged, this, &HexdumpWidget::onSeekChanged);
@ -97,6 +90,7 @@ HexdumpWidget::HexdumpWidget(MainWindow *main, QAction *action) :
}); });
connect(ui->hexTextView, &HexWidget::selectionChanged, this, &HexdumpWidget::selectionChanged); connect(ui->hexTextView, &HexWidget::selectionChanged, this, &HexdumpWidget::selectionChanged);
connect(ui->hexSideTab_2, &QTabWidget::currentChanged, this, &HexdumpWidget::refreshSelectionInfo); connect(ui->hexSideTab_2, &QTabWidget::currentChanged, this, &HexdumpWidget::refreshSelectionInfo);
ui->hexTextView->installEventFilter(this);
initParsing(); initParsing();
selectHexPreview(); selectHexPreview();

View File

@ -194,5 +194,5 @@ void ImportsWidget::on_importsTreeView_doubleClicked(const QModelIndex &index)
if (!index.isValid()) if (!index.isValid())
return; return;
Core()->seek(index.data(ImportsModel::AddressRole).toLongLong()); Core()->seekAndShow(index.data(ImportsModel::AddressRole).toLongLong());
} }

View File

@ -1,27 +1,36 @@
#include "MemoryDockWidget.h" #include "MemoryDockWidget.h"
#include "common/CutterSeekable.h" #include "common/CutterSeekable.h"
#include "MainWindow.h"
#include <QAction> #include <QAction>
#include <QEvent>
MemoryDockWidget::MemoryDockWidget(CutterCore::MemoryWidgetType type, MainWindow *parent, QAction *action) MemoryDockWidget::MemoryDockWidget(MemoryWidgetType type, MainWindow *parent, QAction *action)
: CutterDockWidget(parent, action) : CutterDockWidget(parent, action)
, mType(type), seekable(new CutterSeekable(this)) , mType(type), seekable(new CutterSeekable(this))
{ {
connect(Core(), &CutterCore::raisePrioritizedMemoryWidget, this, &MemoryDockWidget::handleRaiseMemoryWidget); if (parent) {
parent->addMemoryDockWidget(this);
}
connect(seekable, &CutterSeekable::syncChanged, this, &MemoryDockWidget::updateWindowTitle); connect(seekable, &CutterSeekable::syncChanged, this, &MemoryDockWidget::updateWindowTitle);
} }
void MemoryDockWidget::handleRaiseMemoryWidget(CutterCore::MemoryWidgetType raiseType) bool MemoryDockWidget::tryRaiseMemoryWidget()
{ {
if (!seekable->isSynchronized()) { if (!seekable->isSynchronized()) {
return; return false;
}
bool raisingEmptyGraph = (raiseType == CutterCore::MemoryWidgetType::Graph && Core()->isGraphEmpty());
if (raisingEmptyGraph) {
raiseType = CutterCore::MemoryWidgetType::Disassembly;
} }
if (raiseType == mType) { if (mType == MemoryWidgetType::Graph && Core()->isGraphEmpty()) {
return false;
}
raiseMemoryWidget();
return true;
}
void MemoryDockWidget::raiseMemoryWidget()
{
if (getBoundAction()) { if (getBoundAction()) {
getBoundAction()->setChecked(true); getBoundAction()->setChecked(true);
} }
@ -30,15 +39,26 @@ void MemoryDockWidget::handleRaiseMemoryWidget(CutterCore::MemoryWidgetType rais
raise(); raise();
widgetToFocusOnRaise()->setFocus(Qt::FocusReason::TabFocusReason); widgetToFocusOnRaise()->setFocus(Qt::FocusReason::TabFocusReason);
} }
bool MemoryDockWidget::eventFilter(QObject *object, QEvent *event)
{
if (event->type() == QEvent::FocusIn) {
mainWindow->setCurrentMemoryWidget(this);
}
return CutterDockWidget::eventFilter(object, event);
} }
void MemoryDockWidget::updateWindowTitle() void MemoryDockWidget::updateWindowTitle()
{ {
if (seekable->isSynchronized()) { QString name = getWindowTitle();
setWindowTitle(getWindowTitle()); QString id = getDockNumber();
} else { if (!id.isEmpty()) {
setWindowTitle(getWindowTitle() + CutterSeekable::tr(" (unsynced)")); name += " " + id;
} }
if (!seekable->isSynchronized()) {
name += CutterSeekable::tr(" (unsynced)");
}
setWindowTitle(name);
} }
CutterSeekable* MemoryDockWidget::getSeekable() const CutterSeekable* MemoryDockWidget::getSeekable() const

View File

@ -6,19 +6,28 @@
class CutterSeekable; class CutterSeekable;
/* Disassembly/Graph/Hexdump/Pseudocode view priority */
enum class MemoryWidgetType { Disassembly, Graph, Hexdump, Pseudocode };
class MemoryDockWidget : public CutterDockWidget class MemoryDockWidget : public CutterDockWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
MemoryDockWidget(CutterCore::MemoryWidgetType type, MainWindow *parent, QAction *action = nullptr); MemoryDockWidget(MemoryWidgetType type, MainWindow *parent, QAction *action = nullptr);
~MemoryDockWidget() {} ~MemoryDockWidget() {}
CutterSeekable* getSeekable() const; CutterSeekable* getSeekable() const;
bool tryRaiseMemoryWidget();
void raiseMemoryWidget();
MemoryWidgetType getType() const
{
return mType;
}
bool eventFilter(QObject *object, QEvent *event);
private: private:
void handleRaiseMemoryWidget(CutterCore::MemoryWidgetType raiseType);
CutterCore::MemoryWidgetType mType; MemoryWidgetType mType;
public slots: public slots:
void updateWindowTitle(); void updateWindowTitle();

View File

@ -152,5 +152,5 @@ void MemoryMapWidget::on_memoryTreeView_doubleClicked(const QModelIndex &index)
{ {
MemoryMapDescription item = index.data( MemoryMapDescription item = index.data(
MemoryMapModel::MemoryDescriptionRole).value<MemoryMapDescription>(); MemoryMapModel::MemoryDescriptionRole).value<MemoryMapDescription>();
Core()->seek(item.addrStart); Core()->seekAndShow(item.addrStart);
} }

View File

@ -69,7 +69,7 @@ void Omnibar::on_gotoEntry_returnPressed()
{ {
QString str = this->text(); QString str = this->text();
if (!str.isEmpty()) { if (!str.isEmpty()) {
Core()->seek(str); Core()->seekAndShow(str);
} }
this->setText(""); this->setText("");

View File

@ -35,7 +35,7 @@ struct DecompiledCodeTextLine
PseudocodeWidget::PseudocodeWidget(MainWindow *main, QAction *action) : PseudocodeWidget::PseudocodeWidget(MainWindow *main, QAction *action) :
MemoryDockWidget(CutterCore::MemoryWidgetType::Pseudocode, main, action), MemoryDockWidget(MemoryWidgetType::Pseudocode, main, action),
ui(new Ui::PseudocodeWidget) ui(new Ui::PseudocodeWidget)
{ {
ui->setupUi(this); ui->setupUi(this);
@ -48,12 +48,6 @@ PseudocodeWidget::PseudocodeWidget(MainWindow *main, QAction *action) :
connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(fontsUpdated())); connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(fontsUpdated()));
connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(colorsUpdatedSlot())); connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(colorsUpdatedSlot()));
connect(this, &QDockWidget::visibilityChanged, this, [](bool visibility) {
if (visibility) {
Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Pseudocode);
}
});
// TODO Use RefreshDeferrer and remove the refresh button // TODO Use RefreshDeferrer and remove the refresh button
connect(ui->refreshButton, &QAbstractButton::clicked, this, [this]() { connect(ui->refreshButton, &QAbstractButton::clicked, this, [this]() {
doRefresh(Core()->getOffset()); doRefresh(Core()->getOffset());

View File

@ -179,7 +179,7 @@ void RegisterRefsWidget::on_registerRefTreeView_doubleClicked(const QModelIndex
{ {
RegisterRefDescription item = index.data( RegisterRefDescription item = index.data(
RegisterRefModel::RegisterRefDescriptionRole).value<RegisterRefDescription>(); RegisterRefModel::RegisterRefDescriptionRole).value<RegisterRefDescription>();
Core()->seek(item.value); Core()->seekAndShow(item.value);
} }
void RegisterRefsWidget::showRegRefContextMenu(const QPoint &pt) void RegisterRefsWidget::showRegRefContextMenu(const QPoint &pt)

View File

@ -147,7 +147,7 @@ void RelocsWidget::on_relocsTreeView_doubleClicked(const QModelIndex &index)
if (!index.isValid()) if (!index.isValid())
return; return;
Core()->seek(index.data(RelocsModel::AddressRole).toLongLong()); Core()->seekAndShow(index.data(RelocsModel::AddressRole).toLongLong());
} }
void RelocsWidget::refreshRelocs() void RelocsWidget::refreshRelocs()

View File

@ -107,5 +107,5 @@ void ResourcesWidget::onDoubleClicked(const QModelIndex &index)
return; return;
ResourcesDescription res = index.data(Qt::UserRole).value<ResourcesDescription>(); ResourcesDescription res = index.data(Qt::UserRole).value<ResourcesDescription>();
Core()->seek(res.vaddr); Core()->seekAndShow(res.vaddr);
} }

View File

@ -206,7 +206,7 @@ void SearchWidget::on_searchTreeView_doubleClicked(const QModelIndex &index)
SearchDescription search = index.data( SearchDescription search = index.data(
SearchModel::SearchDescriptionRole).value<SearchDescription>(); SearchModel::SearchDescriptionRole).value<SearchDescription>();
Core()->seek(search.offset); Core()->seekAndShow(search.offset);
} }
void SearchWidget::searchChanged() void SearchWidget::searchChanged()

View File

@ -303,7 +303,7 @@ void SectionsWidget::onSectionsDoubleClicked(const QModelIndex &index)
} }
auto section = index.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>(); auto section = index.data(SectionsModel::SectionDescriptionRole).value<SectionDescription>();
Core()->seek(section.vaddr); Core()->seekAndShow(section.vaddr);
} }
void SectionsWidget::resizeEvent(QResizeEvent *event) { void SectionsWidget::resizeEvent(QResizeEvent *event) {
@ -470,7 +470,7 @@ void AddrDockScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
if (event->buttons() & Qt::LeftButton) { if (event->buttons() & Qt::LeftButton) {
RVA seekAddr = getAddrFromPos((int)event->scenePos().y(), true); RVA seekAddr = getAddrFromPos((int)event->scenePos().y(), true);
disableCenterOn = true; disableCenterOn = true;
Core()->seek(seekAddr); Core()->seekAndShow(seekAddr);
disableCenterOn = false; disableCenterOn = false;
return; return;
} }

View File

@ -188,5 +188,5 @@ void SegmentsWidget::onSegmentsDoubleClicked(const QModelIndex &index)
return; return;
auto segment = index.data(SegmentsModel::SegmentDescriptionRole).value<SegmentDescription>(); auto segment = index.data(SegmentsModel::SegmentDescriptionRole).value<SegmentDescription>();
Core()->seek(segment.vaddr); Core()->seekAndShow(segment.vaddr);
} }

View File

@ -108,7 +108,7 @@ void StackWidget::onDoubleClicked(const QModelIndex &index)
// Check if we are clicking on the offset or value columns and seek if it is the case // Check if we are clicking on the offset or value columns and seek if it is the case
if (index.column() <= 1) { if (index.column() <= 1) {
QString item = index.data().toString(); QString item = index.data().toString();
Core()->seek(item); Core()->seekAndShow(item);
} }
} }
@ -123,7 +123,7 @@ void StackWidget::customMenuRequested(QPoint pos)
void StackWidget::seekOffset() void StackWidget::seekOffset()
{ {
QString offset = viewStack->selectionModel()->currentIndex().data().toString(); QString offset = viewStack->selectionModel()->currentIndex().data().toString();
Core()->seek(offset); Core()->seekAndShow(offset);
} }
void StackWidget::editStack() void StackWidget::editStack()

View File

@ -204,7 +204,7 @@ void StringsWidget::on_stringsTreeView_doubleClicked(const QModelIndex &index)
} }
StringDescription str = index.data(StringsModel::StringDescriptionRole).value<StringDescription>(); StringDescription str = index.data(StringsModel::StringDescriptionRole).value<StringDescription>();
Core()->seek(str.vaddr); Core()->seekAndShow(str.vaddr);
} }
void StringsWidget::refreshStrings() void StringsWidget::refreshStrings()

View File

@ -150,7 +150,7 @@ void SymbolsWidget::on_symbolsTreeView_doubleClicked(const QModelIndex &index)
} }
auto symbol = index.data(SymbolsModel::SymbolDescriptionRole).value<SymbolDescription>(); auto symbol = index.data(SymbolsModel::SymbolDescriptionRole).value<SymbolDescription>();
Core()->seek(symbol.vaddr); Core()->seekAndShow(symbol.vaddr);
} }
void SymbolsWidget::refreshSymbols() void SymbolsWidget::refreshSymbols()

View File

@ -188,10 +188,10 @@ void VTablesWidget::on_vTableTreeView_doubleClicked(const QModelIndex &index)
QModelIndex parent = index.parent(); QModelIndex parent = index.parent();
if (parent.isValid()) { if (parent.isValid()) {
Core()->seek(index.data( Core()->seekAndShow(index.data(
VTableModel::VTableDescriptionRole).value<BinClassMethodDescription>().addr); VTableModel::VTableDescriptionRole).value<BinClassMethodDescription>().addr);
} else { } else {
Core()->seek(index.data( Core()->seekAndShow(index.data(
VTableModel::VTableDescriptionRole).value<VTableDescription>().addr); VTableModel::VTableDescriptionRole).value<VTableDescription>().addr);
} }
} }

View File

@ -151,5 +151,5 @@ void ZignaturesWidget::on_zignaturesTreeView_doubleClicked(const QModelIndex &in
{ {
ZignatureDescription item = index.data( ZignatureDescription item = index.data(
ZignaturesModel::ZignatureDescriptionRole).value<ZignatureDescription>(); ZignaturesModel::ZignatureDescriptionRole).value<ZignatureDescription>();
Core()->seek(item.offset); Core()->seekAndShow(item.offset);
} }