From 72eab68be1c7666f19a071bf02d70b9e17c05b72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Wed, 15 May 2019 20:45:16 +0200 Subject: [PATCH] Revert "Fix layout save and restore feature (#1515)" (#1537) This reverts commit 2ba9e170c5804ae038506cc3c1282419c3248947. --- src/common/CutterSeekable.cpp | 1 - src/common/CutterSeekable.h | 2 +- src/core/MainWindow.cpp | 264 ++++++-------------------- src/core/MainWindow.h | 16 +- src/widgets/CutterDockWidget.cpp | 14 +- src/widgets/CutterDockWidget.h | 1 - src/widgets/DisassemblerGraphView.cpp | 16 +- src/widgets/DisassemblerGraphView.h | 4 +- src/widgets/DisassemblyWidget.cpp | 24 ++- src/widgets/DisassemblyWidget.h | 2 + src/widgets/GraphWidget.cpp | 14 +- src/widgets/HexdumpWidget.cpp | 28 ++- src/widgets/HexdumpWidget.h | 4 +- src/widgets/MemoryDockWidget.cpp | 22 +-- src/widgets/MemoryDockWidget.h | 11 -- 15 files changed, 147 insertions(+), 276 deletions(-) diff --git a/src/common/CutterSeekable.cpp b/src/common/CutterSeekable.cpp index bf53ffc5..0be56ee3 100644 --- a/src/common/CutterSeekable.cpp +++ b/src/common/CutterSeekable.cpp @@ -50,7 +50,6 @@ void CutterSeekable::toggleSynchronization() { synchronized = !synchronized; onCoreSeekChanged(Core()->getOffset()); - emit syncChanged(); } bool CutterSeekable::isSynchronized() diff --git a/src/common/CutterSeekable.h b/src/common/CutterSeekable.h index 58664d4d..617cd262 100644 --- a/src/common/CutterSeekable.h +++ b/src/common/CutterSeekable.h @@ -82,5 +82,5 @@ private: signals: void seekableSeekChanged(RVA addr); - void syncChanged(); + }; diff --git a/src/core/MainWindow.cpp b/src/core/MainWindow.cpp index 6140ce04..880fbef1 100644 --- a/src/core/MainWindow.cpp +++ b/src/core/MainWindow.cpp @@ -105,9 +105,6 @@ #include #include -template -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, ui->actionGraph}); - mapper.insert("DisassemblyWidget", {getNewInstance, ui->actionDisassembly}); - mapper.insert("HexdumpWidget", {getNewInstance, 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(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(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(it); - } else if (className == "DisassemblyWidget") { - disassemblyDock = qobject_cast(it); - } else if (className == "HexdumpWidget") { - hexdumpDock = qobject_cast(it); - } - } -} - -void MainWindow::addWidget(QDockWidget* widget) -{ - dockWidgets.push_back(widget); - for (auto action : widget->actions()) { - dockWidgetsOfAction.insert(action, widget); - connect(qobject_cast(widget), &CutterDockWidget::closed, - this, [this]() { - QDockWidget *widget = qobject_cast(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 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 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 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. * diff --git a/src/core/MainWindow.h b/src/core/MainWindow.h index ef6e91b2..5d50433d 100644 --- a/src/core/MainWindow.h +++ b/src/core/MainWindow.h @@ -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 dockWidgets; - QMultiMap dockWidgetsOfAction; + QMap 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, QAction*>> mapper; - - QString getUniqueObjectName(const QString &className) const; }; #endif // MAINWINDOW_H diff --git a/src/widgets/CutterDockWidget.cpp b/src/widgets/CutterDockWidget.cpp index 6b925be2..8f4d5822 100644 --- a/src/widgets/CutterDockWidget.cpp +++ b/src/widgets/CutterDockWidget.cpp @@ -8,12 +8,12 @@ CutterDockWidget::CutterDockWidget(MainWindow *parent, QAction *action) : QDockWidget(parent), action(action) { - if (action) { - addAction(action); - connect(action, &QAction::triggered, this, &CutterDockWidget::toggleDockWidget); - } if (parent) { - parent->addWidget(this); + parent->addToDockWidgetList(this); + if (action) { + parent->addDockWidgetAction(this, action); + connect(action, &QAction::triggered, this, &CutterDockWidget::toggleDockWidget); + } } // 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 diff --git a/src/widgets/CutterDockWidget.h b/src/widgets/CutterDockWidget.h index 96a9bfdb..8793a4c2 100644 --- a/src/widgets/CutterDockWidget.h +++ b/src/widgets/CutterDockWidget.h @@ -57,7 +57,6 @@ public: signals: void becameVisibleToUser(); - void closed(); public slots: void toggleDockWidget(bool show); diff --git a/src/widgets/DisassemblerGraphView.cpp b/src/widgets/DisassemblerGraphView.cpp index 21de228c..e1f5eac8 100644 --- a/src/widgets/DisassemblerGraphView.cpp +++ b/src/widgets/DisassemblerGraphView.cpp @@ -28,12 +28,12 @@ #include -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(); diff --git a/src/widgets/DisassemblerGraphView.h b/src/widgets/DisassemblerGraphView.h index f1b02af0..4cc6343e 100644 --- a/src/widgets/DisassemblerGraphView.h +++ b/src/widgets/DisassemblerGraphView.h @@ -84,7 +84,7 @@ class DisassemblerGraphView : public GraphView }; public: - DisassemblerGraphView(QWidget *parent, CutterSeekable* seekable); + DisassemblerGraphView(QWidget *parent); ~DisassemblerGraphView() override; std::unordered_map 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(); diff --git a/src/widgets/DisassemblyWidget.cpp b/src/widgets/DisassemblyWidget.cpp index c84d5c65..3c219a5c 100644 --- a/src/widgets/DisassemblyWidget.cpp +++ b/src/widgets/DisassemblyWidget.cpp @@ -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 diff --git a/src/widgets/DisassemblyWidget.h b/src/widgets/DisassemblyWidget.h index 737d3067..1ab5787d 100644 --- a/src/widgets/DisassemblyWidget.h +++ b/src/widgets/DisassemblyWidget.h @@ -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 getSameWordsSelections(); QAction syncIt; + CutterSeekable *seekable; }; class DisassemblyScrollArea : public QAbstractScrollArea diff --git a/src/widgets/GraphWidget.cpp b/src/widgets/GraphWidget.cpp index 6a38a957..bb1c62b4 100644 --- a/src/widgets/GraphWidget.cpp +++ b/src/widgets/GraphWidget.cpp @@ -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 diff --git a/src/widgets/HexdumpWidget.cpp b/src/widgets/HexdumpWidget.cpp index ee43a8a0..899c1ddb 100644 --- a/src/widgets/HexdumpWidget.cpp +++ b/src/widgets/HexdumpWidget.cpp @@ -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(); diff --git a/src/widgets/HexdumpWidget.h b/src/widgets/HexdumpWidget.h index 9bb51ca8..3386943e 100644 --- a/src/widgets/HexdumpWidget.h +++ b/src/widgets/HexdumpWidget.h @@ -32,11 +32,12 @@ class HexdumpWidget : public MemoryDockWidget public: explicit HexdumpWidget(MainWindow *main, QAction *action = nullptr); ~HexdumpWidget(); - Highlighter *highlighter; + Highlighter *highlighter; 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); diff --git a/src/widgets/MemoryDockWidget.cpp b/src/widgets/MemoryDockWidget.cpp index 4d59f252..84495643 100644 --- a/src/widgets/MemoryDockWidget.cpp +++ b/src/widgets/MemoryDockWidget.cpp @@ -1,32 +1,12 @@ #include "MemoryDockWidget.h" -#include "common/CutterSeekable.h" #include 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) diff --git a/src/widgets/MemoryDockWidget.h b/src/widgets/MemoryDockWidget.h index 3da15d7b..65cbee05 100644 --- a/src/widgets/MemoryDockWidget.h +++ b/src/widgets/MemoryDockWidget.h @@ -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