mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-20 20:06:12 +00:00
This reverts commit 2ba9e170c5
.
This commit is contained in:
parent
d35bed54a3
commit
72eab68be1
@ -50,7 +50,6 @@ void CutterSeekable::toggleSynchronization()
|
||||
{
|
||||
synchronized = !synchronized;
|
||||
onCoreSeekChanged(Core()->getOffset());
|
||||
emit syncChanged();
|
||||
}
|
||||
|
||||
bool CutterSeekable::isSynchronized()
|
||||
|
@ -82,5 +82,5 @@ private:
|
||||
|
||||
signals:
|
||||
void seekableSeekChanged(RVA addr);
|
||||
void syncChanged();
|
||||
|
||||
};
|
||||
|
@ -105,9 +105,6 @@
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsView>
|
||||
|
||||
template<class T>
|
||||
T* getNewInstance(MainWindow *m, QAction *a) { return new T(m, a); }
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
core(Core()),
|
||||
@ -126,16 +123,9 @@ void MainWindow::initUI()
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
mapper.insert("GraphWidget", {getNewInstance<GraphWidget>, ui->actionGraph});
|
||||
mapper.insert("DisassemblyWidget", {getNewInstance<DisassemblyWidget>, ui->actionDisassembly});
|
||||
mapper.insert("HexdumpWidget", {getNewInstance<HexdumpWidget>, ui->actionHexdump});
|
||||
|
||||
initToolBar();
|
||||
initDocks();
|
||||
|
||||
QSettings s;
|
||||
s.setValue("state.empty", saveState());
|
||||
|
||||
/*
|
||||
* Some global shortcuts
|
||||
*/
|
||||
@ -256,6 +246,8 @@ void MainWindow::initToolBar()
|
||||
void MainWindow::initDocks()
|
||||
{
|
||||
dockWidgets.reserve(20);
|
||||
disassemblyDock = new DisassemblyWidget(this, ui->actionDisassembly);
|
||||
hexdumpDock = new HexdumpWidget(this, ui->actionHexdump);
|
||||
pseudocodeDock = new PseudocodeWidget(this, ui->actionPseudocode);
|
||||
consoleDock = new ConsoleWidget(this, ui->actionConsole);
|
||||
|
||||
@ -274,6 +266,7 @@ void MainWindow::initDocks()
|
||||
});
|
||||
|
||||
ui->actionOverview->setChecked(overviewDock->getUserOpened());
|
||||
graphDock = new GraphWidget(this, ui->actionGraph);
|
||||
sectionsDock = new SectionsWidget(this, ui->actionSections);
|
||||
segmentsDock = new SegmentsWidget(this, ui->actionSegments);
|
||||
entrypointDock = new EntrypointWidget(this, ui->actionEntrypoints);
|
||||
@ -300,35 +293,6 @@ void MainWindow::initDocks()
|
||||
classesDock = new ClassesWidget(this, ui->actionClasses);
|
||||
resourcesDock = new ResourcesWidget(this, ui->actionResources);
|
||||
vTablesDock = new VTablesWidget(this, ui->actionVTables);
|
||||
|
||||
QSettings s;
|
||||
QStringList docks = s.value("docks").toStringList();
|
||||
|
||||
// Restore all extra widgets
|
||||
QString className;
|
||||
for (const auto &it : docks) {
|
||||
if (std::none_of(dockWidgets.constBegin(), dockWidgets.constEnd(),
|
||||
[&it](QDockWidget *w) { return w->objectName() == it; })) {
|
||||
className = it.split(' ').at(0);
|
||||
if (mapper.contains(className)) {
|
||||
auto widget = mapper[className].first(this, mapper[className].second);
|
||||
widget->setObjectName(it);
|
||||
addExtraWidget(widget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateMemberPointers();
|
||||
|
||||
if (!disassemblyDock) {
|
||||
on_actionExtraDisassembly_triggered();
|
||||
} else if (!graphDock) {
|
||||
on_actionExtraGraph_triggered();
|
||||
} else if (!hexdumpDock) {
|
||||
on_actionExtraHexdump_triggered();
|
||||
}
|
||||
|
||||
updateMemberPointers();
|
||||
}
|
||||
|
||||
void MainWindow::initLayout()
|
||||
@ -337,8 +301,10 @@ void MainWindow::initLayout()
|
||||
enableDebugWidgetsMenu(false);
|
||||
// Restore saved settings
|
||||
readSettingsOrDefault();
|
||||
|
||||
initCorners();
|
||||
// TODO: Allow the user to select this option visually in the GUI settings
|
||||
// Adjust the DockWidget areas
|
||||
setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);
|
||||
setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
|
||||
}
|
||||
|
||||
void MainWindow::toggleOverview(bool visibility, GraphWidget *targetGraph)
|
||||
@ -359,29 +325,26 @@ void MainWindow::updateTasksIndicator()
|
||||
|
||||
void MainWindow::on_actionExtraGraph_triggered()
|
||||
{
|
||||
auto *extraDock = new GraphWidget(this, ui->actionGraph);
|
||||
extraDock->setObjectName(getUniqueObjectName(extraDock->metaObject()->className()));
|
||||
auto *extraDock = new GraphWidget(this, nullptr);
|
||||
addExtraWidget(extraDock);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionExtraHexdump_triggered()
|
||||
{
|
||||
auto *extraDock = new HexdumpWidget(this, ui->actionHexdump);
|
||||
extraDock->setObjectName(getUniqueObjectName(extraDock->metaObject()->className()));
|
||||
auto *extraDock = new HexdumpWidget(this, nullptr);
|
||||
addExtraWidget(extraDock);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionExtraDisassembly_triggered()
|
||||
{
|
||||
auto *extraDock = new DisassemblyWidget(this, ui->actionDisassembly);
|
||||
extraDock->setObjectName(getUniqueObjectName(extraDock->metaObject()->className()));
|
||||
auto *extraDock = new DisassemblyWidget(this, nullptr);
|
||||
addExtraWidget(extraDock);
|
||||
}
|
||||
|
||||
void MainWindow::addExtraWidget(CutterDockWidget *extraDock)
|
||||
{
|
||||
extraDock->setTransient(true);
|
||||
addDockWidget(Qt::TopDockWidgetArea, extraDock, Qt::Orientation::Horizontal);
|
||||
addDockWidget(Qt::TopDockWidgetArea, extraDock);
|
||||
auto restoreExtraDock = qhelpers::forceWidth(extraDock->widget(), 600);
|
||||
qApp->processEvents();
|
||||
restoreExtraDock.restoreWidth(extraDock->widget());
|
||||
@ -417,8 +380,7 @@ QMenu *MainWindow::getMenuByType(MenuType type)
|
||||
void MainWindow::addPluginDockWidget(QDockWidget *dockWidget, QAction *action)
|
||||
{
|
||||
addDockWidget(Qt::TopDockWidgetArea, dockWidget);
|
||||
dockWidget->addAction(action);
|
||||
addWidget(dockWidget);
|
||||
addDockWidgetAction(dockWidget, action);
|
||||
ui->menuPlugins->addAction(action);
|
||||
addDockWidget(Qt::DockWidgetArea::TopDockWidgetArea, dockWidget);
|
||||
updateDockActionChecked(action);
|
||||
@ -529,13 +491,6 @@ void MainWindow::finalizeOpen()
|
||||
showMaximized();
|
||||
|
||||
|
||||
QSettings s;
|
||||
QStringList unsync = s.value("unsync").toStringList();
|
||||
for (auto it : dockWidgets) {
|
||||
if (unsync.contains(it->objectName())) {
|
||||
qobject_cast<MemoryDockWidget*>(it)->toggleSync();
|
||||
}
|
||||
}
|
||||
|
||||
// Set focus to disasm or graph widget
|
||||
|
||||
@ -648,7 +603,7 @@ void MainWindow::readSettingsOrDefault()
|
||||
* Check if saved settings exist
|
||||
* If not, then read the default layout
|
||||
*/
|
||||
if (!geo.length() || !state.length()) {
|
||||
if (!geo.length() && !state.length()) {
|
||||
resetToDefaultLayout();
|
||||
return;
|
||||
}
|
||||
@ -684,22 +639,6 @@ void MainWindow::readSettingsOrDefault()
|
||||
void MainWindow::saveSettings()
|
||||
{
|
||||
QSettings settings;
|
||||
|
||||
QStringList docks;
|
||||
const QStringList syncable = QStringList()
|
||||
<< hexdumpDock->metaObject()->className()
|
||||
<< disassemblyDock->metaObject()->className()
|
||||
<< graphDock->metaObject()->className();
|
||||
QStringList unsync;
|
||||
for (const auto &it : dockWidgets) {
|
||||
docks.append(it->objectName());
|
||||
if (syncable.contains(it->metaObject()->className()) &&
|
||||
!qobject_cast<MemoryDockWidget*>(it)->isSynced()) {
|
||||
unsync.append(it->objectName());
|
||||
}
|
||||
}
|
||||
settings.setValue("docks", docks);
|
||||
settings.setValue("unsync", unsync);
|
||||
settings.setValue("geometry", saveGeometry());
|
||||
settings.setValue("size", size());
|
||||
settings.setValue("pos", pos());
|
||||
@ -786,7 +725,22 @@ void MainWindow::restoreDocks()
|
||||
addDockWidget(Qt::TopDockWidgetArea, overviewDock);
|
||||
|
||||
// Function | Dashboard
|
||||
splitDockWidget(functionsDock, dashboardDock, Qt::Horizontal);
|
||||
splitDockWidget(overviewDock, dashboardDock, Qt::Horizontal);
|
||||
splitDockWidget(functionsDock, overviewDock, Qt::Vertical);
|
||||
|
||||
// In the lower half the console is the first widget
|
||||
addDockWidget(Qt::BottomDockWidgetArea, consoleDock);
|
||||
|
||||
// Console | Sections
|
||||
splitDockWidget(consoleDock, sectionsDock, Qt::Horizontal);
|
||||
splitDockWidget(consoleDock, segmentsDock, Qt::Horizontal);
|
||||
|
||||
// Tabs for center (must be applied after splitDockWidget())
|
||||
tabifyDockWidget(sectionsDock, commentsDock);
|
||||
tabifyDockWidget(segmentsDock, commentsDock);
|
||||
tabifyDockWidget(dashboardDock, disassemblyDock);
|
||||
tabifyDockWidget(dashboardDock, graphDock);
|
||||
tabifyDockWidget(dashboardDock, hexdumpDock);
|
||||
tabifyDockWidget(dashboardDock, pseudocodeDock);
|
||||
tabifyDockWidget(dashboardDock, entrypointDock);
|
||||
tabifyDockWidget(dashboardDock, flagsDock);
|
||||
@ -803,31 +757,17 @@ void MainWindow::restoreDocks()
|
||||
tabifyDockWidget(dashboardDock, resourcesDock);
|
||||
tabifyDockWidget(dashboardDock, vTablesDock);
|
||||
tabifyDockWidget(dashboardDock, sdbDock);
|
||||
tabifyDockWidget(dashboardDock, memoryMapDock);
|
||||
tabifyDockWidget(dashboardDock, breakpointDock);
|
||||
tabifyDockWidget(dashboardDock, registerRefsDock);
|
||||
for (const auto &it : dockWidgets) {
|
||||
if (QRegExp("\\w+ \\d+").exactMatch(it->objectName())) {
|
||||
tabifyDockWidget(dashboardDock, it);
|
||||
}
|
||||
}
|
||||
|
||||
splitDockWidget(functionsDock, overviewDock, Qt::Vertical);
|
||||
|
||||
// In the lower half the console is the first widget
|
||||
addDockWidget(Qt::BottomDockWidgetArea, consoleDock);
|
||||
|
||||
// Console | Sections
|
||||
splitDockWidget(consoleDock, sectionsDock, Qt::Horizontal);
|
||||
splitDockWidget(consoleDock, segmentsDock, Qt::Horizontal);
|
||||
|
||||
tabifyDockWidget(sectionsDock, commentsDock);
|
||||
|
||||
// Add Stack, Registers and Backtrace vertically stacked
|
||||
addDockWidget(Qt::TopDockWidgetArea, stackDock);
|
||||
splitDockWidget(stackDock, registersDock, Qt::Vertical);
|
||||
tabifyDockWidget(stackDock, backtraceDock);
|
||||
|
||||
// MemoryMap/Breakpoint/RegRefs widget goes in the center tabs
|
||||
tabifyDockWidget(dashboardDock, memoryMapDock);
|
||||
tabifyDockWidget(dashboardDock, breakpointDock);
|
||||
tabifyDockWidget(dashboardDock, registerRefsDock);
|
||||
|
||||
updateDockActionsChecked();
|
||||
}
|
||||
|
||||
@ -841,85 +781,14 @@ void MainWindow::hideAllDocks()
|
||||
|
||||
void MainWindow::updateDockActionsChecked()
|
||||
{
|
||||
for (auto i = dockWidgetsOfAction.constBegin(); i != dockWidgetsOfAction.constEnd(); i++) {
|
||||
updateDockActionChecked(i.key());
|
||||
}
|
||||
}
|
||||
|
||||
QString MainWindow::getUniqueObjectName(const QString& className) const
|
||||
{
|
||||
QStringList docks;
|
||||
docks.reserve(dockWidgets.size());
|
||||
QString name;
|
||||
for (const auto &it : dockWidgets) {
|
||||
name = it->objectName();
|
||||
if (name.contains(className)) {
|
||||
docks.push_back(name);
|
||||
}
|
||||
}
|
||||
|
||||
if (docks.isEmpty()) {
|
||||
return className;
|
||||
}
|
||||
|
||||
int id = 0;
|
||||
while (docks.contains(className + " " + QString::number(id))) {
|
||||
id++;
|
||||
}
|
||||
|
||||
return className + " " + QString::number(id);
|
||||
}
|
||||
|
||||
void MainWindow::initCorners()
|
||||
{
|
||||
// TODO: Allow the user to select this option visually in the GUI settings
|
||||
// Adjust the DockWidget areas
|
||||
setCorner(Qt::TopLeftCorner, Qt::TopDockWidgetArea);
|
||||
setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
|
||||
|
||||
setCorner(Qt::BottomRightCorner, Qt::BottomDockWidgetArea);
|
||||
setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea);
|
||||
}
|
||||
|
||||
void MainWindow::updateMemberPointers()
|
||||
{
|
||||
QString className;
|
||||
for (auto it : dockWidgets) {
|
||||
className = it->metaObject()->className();
|
||||
if (className == "GraphWidget") {
|
||||
graphDock = qobject_cast<GraphWidget*>(it);
|
||||
} else if (className == "DisassemblyWidget") {
|
||||
disassemblyDock = qobject_cast<DisassemblyWidget*>(it);
|
||||
} else if (className == "HexdumpWidget") {
|
||||
hexdumpDock = qobject_cast<HexdumpWidget*>(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::addWidget(QDockWidget* widget)
|
||||
{
|
||||
dockWidgets.push_back(widget);
|
||||
for (auto action : widget->actions()) {
|
||||
dockWidgetsOfAction.insert(action, widget);
|
||||
connect(qobject_cast<CutterDockWidget*>(widget), &CutterDockWidget::closed,
|
||||
this, [this]() {
|
||||
QDockWidget *widget = qobject_cast<QDockWidget*>(sender());
|
||||
dockWidgets.removeOne(widget);
|
||||
for (auto action : widget->actions()) {
|
||||
dockWidgetsOfAction.remove(action, widget);
|
||||
}
|
||||
updateMemberPointers();
|
||||
});
|
||||
for (auto i = dockWidgetActions.constBegin(); i != dockWidgetActions.constEnd(); i++) {
|
||||
i.key()->setChecked(!i.value()->isHidden());
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::updateDockActionChecked(QAction *action)
|
||||
{
|
||||
auto actions = dockWidgetsOfAction.values(action);
|
||||
action->setChecked(!std::accumulate(actions.begin(), actions.end(), false,
|
||||
[](bool a, QDockWidget* w) -> bool {
|
||||
return a || w->isHidden();
|
||||
}));
|
||||
action->setChecked(!dockWidgetActions[action]->isHidden());
|
||||
}
|
||||
|
||||
void MainWindow::showZenDocks()
|
||||
@ -927,20 +796,17 @@ void MainWindow::showZenDocks()
|
||||
const QList<QDockWidget *> zenDocks = { functionsDock,
|
||||
dashboardDock,
|
||||
stringsDock,
|
||||
searchDock,
|
||||
hexdumpDock,
|
||||
disassemblyDock,
|
||||
graphDock,
|
||||
importsDock
|
||||
disassemblyDock,
|
||||
hexdumpDock,
|
||||
searchDock,
|
||||
importsDock,
|
||||
};
|
||||
int width = functionsDock->maximumWidth();
|
||||
functionsDock->setMaximumWidth(200);
|
||||
for (auto w : dockWidgets) {
|
||||
if (zenDocks.contains(w)) {
|
||||
w->show();
|
||||
}
|
||||
}
|
||||
functionsDock->setMaximumWidth(width);
|
||||
updateDockActionsChecked();
|
||||
}
|
||||
|
||||
@ -948,24 +814,21 @@ void MainWindow::showDebugDocks()
|
||||
{
|
||||
const QList<QDockWidget *> debugDocks = { functionsDock,
|
||||
stringsDock,
|
||||
graphDock,
|
||||
disassemblyDock,
|
||||
hexdumpDock,
|
||||
searchDock,
|
||||
stackDock,
|
||||
registersDock,
|
||||
hexdumpDock,
|
||||
disassemblyDock,
|
||||
graphDock,
|
||||
backtraceDock,
|
||||
memoryMapDock,
|
||||
breakpointDock
|
||||
};
|
||||
int width = functionsDock->maximumWidth();
|
||||
functionsDock->setMaximumWidth(200);
|
||||
for (auto w : dockWidgets) {
|
||||
if (debugDocks.contains(w)) {
|
||||
w->show();
|
||||
}
|
||||
}
|
||||
functionsDock->setMaximumWidth(width);
|
||||
updateDockActionsChecked();
|
||||
}
|
||||
|
||||
@ -1011,23 +874,6 @@ void MainWindow::restoreDebugLayout()
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::resetDockWidgetList()
|
||||
{
|
||||
QStringList isLeft;
|
||||
QList<QWidget*> toClose;
|
||||
for (auto it : dockWidgets) {
|
||||
if (isLeft.contains(it->metaObject()->className())) {
|
||||
toClose.append(it);
|
||||
} else if (QRegExp("\\w+ \\d+").exactMatch(it->objectName())) {
|
||||
isLeft.append(it->metaObject()->className());
|
||||
}
|
||||
}
|
||||
for (auto it : toClose) {
|
||||
it->close();
|
||||
}
|
||||
updateMemberPointers();
|
||||
}
|
||||
|
||||
void MainWindow::on_actionLock_triggered()
|
||||
{
|
||||
panelLock = !panelLock;
|
||||
@ -1059,21 +905,9 @@ void MainWindow::on_actionFunctionsRename_triggered()
|
||||
|
||||
void MainWindow::on_actionDefault_triggered()
|
||||
{
|
||||
QSettings s;
|
||||
restoreState(s.value("state.empty").toByteArray());
|
||||
|
||||
initCorners();
|
||||
resetDockWidgetList();
|
||||
|
||||
if (core->currentlyDebugging) {
|
||||
resetToDefaultLayout();
|
||||
saveSettings();
|
||||
|
||||
resetToDebugLayout();
|
||||
} else {
|
||||
resetToDebugLayout();
|
||||
saveDebugSettings();
|
||||
|
||||
resetToDefaultLayout();
|
||||
}
|
||||
}
|
||||
@ -1361,6 +1195,16 @@ bool MainWindow::eventFilter(QObject *, QEvent *event)
|
||||
return false;
|
||||
}
|
||||
|
||||
void MainWindow::addToDockWidgetList(QDockWidget *dockWidget)
|
||||
{
|
||||
this->dockWidgets.push_back(dockWidget);
|
||||
}
|
||||
|
||||
void MainWindow::addDockWidgetAction(QDockWidget *dockWidget, QAction *action)
|
||||
{
|
||||
this->dockWidgetActions[action] = dockWidget;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Show a warning message box.
|
||||
*
|
||||
|
@ -94,7 +94,8 @@ public:
|
||||
void setFilename(const QString &fn);
|
||||
void refreshOmniBar(const QStringList &flags);
|
||||
|
||||
void addWidget(QDockWidget* widget);
|
||||
void addToDockWidgetList(QDockWidget *dockWidget);
|
||||
void addDockWidgetAction(QDockWidget *dockWidget, QAction *action);
|
||||
void addExtraWidget(CutterDockWidget *extraDock);
|
||||
|
||||
void addPluginDockWidget(QDockWidget *dockWidget, QAction *action);
|
||||
@ -206,7 +207,7 @@ private:
|
||||
Configuration *configuration;
|
||||
|
||||
QList<QDockWidget *> dockWidgets;
|
||||
QMultiMap<QAction *, QDockWidget *> dockWidgetsOfAction;
|
||||
QMap<QAction *, QDockWidget *> dockWidgetActions;
|
||||
DisassemblyWidget *disassemblyDock = nullptr;
|
||||
HexdumpWidget *hexdumpDock = nullptr;
|
||||
PseudocodeWidget *pseudocodeDock = nullptr;
|
||||
@ -248,15 +249,12 @@ private:
|
||||
void initToolBar();
|
||||
void initDocks();
|
||||
void initLayout();
|
||||
void initCorners();
|
||||
void displayInitialOptionsDialog(const InitialOptions &options = InitialOptions(), bool skipOptionsDialog = false);
|
||||
|
||||
void resetToDefaultLayout();
|
||||
void resetToDebugLayout();
|
||||
void restoreDebugLayout();
|
||||
|
||||
void updateMemberPointers();
|
||||
void resetDockWidgetList();
|
||||
void restoreDocks();
|
||||
void hideAllDocks();
|
||||
void showZenDocks();
|
||||
@ -268,14 +266,6 @@ private:
|
||||
void updateDockActionsChecked();
|
||||
void setOverviewData();
|
||||
bool isOverviewActive();
|
||||
|
||||
/**
|
||||
* @brief Map, where key is class name an value is pair of
|
||||
* pointer to class constructor and action that passed to this constructor.
|
||||
*/
|
||||
QMap<QString, std::pair<std::function<CutterDockWidget*(MainWindow*, QAction*)>, QAction*>> mapper;
|
||||
|
||||
QString getUniqueObjectName(const QString &className) const;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
@ -8,12 +8,12 @@ CutterDockWidget::CutterDockWidget(MainWindow *parent, QAction *action) :
|
||||
QDockWidget(parent),
|
||||
action(action)
|
||||
{
|
||||
if (parent) {
|
||||
parent->addToDockWidgetList(this);
|
||||
if (action) {
|
||||
addAction(action);
|
||||
parent->addDockWidgetAction(this, action);
|
||||
connect(action, &QAction::triggered, this, &CutterDockWidget::toggleDockWidget);
|
||||
}
|
||||
if (parent) {
|
||||
parent->addWidget(this);
|
||||
}
|
||||
|
||||
// Install event filter to catch redraw widgets when needed
|
||||
@ -39,7 +39,7 @@ bool CutterDockWidget::eventFilter(QObject *object, QEvent *event)
|
||||
void CutterDockWidget::toggleDockWidget(bool show)
|
||||
{
|
||||
if (!show) {
|
||||
this->hide();
|
||||
this->close();
|
||||
} else {
|
||||
this->show();
|
||||
this->raise();
|
||||
@ -73,8 +73,6 @@ void CutterDockWidget::closeEvent(QCloseEvent *event)
|
||||
if (isTransient) {
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
emit closed();
|
||||
}
|
||||
|
||||
QAction *CutterDockWidget::getBoundAction() const
|
||||
|
@ -57,7 +57,6 @@ public:
|
||||
|
||||
signals:
|
||||
void becameVisibleToUser();
|
||||
void closed();
|
||||
|
||||
public slots:
|
||||
void toggleDockWidget(bool show);
|
||||
|
@ -28,12 +28,12 @@
|
||||
|
||||
#include <cmath>
|
||||
|
||||
DisassemblerGraphView::DisassemblerGraphView(QWidget *parent, CutterSeekable* seekable)
|
||||
DisassemblerGraphView::DisassemblerGraphView(QWidget *parent)
|
||||
: GraphView(parent),
|
||||
mFontMetrics(nullptr),
|
||||
blockMenu(new DisassemblyContextMenu(this)),
|
||||
contextMenu(new QMenu(this)),
|
||||
seekable(seekable)
|
||||
seekable(new CutterSeekable(this))
|
||||
{
|
||||
highlight_token = nullptr;
|
||||
auto *layout = new QVBoxLayout(this);
|
||||
@ -106,7 +106,7 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget *parent, CutterSeekable* se
|
||||
actionExportGraph.setText(tr("Export Graph"));
|
||||
connect(&actionExportGraph, SIGNAL(triggered(bool)), this, SLOT(on_actionExportGraph_triggered()));
|
||||
actionSyncOffset.setText(tr("Sync/unsync offset"));
|
||||
connect(&actionSyncOffset, &QAction::triggered, this, [this]() { this->seekable->toggleSynchronization(); });
|
||||
connect(&actionSyncOffset, SIGNAL(triggered(bool)), this, SLOT(toggleSync()));
|
||||
|
||||
// Context menu that applies to everything
|
||||
contextMenu->addAction(&actionExportGraph);
|
||||
@ -156,6 +156,16 @@ DisassemblerGraphView::~DisassemblerGraphView()
|
||||
}
|
||||
}
|
||||
|
||||
void DisassemblerGraphView::toggleSync()
|
||||
{
|
||||
seekable->toggleSynchronization();
|
||||
if (seekable->isSynchronized()) {
|
||||
parentWidget()->setWindowTitle(windowTitle);
|
||||
} else {
|
||||
parentWidget()->setWindowTitle(windowTitle + CutterSeekable::tr(" (unsynced)"));
|
||||
}
|
||||
}
|
||||
|
||||
void DisassemblerGraphView::refreshView()
|
||||
{
|
||||
initFont();
|
||||
|
@ -84,7 +84,7 @@ class DisassemblerGraphView : public GraphView
|
||||
};
|
||||
|
||||
public:
|
||||
DisassemblerGraphView(QWidget *parent, CutterSeekable* seekable);
|
||||
DisassemblerGraphView(QWidget *parent);
|
||||
~DisassemblerGraphView() override;
|
||||
std::unordered_map<ut64, DisassemblyBlock> disassembly_blocks;
|
||||
virtual void drawBlock(QPainter &p, GraphView::GraphBlock &block) override;
|
||||
@ -112,6 +112,8 @@ public slots:
|
||||
void colorsUpdatedSlot();
|
||||
void fontsUpdatedSlot();
|
||||
void onSeekChanged(RVA addr);
|
||||
void toggleSync();
|
||||
|
||||
void zoom(QPointF mouseRelativePos, double velocity);
|
||||
void zoomReset();
|
||||
|
||||
|
@ -38,8 +38,19 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main, QAction *action)
|
||||
, mCtxMenu(new DisassemblyContextMenu(this))
|
||||
, mDisasScrollArea(new DisassemblyScrollArea(this))
|
||||
, mDisasTextEdit(new DisassemblyTextEdit(this))
|
||||
, seekable(new CutterSeekable(this))
|
||||
{
|
||||
setObjectName("DisassemblyWidget");
|
||||
/*
|
||||
* Ugly hack just for the layout issue
|
||||
* QSettings saves the state with the object names
|
||||
* By doing this hack,
|
||||
* you can at least avoid some mess by dismissing all the Extra Widgets
|
||||
*/
|
||||
QString name = "Disassembly";
|
||||
if (!action) {
|
||||
name = "Extra Disassembly";
|
||||
}
|
||||
setObjectName(name);
|
||||
|
||||
topOffset = bottomOffset = RVA_INVALID;
|
||||
cursorLineOffset = 0;
|
||||
@ -176,6 +187,17 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main, QAction *action)
|
||||
#undef ADD_ACTION
|
||||
}
|
||||
|
||||
void DisassemblyWidget::toggleSync()
|
||||
{
|
||||
QString windowTitle = tr("Disassembly");
|
||||
seekable->toggleSynchronization();
|
||||
if (seekable->isSynchronized()) {
|
||||
setWindowTitle(windowTitle);
|
||||
} else {
|
||||
setWindowTitle(windowTitle + CutterSeekable::tr(" (unsynced)"));
|
||||
}
|
||||
}
|
||||
|
||||
void DisassemblyWidget::setPreviewMode(bool previewMode)
|
||||
{
|
||||
mDisasTextEdit->setContextMenuPolicy(previewMode
|
||||
|
@ -29,6 +29,7 @@ public slots:
|
||||
void fontsUpdatedSlot();
|
||||
void colorsUpdatedSlot();
|
||||
void seekPrev();
|
||||
void toggleSync();
|
||||
void setPreviewMode(bool previewMode);
|
||||
|
||||
protected slots:
|
||||
@ -81,6 +82,7 @@ private:
|
||||
QList<QTextEdit::ExtraSelection> getSameWordsSelections();
|
||||
|
||||
QAction syncIt;
|
||||
CutterSeekable *seekable;
|
||||
};
|
||||
|
||||
class DisassemblyScrollArea : public QAbstractScrollArea
|
||||
|
@ -6,9 +6,19 @@
|
||||
GraphWidget::GraphWidget(MainWindow *main, QAction *action) :
|
||||
MemoryDockWidget(CutterCore::MemoryWidgetType::Graph, main, action)
|
||||
{
|
||||
setObjectName("GraphWidget");
|
||||
/*
|
||||
* Ugly hack just for the layout issue
|
||||
* QSettings saves the state with the object names
|
||||
* By doing this hack,
|
||||
* you can at least avoid some mess by dismissing all the Extra Widgets
|
||||
*/
|
||||
QString name = "Graph";
|
||||
if (!action) {
|
||||
name = "Extra Graph";
|
||||
}
|
||||
setObjectName(name);
|
||||
setAllowedAreas(Qt::AllDockWidgetAreas);
|
||||
graphView = new DisassemblerGraphView(this, seekable);
|
||||
graphView = new DisassemblerGraphView(this);
|
||||
setWidget(graphView);
|
||||
|
||||
// getting the name of the class is implementation defined, and cannot be
|
||||
|
@ -17,11 +17,22 @@
|
||||
|
||||
HexdumpWidget::HexdumpWidget(MainWindow *main, QAction *action) :
|
||||
MemoryDockWidget(CutterCore::MemoryWidgetType::Hexdump, main, action),
|
||||
ui(new Ui::HexdumpWidget)
|
||||
ui(new Ui::HexdumpWidget),
|
||||
seekable(new CutterSeekable(this))
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
setObjectName("HexdumpWidget");
|
||||
/*
|
||||
* Ugly hack just for the layout issue
|
||||
* QSettings saves the state with the object names
|
||||
* By doing this hack,
|
||||
* you can at least avoid some mess by dismissing all the Extra Widgets
|
||||
*/
|
||||
QString name = "Hexdump";
|
||||
if (!action) {
|
||||
name = "Extra Hexdump";
|
||||
}
|
||||
setObjectName(name);
|
||||
|
||||
ui->copyMD5->setIcon(QIcon(":/img/icons/copy.svg"));
|
||||
ui->copySHA1->setIcon(QIcon(":/img/icons/copy.svg"));
|
||||
@ -151,6 +162,19 @@ void HexdumpWidget::on_parseBitsComboBox_currentTextChanged(const QString &/*arg
|
||||
refreshSelectionInfo();
|
||||
}
|
||||
|
||||
|
||||
void HexdumpWidget::toggleSync()
|
||||
{
|
||||
QString windowTitle = tr("Hexdump");
|
||||
seekable->toggleSynchronization();
|
||||
if (seekable->isSynchronized()) {
|
||||
setWindowTitle(windowTitle);
|
||||
} else {
|
||||
setWindowTitle(windowTitle + CutterSeekable::tr(" (unsynced)"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HexdumpWidget::setupFonts()
|
||||
{
|
||||
QFont font = Config()->getFont();
|
||||
|
@ -37,6 +37,7 @@ public:
|
||||
public slots:
|
||||
void initParsing();
|
||||
|
||||
void toggleSync();
|
||||
protected:
|
||||
virtual void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
@ -57,6 +58,7 @@ private:
|
||||
void clearParseWindow();
|
||||
|
||||
QAction syncAction;
|
||||
CutterSeekable *seekable;
|
||||
|
||||
private slots:
|
||||
void onSeekChanged(RVA addr);
|
||||
|
@ -1,32 +1,12 @@
|
||||
#include "MemoryDockWidget.h"
|
||||
#include "common/CutterSeekable.h"
|
||||
|
||||
#include <QAction>
|
||||
|
||||
MemoryDockWidget::MemoryDockWidget(CutterCore::MemoryWidgetType type, MainWindow *parent, QAction *action)
|
||||
: CutterDockWidget(parent, action)
|
||||
, mType(type), seekable(new CutterSeekable(this))
|
||||
, mType(type)
|
||||
{
|
||||
connect(Core(), &CutterCore::raisePrioritizedMemoryWidget, this, &MemoryDockWidget::handleRaiseMemoryWidget);
|
||||
connect(seekable, &CutterSeekable::syncChanged, this, [this]() {
|
||||
if (seekable->isSynchronized()) {
|
||||
setWindowTitle(windowTitle().remove(CutterSeekable::tr(" (unsynced)")));
|
||||
} else {
|
||||
setWindowTitle(windowTitle() + CutterSeekable::tr(" (unsynced)"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bool MemoryDockWidget::isSynced() const
|
||||
{
|
||||
return seekable && seekable->isSynchronized();
|
||||
}
|
||||
|
||||
void MemoryDockWidget::toggleSync()
|
||||
{
|
||||
if (seekable) {
|
||||
seekable->toggleSynchronization();
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryDockWidget::handleRaiseMemoryWidget(CutterCore::MemoryWidgetType raiseType)
|
||||
|
@ -4,8 +4,6 @@
|
||||
#include "CutterDockWidget.h"
|
||||
#include "core/Cutter.h"
|
||||
|
||||
class CutterSeekable;
|
||||
|
||||
class MemoryDockWidget : public CutterDockWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -13,19 +11,10 @@ public:
|
||||
MemoryDockWidget(CutterCore::MemoryWidgetType type, MainWindow *parent, QAction *action = nullptr);
|
||||
~MemoryDockWidget() {}
|
||||
|
||||
bool isSynced() const;
|
||||
|
||||
public slots:
|
||||
void toggleSync();
|
||||
|
||||
private:
|
||||
void handleRaiseMemoryWidget(CutterCore::MemoryWidgetType raiseType);
|
||||
|
||||
CutterCore::MemoryWidgetType mType;
|
||||
|
||||
protected:
|
||||
CutterSeekable *seekable = nullptr;
|
||||
|
||||
};
|
||||
|
||||
#endif // MEMORYDOCKWIDGET_H
|
||||
|
Loading…
Reference in New Issue
Block a user