diff options
author | hjk <hjk@qt.io> | 2018-09-04 13:29:15 +0200 |
---|---|---|
committer | hjk <hjk@qt.io> | 2018-09-11 08:48:31 +0000 |
commit | bdc1ea1d7442a3938de693d576cddb5473c5c3cd (patch) | |
tree | 5b94214adc6556bdccde0945669ebaa1fa46e5ac /src/plugins/debugger | |
parent | 892be5a70c92c728e82603da8f02c5eb0df89f6b (diff) | |
download | qt-creator-bdc1ea1d7442a3938de693d576cddb5473c5c3cd.tar.gz |
Debugger: Do not remember persistent layout settings per engine
Fixes: QTCREATORBUG-21006
Change-Id: Id3c2062eb5b42808d666f0fc3620a82666fe14a2
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Diffstat (limited to 'src/plugins/debugger')
-rw-r--r-- | src/plugins/debugger/debuggerengine.cpp | 62 | ||||
-rw-r--r-- | src/plugins/debugger/debuggerengine.h | 6 | ||||
-rw-r--r-- | src/plugins/debugger/debuggermainwindow.cpp | 414 | ||||
-rw-r--r-- | src/plugins/debugger/debuggermainwindow.h | 12 | ||||
-rw-r--r-- | src/plugins/debugger/debuggerplugin.cpp | 2 | ||||
-rw-r--r-- | src/plugins/debugger/debuggerruncontrol.cpp | 11 | ||||
-rw-r--r-- | src/plugins/debugger/qml/qmlengine.cpp | 2 | ||||
-rw-r--r-- | src/plugins/debugger/snapshothandler.cpp | 75 | ||||
-rw-r--r-- | src/plugins/debugger/snapshothandler.h | 1 |
9 files changed, 317 insertions, 268 deletions
diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index 0b6a6d55f0..49138ef1e1 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -288,7 +288,6 @@ public: this, [this] { updateState(true); }); } - ~DebuggerEnginePrivate() { destroyPerspective(); @@ -324,6 +323,9 @@ public: if (!m_perspective) return; + delete m_perspective; + m_perspective = nullptr; + EngineManager::unregisterEngine(m_engine); // Give up ownership on claimed breakpoints. @@ -331,9 +333,6 @@ public: m_toolTipManager.deregisterEngine(); m_memoryAgents.handleDebuggerFinished(); - delete m_perspective; - m_perspective = nullptr; - setBusyCursor(false); } @@ -419,6 +418,7 @@ public: void updateReverseActions(); DebuggerEngine *m_engine = nullptr; // Not owned. + QString m_runId; QPointer<RunConfiguration> m_runConfiguration; // Not owned. QString m_debuggerName; Perspective *m_perspective = nullptr; @@ -518,9 +518,14 @@ void DebuggerEnginePrivate::setupViews() const DebuggerRunParameters &rp = m_runParameters; QTC_CHECK(!m_perspective); - const QString perspectiveId = "Debugger.Perspective." + m_debuggerName + '.' + rp.displayName; - m_perspective = new Perspective(perspectiveId, m_engine->displayName(), - Debugger::Constants::PRESET_PERSPECTIVE_ID); + + m_perspective = new Perspective("Debugger.Perspective." + m_runId, + m_engine->displayName(), + Debugger::Constants::PRESET_PERSPECTIVE_ID, + m_debuggerName); + m_perspective->setShouldPersistChecker([this] { + return EngineManager::isLastOf(m_debuggerName); + }); m_progress.setProgressRange(0, 1000); FutureProgress *fp = ProgressManager::addTask(m_progress.future(), @@ -562,10 +567,6 @@ void DebuggerEnginePrivate::setupViews() QSettings *settings = ICore::settings(); - auto dockId = [perspectiveId](const QString &dockname) { - return QString(dockname + '.' + perspectiveId); - }; - m_modulesView = new BaseTreeView; m_modulesView->setModel(m_modulesHandler.model()); m_modulesView->setSortingEnabled(true); @@ -574,7 +575,7 @@ void DebuggerEnginePrivate::setupViews() m_engine, &DebuggerEngine::reloadModules, Qt::QueuedConnection); m_modulesWindow = addSearch(m_modulesView); - m_modulesWindow->setObjectName(dockId(DOCKWIDGET_MODULES)); + m_modulesWindow->setObjectName(DOCKWIDGET_MODULES); m_modulesWindow->setWindowTitle(tr("&Modules")); m_registerView = new BaseTreeView; @@ -585,7 +586,7 @@ void DebuggerEnginePrivate::setupViews() m_engine, &DebuggerEngine::reloadRegisters, Qt::QueuedConnection); m_registerWindow = addSearch(m_registerView); - m_registerWindow->setObjectName(dockId(DOCKWIDGET_REGISTER)); + m_registerWindow->setObjectName(DOCKWIDGET_REGISTER); m_registerWindow->setWindowTitle(tr("Reg&isters")); m_stackView = new BaseTreeView; @@ -593,7 +594,7 @@ void DebuggerEnginePrivate::setupViews() m_stackView->setSettings(settings, "Debugger.StackView"); m_stackView->setIconSize(QSize(10, 10)); m_stackWindow = addSearch(m_stackView); - m_stackWindow->setObjectName(dockId(DOCKWIDGET_STACK)); + m_stackWindow->setObjectName(DOCKWIDGET_STACK); m_stackWindow->setWindowTitle(tr("&Stack")); m_sourceFilesView = new BaseTreeView; @@ -604,7 +605,7 @@ void DebuggerEnginePrivate::setupViews() m_engine, &DebuggerEngine::reloadSourceFiles, Qt::QueuedConnection); m_sourceFilesWindow = addSearch(m_sourceFilesView); - m_sourceFilesWindow->setObjectName(dockId(DOCKWIDGET_SOURCE_FILES)); + m_sourceFilesWindow->setObjectName(DOCKWIDGET_SOURCE_FILES); m_sourceFilesWindow->setWindowTitle(tr("Source Files")); m_threadsView = new BaseTreeView; @@ -613,13 +614,13 @@ void DebuggerEnginePrivate::setupViews() m_threadsView->setSettings(settings, "Debugger.ThreadsView"); m_threadsView->setIconSize(QSize(10, 10)); m_threadsWindow = addSearch(m_threadsView); - m_threadsWindow->setObjectName(dockId(DOCKWIDGET_THREADS)); + m_threadsWindow->setObjectName(DOCKWIDGET_THREADS); m_threadsWindow->setWindowTitle(tr("&Threads")); m_returnView = new WatchTreeView{ReturnType}; m_returnView->setModel(m_watchHandler.model()); m_returnWindow = addSearch(m_returnView); - m_returnWindow->setObjectName(dockId("CppDebugReturn")); + m_returnWindow->setObjectName("CppDebugReturn"); m_returnWindow->setWindowTitle(tr("Locals")); m_returnWindow->setVisible(false); @@ -627,26 +628,26 @@ void DebuggerEnginePrivate::setupViews() m_localsView->setModel(m_watchHandler.model()); m_localsView->setSettings(settings, "Debugger.LocalsView"); m_localsWindow = addSearch(m_localsView); - m_localsWindow->setObjectName(dockId("CppDebugLocals")); + m_localsWindow->setObjectName("CppDebugLocals"); m_localsWindow->setWindowTitle(tr("Locals")); m_inspectorView = new WatchTreeView{InspectType}; m_inspectorView->setModel(m_watchHandler.model()); m_inspectorView->setSettings(settings, "Debugger.LocalsView"); // sic! same as locals view. m_inspectorWindow = addSearch(m_inspectorView); - m_inspectorWindow->setObjectName(dockId("Inspector")); + m_inspectorWindow->setObjectName("Inspector"); m_inspectorWindow->setWindowTitle(tr("Locals")); m_watchersView = new WatchTreeView{WatchersType}; m_watchersView->setModel(m_watchHandler.model()); m_watchersView->setSettings(settings, "Debugger.WatchersView"); m_watchersWindow = addSearch(m_watchersView); - m_watchersWindow->setObjectName(dockId("CppDebugWatchers")); + m_watchersWindow->setObjectName("CppDebugWatchers"); m_watchersWindow->setWindowTitle(tr("&Expressions")); m_localsAndInspectorWindow = new LocalsAndInspectorWindow( m_localsWindow, m_inspectorWindow, m_returnWindow); - m_localsAndInspectorWindow->setObjectName(dockId(DOCKWIDGET_LOCALS_AND_INSPECTOR)); + m_localsAndInspectorWindow->setObjectName(DOCKWIDGET_LOCALS_AND_INSPECTOR); m_localsAndInspectorWindow->setWindowTitle(m_localsWindow->windowTitle()); // Locals @@ -663,10 +664,10 @@ void DebuggerEnginePrivate::setupViews() m_breakView->setModel(m_breakHandler.model()); m_breakView->setRootIsDecorated(true); m_breakWindow = addSearch(m_breakView); - m_breakWindow->setObjectName(dockId(DOCKWIDGET_BREAK)); + m_breakWindow->setObjectName(DOCKWIDGET_BREAK); m_breakWindow->setWindowTitle(tr("&Breakpoints")); - m_perspective->addToolBarWidget(EngineManager::engineChooser()); + m_perspective->addToolBarSwitcher(EngineManager::engineChooser(), false); m_perspective->addToolBarAction(&m_continueAction); m_perspective->addToolBarAction(&m_interruptAction); @@ -798,6 +799,11 @@ void DebuggerEngine::setDebuggerName(const QString &name) d->m_debuggerName = name; } +QString DebuggerEngine::debuggerName() const +{ + return d->m_debuggerName; +} + QString DebuggerEngine::stateName(int s) { # define SN(x) case x: return QLatin1String(#x); @@ -930,6 +936,11 @@ void DebuggerEngine::setRunParameters(const DebuggerRunParameters &runParameters d->m_runParameters = runParameters; } +void DebuggerEngine::setRunId(const QString &id) +{ + d->m_runId = id; +} + void DebuggerEngine::setRunTool(DebuggerRunTool *runTool) { RunControl *runControl = runTool->runControl(); @@ -2444,6 +2455,11 @@ void DebuggerEngine::startDying() const other->d->m_isDying = true; } +QString DebuggerEngine::runId() const +{ + return d->m_runId; +} + bool DebuggerRunParameters::isCppDebugging() const { return cppEngineType == GdbEngineType diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h index ec5ae85f0e..b9a31caf51 100644 --- a/src/plugins/debugger/debuggerengine.h +++ b/src/plugins/debugger/debuggerengine.h @@ -233,6 +233,9 @@ public: void setRunTool(DebuggerRunTool *runTool); void setRunParameters(const DebuggerRunParameters &runParameters); + void setRunId(const QString &id); + QString runId() const; + const DebuggerRunParameters &runParameters() const; bool isStartupRunConfiguration() const; void setCompanionEngine(DebuggerEngine *engine); @@ -302,7 +305,7 @@ public: virtual void updateLocals(); virtual Core::Context languageContext() const { return {}; } - virtual QString displayName() const; + QString displayName() const; virtual bool stateAcceptsBreakpointChanges() const { return true; } virtual bool acceptsBreakpoint(const BreakpointParameters &bp) const = 0; @@ -415,6 +418,7 @@ public: WatchTreeView *inspectorView(); void updateLocalsWindow(bool showReturn); void raiseWatchersWindow(); + QString debuggerName() const; bool isRegistersWindowVisible() const; bool isModulesWindowVisible() const; diff --git a/src/plugins/debugger/debuggermainwindow.cpp b/src/plugins/debugger/debuggermainwindow.cpp index 3f04cf1896..bc7933df2c 100644 --- a/src/plugins/debugger/debuggermainwindow.cpp +++ b/src/plugins/debugger/debuggermainwindow.cpp @@ -68,64 +68,6 @@ const char OWNED_BY_PERSPECTIVE[] = "OwnedByPerspective"; static DebuggerMainWindow *theMainWindow = nullptr; -class ToolbarOperation -{ -public: - void attachToToolbar(QWidget *parent) - { - QLayout *layout = parent->layout(); - if (toolBarWidget) { - toolBarWidget->setParent(parent); - layout->addWidget(toolBarWidget); - } - if (toolBarAction) { - toolBarAction->m_toolButton = new QToolButton(parent); - toolBarAction->m_toolButton->setToolButtonStyle(toolBarAction->m_toolButtonStyle); - toolBarAction->m_toolButton->setProperty("panelwidget", true); - toolBarAction->m_toolButton->setDefaultAction(toolBarAction); - toolBarAction->m_toolButton->setVisible(toolBarAction->isVisible()); - layout->addWidget(toolBarAction->m_toolButton); - } - if (toolBarPlainAction) { - toolBarPlainActionButton = new QToolButton(parent); - toolBarPlainActionButton->setProperty("panelwidget", true); - toolBarPlainActionButton->setDefaultAction(toolBarPlainAction); - layout->addWidget(toolBarPlainActionButton); - } - if (separator) { - separator->setParent(parent); - layout->addWidget(separator); - } - } - - void detachFromToolbar() - { - if (toolBarWidget) { - toolBarWidget->setParent(nullptr); - } - if (toolBarAction) { - delete toolBarAction->m_toolButton; - toolBarAction->m_toolButton = nullptr; - } - if (toolBarPlainAction) { - delete toolBarPlainActionButton; - toolBarPlainActionButton = nullptr; - } - if (separator) { - separator->setParent(nullptr); - } - } - - QPointer<QAction> toolBarPlainAction; // Owned by plugin if present. - QPointer<OptionalAction> toolBarAction; // Owned by plugin if present. - QPointer<QWidget> toolBarWidget; // Owned by plugin if present. - - // Helper/wrapper widget owned by us if present. - QPointer<QToolButton> toolBarPlainActionButton; - QPointer<QWidget> toolBarWidgetParent; - QPointer<QWidget> separator; -}; - class DockOperation { public: @@ -139,21 +81,26 @@ public: class PerspectivePrivate { public: - ~PerspectivePrivate() { destroyToolBar(); } - void showToolBar(); void hideToolBar(); - void destroyToolBar(); + void restoreLayout(); + void saveLayout(); + QString settingsId() const; + QToolButton *setupToolButton(QAction *action); QString m_id; QString m_name; QString m_parentPerspectiveId; + QString m_subPerspectiveType; QVector<DockOperation> m_dockOperations; - QVector<ToolbarOperation> m_toolBarOperations; QPointer<QWidget> m_centralWidget; Perspective::Callback m_aboutToActivateCallback; - QPointer<QWidget> m_toolButtonBox; + QPointer<QWidget> m_innerToolBar; + QHBoxLayout *m_innerToolBarLayout = nullptr; + QPointer<QWidget> m_switcher; QString m_lastActiveSubPerspectiveId; + QHash<QString, QVariant> m_nonPersistenSettings; + Perspective::ShouldPersistChecker m_shouldPersistChecker; }; class DebuggerMainWindowPrivate : public QObject @@ -161,15 +108,13 @@ class DebuggerMainWindowPrivate : public QObject public: DebuggerMainWindowPrivate(DebuggerMainWindow *parent); - void ensureToolBarDockExists(); + void createToolBar(); void selectPerspective(Perspective *perspective); void depopulateCurrentPerspective(); void populateCurrentPerspective(); - void savePerspectiveHelper(const Perspective *perspective); void destroyPerspective(Perspective *perspective); void registerPerspective(Perspective *perspective); - void increaseChooserWidthIfNecessary(const QString &visibleName); void resetCurrentPerspective(); int indexInChooser(Perspective *perspective) const; @@ -177,7 +122,8 @@ public: Perspective *m_currentPerspective = nullptr; QComboBox *m_perspectiveChooser = nullptr; QStackedWidget *m_centralWidgetStack = nullptr; - QHBoxLayout *m_toolBarLayout = nullptr; + QHBoxLayout *m_subToolsSwitcherLayout = nullptr; + QHBoxLayout *m_innerToolsLayout = nullptr; QWidget *m_editorPlaceHolder = nullptr; Utils::StatusLabel *m_statusLabel = nullptr; QDockWidget *m_toolBarDock = nullptr; @@ -195,8 +141,9 @@ DebuggerMainWindowPrivate::DebuggerMainWindowPrivate(DebuggerMainWindow *parent) m_editorPlaceHolder = new EditorManagerPlaceHolder; m_perspectiveChooser = new QComboBox; - m_perspectiveChooser->setObjectName(QLatin1String("PerspectiveChooser")); + m_perspectiveChooser->setObjectName("PerspectiveChooser"); m_perspectiveChooser->setProperty("panelwidget", true); + m_perspectiveChooser->setSizeAdjustPolicy(QComboBox::AdjustToContents); connect(m_perspectiveChooser, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), this, [this](int item) { Perspective *perspective = Perspective::findPerspective(m_perspectiveChooser->itemData(item).toString()); @@ -206,6 +153,62 @@ DebuggerMainWindowPrivate::DebuggerMainWindowPrivate(DebuggerMainWindow *parent) else perspective->select(); }); + + auto viewButton = new QToolButton; + viewButton->setText(tr("&Views")); + + auto closeButton = new QToolButton(); + closeButton->setIcon(Utils::Icons::CLOSE_SPLIT_BOTTOM.icon()); + closeButton->setToolTip(tr("Leave Debug Mode")); + + auto toolbar = new Utils::StyledBar; + toolbar->setProperty("topBorder", true); + + // "Engine switcher" style comboboxes + auto subToolsSwitcher = new QWidget; + m_subToolsSwitcherLayout = new QHBoxLayout(subToolsSwitcher); + m_subToolsSwitcherLayout->setMargin(0); + m_subToolsSwitcherLayout->setSpacing(0); + + // All perspective toolbars will get inserted here, but only + // the current perspective's toolbar is set visible. + auto innerTools = new QWidget; + m_innerToolsLayout = new QHBoxLayout(innerTools); + m_innerToolsLayout->setMargin(0); + m_innerToolsLayout->setSpacing(0); + + auto hbox = new QHBoxLayout(toolbar); + hbox->setMargin(0); + hbox->setSpacing(0); + hbox->addWidget(m_perspectiveChooser); + hbox->addWidget(subToolsSwitcher); + hbox->addWidget(innerTools); + hbox->addWidget(m_statusLabel); + hbox->addStretch(1); + hbox->addWidget(new Utils::StyledSeparator); + hbox->addWidget(viewButton); + hbox->addWidget(closeButton); + + auto dock = new QDockWidget(tr("Toolbar"), q); + dock->setObjectName(QLatin1String("Toolbar")); + dock->setFeatures(QDockWidget::NoDockWidgetFeatures); + dock->setAllowedAreas(Qt::BottomDockWidgetArea); + dock->setTitleBarWidget(new QWidget(dock)); // hide title bar + dock->setProperty("managed_dockwidget", QLatin1String("true")); + toolbar->setParent(dock); + dock->setWidget(toolbar); + m_toolBarDock = dock; + q->addDockWidget(Qt::BottomDockWidgetArea, m_toolBarDock); + + connect(viewButton, &QAbstractButton::clicked, [this, viewButton] { + QMenu menu; + q->addDockActionsToMenu(&menu); + menu.exec(viewButton->mapToGlobal(QPoint())); + }); + + connect(closeButton, &QAbstractButton::clicked, [] { + ModeManager::activateMode(Core::Constants::MODE_EDIT); + }); } DebuggerMainWindow::DebuggerMainWindow() @@ -246,7 +249,6 @@ DebuggerMainWindow::DebuggerMainWindow() DebuggerMainWindow::~DebuggerMainWindow() { - d->savePerspectiveHelper(d->m_currentPerspective); delete d; } @@ -264,30 +266,20 @@ void DebuggerMainWindow::doShutdown() void DebuggerMainWindowPrivate::registerPerspective(Perspective *perspective) { - m_perspectives.append(perspective); QString parentPerspective = perspective->d->m_parentPerspectiveId; // Add only "main" perspectives to the chooser. - if (parentPerspective.isEmpty()) { - m_perspectiveChooser->addItem(perspective->name(), perspective->id()); - increaseChooserWidthIfNecessary(perspective->name()); - } -} - -void DebuggerMainWindowPrivate::increaseChooserWidthIfNecessary(const QString &visibleName) -{ - const int oldWidth = m_perspectiveChooser->width(); - const int contentWidth = m_perspectiveChooser->fontMetrics().width(visibleName); - QStyleOptionComboBox option; - option.initFrom(m_perspectiveChooser); - const QSize sz(contentWidth, 1); - const int width = m_perspectiveChooser->style()->sizeFromContents( - QStyle::CT_ComboBox, &option, sz).width(); - if (width > oldWidth) - m_perspectiveChooser->setFixedWidth(width); + if (parentPerspective.isEmpty()) + m_perspectiveChooser->addItem(perspective->d->m_name, perspective->d->m_id); + m_perspectives.append(perspective); } void DebuggerMainWindowPrivate::destroyPerspective(Perspective *perspective) { + if (perspective == m_currentPerspective) { + depopulateCurrentPerspective(); + m_currentPerspective = nullptr; + } + m_perspectives.removeAll(perspective); // Dynamic perspectives are currently not visible in the chooser. @@ -295,14 +287,6 @@ void DebuggerMainWindowPrivate::destroyPerspective(Perspective *perspective) const int idx = indexInChooser(perspective); if (idx != -1) m_perspectiveChooser->removeItem(idx); - - if (perspective == m_currentPerspective) { - m_currentPerspective = nullptr; - if (!perspective->d->m_parentPerspectiveId.isEmpty()) { - if (Perspective *parent = Perspective::findPerspective(perspective->d->m_parentPerspectiveId)) - parent->select(); - } - } } void DebuggerMainWindow::showStatusMessage(const QString &message, int timeoutMS) @@ -330,6 +314,9 @@ void DebuggerMainWindow::onModeChanged(Core::Id mode) QTC_ASSERT(perspective, return); perspective->select(); } else { + if (Perspective *perspective = theMainWindow->d->m_currentPerspective) + perspective->d->saveLayout(); + theMainWindow->setDockActionsVisible(false); // Hide dock widgets manually in case they are floating. @@ -359,6 +346,10 @@ Perspective *Perspective::findPerspective(const QString &perspectiveId) void DebuggerMainWindowPrivate::resetCurrentPerspective() { + if (m_currentPerspective) { + m_currentPerspective->d->m_nonPersistenSettings.clear(); + m_currentPerspective->d->hideToolBar(); + } depopulateCurrentPerspective(); populateCurrentPerspective(); } @@ -372,6 +363,11 @@ void DebuggerMainWindowPrivate::selectPerspective(Perspective *perspective) { QTC_ASSERT(perspective, return); + if (m_currentPerspective) { + m_currentPerspective->d->saveLayout(); + m_currentPerspective->d->hideToolBar(); + } + depopulateCurrentPerspective(); m_currentPerspective = perspective; @@ -380,64 +376,21 @@ void DebuggerMainWindowPrivate::selectPerspective(Perspective *perspective) populateCurrentPerspective(); - QSettings *settings = ICore::settings(); - settings->beginGroup(perspective->d->m_id); - if (settings->value(QLatin1String("ToolSettingsSaved"), false).toBool()) - q->restoreSettings(settings); - settings->endGroup(); + if (m_currentPerspective) + m_currentPerspective->d->restoreLayout(); const int index = indexInChooser(m_currentPerspective); - if (index != -1) + if (index != -1) { m_perspectiveChooser->setCurrentIndex(index); -} - -void DebuggerMainWindowPrivate::ensureToolBarDockExists() -{ - if (m_toolBarDock) - return; - - auto viewButton = new QToolButton; - viewButton->setText(tr("&Views")); - - auto closeButton = new QToolButton(); - closeButton->setIcon(Utils::Icons::CLOSE_SPLIT_BOTTOM.icon()); - closeButton->setToolTip(tr("Leave Debug Mode")); - - auto toolbar = new Utils::StyledBar; - toolbar->setProperty("topBorder", true); - auto hbox = new QHBoxLayout(toolbar); - m_toolBarLayout = hbox; - hbox->setMargin(0); - hbox->setSpacing(0); - hbox->addWidget(m_perspectiveChooser); - // <- All perspective toolbars will get inserted here, but only - // the current perspective's toolbar is set visible. - hbox->addWidget(m_statusLabel); - hbox->addStretch(1); - hbox->addWidget(new Utils::StyledSeparator); - hbox->addWidget(viewButton); - hbox->addWidget(closeButton); - - auto dock = new QDockWidget(tr("Toolbar"), q); - dock->setObjectName(QLatin1String("Toolbar")); - dock->setFeatures(QDockWidget::NoDockWidgetFeatures); - dock->setAllowedAreas(Qt::BottomDockWidgetArea); - dock->setTitleBarWidget(new QWidget(dock)); // hide title bar - dock->setProperty("managed_dockwidget", QLatin1String("true")); - dock->setWidget(toolbar); - m_toolBarDock = dock; - q->addDockWidget(Qt::BottomDockWidgetArea, m_toolBarDock); - m_toolBarDock->setVisible(true); - - connect(viewButton, &QAbstractButton::clicked, [this, viewButton] { - QMenu menu; - q->addDockActionsToMenu(&menu); - menu.exec(viewButton->mapToGlobal(QPoint())); - }); - connect(closeButton, &QAbstractButton::clicked, [] { - ModeManager::activateMode(Core::Constants::MODE_EDIT); - }); + const int contentWidth = m_perspectiveChooser->fontMetrics().width(perspective->d->m_name); + QStyleOptionComboBox option; + option.initFrom(m_perspectiveChooser); + const QSize sz(contentWidth, 1); + const int width = m_perspectiveChooser->style()->sizeFromContents( + QStyle::CT_ComboBox, &option, sz).width(); + m_perspectiveChooser->setFixedWidth(width); + } } QWidget *createModeWindow(const Core::Id &mode) @@ -493,7 +446,6 @@ QWidget *createModeWindow(const Core::Id &mode) void DebuggerMainWindowPrivate::depopulateCurrentPerspective() { // Clean up old perspective. - savePerspectiveHelper(m_currentPerspective); for (QDockWidget *dock : q->dockWidgets()) { if (dock->property(OWNED_BY_PERSPECTIVE).toBool()) { // Prevent deletion of plugin-owned widgets. @@ -509,8 +461,6 @@ void DebuggerMainWindowPrivate::depopulateCurrentPerspective() ICore::removeAdditionalContext(m_currentPerspective->context()); QWidget *central = m_currentPerspective->centralWidget(); m_centralWidgetStack->removeWidget(central ? central : m_editorPlaceHolder); - - m_currentPerspective->d->hideToolBar(); } } @@ -552,7 +502,6 @@ void DebuggerMainWindowPrivate::populateCurrentPerspective() } QDockWidget *anchor = dockForDockId.value(op.anchorDockId); if (!anchor && op.area == Qt::BottomDockWidgetArea) { - ensureToolBarDockExists(); anchor = m_toolBarDock; } @@ -585,33 +534,40 @@ void DebuggerMainWindowPrivate::populateCurrentPerspective() ICore::addAdditionalContext(m_currentPerspective->context()); } -void DebuggerMainWindowPrivate::savePerspectiveHelper(const Perspective *perspective) -{ - if (!perspective) - return; - QSettings *settings = ICore::settings(); - settings->beginGroup(perspective->d->m_id); - q->saveSettings(settings); - settings->setValue(QLatin1String("ToolSettingsSaved"), true); - settings->endGroup(); -} - // Perspective -Perspective::Perspective(const QString &id, const QString &name, const QString &parentPerspectiveId) +Perspective::Perspective(const QString &id, const QString &name, + const QString &parentPerspectiveId, + const QString &subPerspectiveType) : d(new PerspectivePrivate) { + const bool shouldPersist = parentPerspectiveId.isEmpty(); d->m_id = id; d->m_name = name; d->m_parentPerspectiveId = parentPerspectiveId; + d->m_subPerspectiveType = subPerspectiveType; + d->m_shouldPersistChecker = [shouldPersist] { return shouldPersist; }; DebuggerMainWindow::ensureMainWindowExists(); theMainWindow->d->registerPerspective(this); + + d->m_innerToolBar = new QWidget; + d->m_innerToolBar->setVisible(false); + theMainWindow->d->m_innerToolsLayout->addWidget(d->m_innerToolBar); + + d->m_innerToolBarLayout = new QHBoxLayout(d->m_innerToolBar); + d->m_innerToolBarLayout->setMargin(0); + d->m_innerToolBarLayout->setSpacing(0); } Perspective::~Perspective() { if (theMainWindow) { + d->saveLayout(); + + delete d->m_innerToolBar; + d->m_innerToolBar = nullptr; + theMainWindow->d->destroyPerspective(this); } delete d; @@ -623,11 +579,6 @@ void Perspective::setCentralWidget(QWidget *centralWidget) d->m_centralWidget = centralWidget; } -QString Perspective::name() const -{ - return d->m_name; -} - QString Perspective::id() const { return d->m_id; @@ -655,36 +606,50 @@ void Perspective::setEnabled(bool enabled) item->setFlags(enabled ? item->flags() | Qt::ItemIsEnabled : item->flags() & ~Qt::ItemIsEnabled ); } +QToolButton *PerspectivePrivate::setupToolButton(QAction *action) +{ + auto toolButton = new QToolButton(m_innerToolBar); + toolButton->setProperty("panelwidget", true); + toolButton->setDefaultAction(action); + m_innerToolBarLayout->addWidget(toolButton); + return toolButton; +} + void Perspective::addToolBarAction(QAction *action) { - auto toolButton = new QToolButton; - ToolbarOperation op; - op.toolBarPlainAction = action; - op.toolBarPlainActionButton = toolButton; - d->m_toolBarOperations.append(op); + d->setupToolButton(action); } void Perspective::addToolBarAction(OptionalAction *action) { - ToolbarOperation op; - op.toolBarAction = action; - d->m_toolBarOperations.append(op); + action->m_toolButton = d->setupToolButton(action); } void Perspective::addToolBarWidget(QWidget *widget) { - ToolbarOperation op; - op.toolBarWidget = widget; // QStyle::polish is called before it is added to the toolbar, explicitly make it a panel widget - op.toolBarWidget->setProperty("panelwidget", true); - d->m_toolBarOperations.append(op); + widget->setProperty("panelwidget", true); + widget->setParent(d->m_innerToolBar); + d->m_innerToolBarLayout->addWidget(widget); +} + +void Perspective::addToolBarSwitcher(QWidget *widget, bool owner) +{ + d->m_switcher = widget; + d->m_switcher->setProperty("panelwidget", true); + d->m_switcher->setVisible(false); + if (owner) + theMainWindow->d->m_subToolsSwitcherLayout->addWidget(d->m_switcher); } void Perspective::addToolbarSeparator() { - ToolbarOperation op; - op.separator = new StyledSeparator; - d->m_toolBarOperations.append(op); + d->m_innerToolBarLayout->addWidget(new StyledSeparator(d->m_innerToolBar)); +} + +void Perspective::setShouldPersistChecker(const ShouldPersistChecker &checker) +{ + d->m_shouldPersistChecker = checker; } QWidget *Perspective::centralWidget() const @@ -704,39 +669,17 @@ Context Perspective::context() const void PerspectivePrivate::showToolBar() { - if (!m_toolButtonBox) { - m_toolButtonBox = new QWidget; - theMainWindow->d->m_toolBarLayout->insertWidget(1, m_toolButtonBox); - - auto hbox = new QHBoxLayout(m_toolButtonBox); - hbox->setMargin(0); - hbox->setSpacing(0); - for (ToolbarOperation &op : m_toolBarOperations) - op.attachToToolbar(m_toolButtonBox); - } - - for (ToolbarOperation &op : m_toolBarOperations) { - if (op.toolBarAction) - op.toolBarAction->m_toolButton->setVisible(op.toolBarAction->isVisible()); - } - - m_toolButtonBox->setVisible(true); + m_innerToolBar->setVisible(true); + if (m_switcher) + m_switcher->setVisible(true); } void PerspectivePrivate::hideToolBar() { - if (m_toolButtonBox) - m_toolButtonBox->setVisible(false); - -} -void PerspectivePrivate::destroyToolBar() -{ - // Detach potentially re-used widgets to prevent deletion. - for (ToolbarOperation &op : m_toolBarOperations) - op.detachFromToolbar(); - - delete m_toolButtonBox; - m_toolButtonBox = nullptr; + QTC_ASSERT(m_innerToolBar, return); + m_innerToolBar->setVisible(false); + if (m_switcher) + m_switcher->setVisible(false); } void Perspective::addWindow(QWidget *widget, @@ -765,7 +708,45 @@ void Perspective::select() parent->d->m_lastActiveSubPerspectiveId = d->m_id; else d->m_lastActiveSubPerspectiveId.clear(); - ICore::settings()->setValue(QLatin1String(LAST_PERSPECTIVE_KEY), d->m_id); + + const QString &lastKey = d->m_parentPerspectiveId.isEmpty() ? d->m_id : d->m_parentPerspectiveId; + ICore::settings()->setValue(QLatin1String(LAST_PERSPECTIVE_KEY), lastKey); +} + +void PerspectivePrivate::restoreLayout() +{ + if (m_nonPersistenSettings.isEmpty()) { + //qDebug() << "PERSPECTIVE" << m_id << "RESTORE PERSISTENT FROM " << settingsId(); + QSettings *settings = ICore::settings(); + settings->beginGroup(settingsId()); + theMainWindow->restoreSettings(settings); + settings->endGroup(); + m_nonPersistenSettings = theMainWindow->saveSettings(); + } else { + //qDebug() << "PERSPECTIVE" << m_id << "RESTORE FROM LOCAL TEMP"; + theMainWindow->restoreSettings(m_nonPersistenSettings); + } +} + +void PerspectivePrivate::saveLayout() +{ + //qDebug() << "PERSPECTIVE" << m_id << "SAVE LOCAL TEMP"; + m_nonPersistenSettings = theMainWindow->saveSettings(); + + if (m_shouldPersistChecker()) { + //qDebug() << "PERSPECTIVE" << m_id << "SAVE PERSISTENT TO " << settingsId(); + QSettings *settings = ICore::settings(); + settings->beginGroup(settingsId()); + theMainWindow->saveSettings(settings); + settings->endGroup(); + } else { + //qDebug() << "PERSPECTIVE" << m_id << "NOT PERSISTENT"; + } +} + +QString PerspectivePrivate::settingsId() const +{ + return m_parentPerspectiveId.isEmpty() ? m_id : (m_parentPerspectiveId + '.' + m_subPerspectiveType); } // ToolbarAction @@ -789,7 +770,8 @@ void OptionalAction::setVisible(bool on) void OptionalAction::setToolButtonStyle(Qt::ToolButtonStyle style) { - m_toolButtonStyle = style; + QTC_ASSERT(m_toolButton, return); + m_toolButton->setToolButtonStyle(style); } } // Utils diff --git a/src/plugins/debugger/debuggermainwindow.h b/src/plugins/debugger/debuggermainwindow.h index d950363e8c..da9072dfd0 100644 --- a/src/plugins/debugger/debuggermainwindow.h +++ b/src/plugins/debugger/debuggermainwindow.h @@ -57,14 +57,14 @@ public: public: QPointer<QToolButton> m_toolButton; - Qt::ToolButtonStyle m_toolButtonStyle = Qt::ToolButtonIconOnly; }; class DEBUGGER_EXPORT Perspective { public: Perspective(const QString &id, const QString &name, - const QString &parentPerspectiveId = QString()); + const QString &parentPerspectiveId = QString(), + const QString &subPerspectiveType = QString()); ~Perspective(); enum OperationType { SplitVertical, SplitHorizontal, AddToTab, Raise }; @@ -79,12 +79,14 @@ public: void addToolBarAction(QAction *action); void addToolBarAction(OptionalAction *action); void addToolBarWidget(QWidget *widget); + void addToolBarSwitcher(QWidget *widget, bool owner); void addToolbarSeparator(); - QWidget *centralWidget() const; + using ShouldPersistChecker = std::function<bool()>; + void setShouldPersistChecker(const ShouldPersistChecker &checker); - QString name() const; - QString id() const; + QString id() const; // Currently used by GammaRay plugin. + QWidget *centralWidget() const; using Callback = std::function<void()>; void setAboutToActivateCallback(const Callback &cb); diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index a24fe26dcf..d2d269afbf 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -1339,7 +1339,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments, connect(action(SettingsDialog), &QAction::triggered, [] { ICore::showOptionsDialog(DEBUGGER_COMMON_SETTINGS_ID); }); - m_perspective.addToolBarWidget(EngineManager::engineChooser()); + m_perspective.addToolBarSwitcher(EngineManager::engineChooser(), true); m_perspective.addToolBarAction(&m_startAction); // QAction *operateByInstructionAction = action(OperateByInstruction); diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp index e9902f0b3a..63848a6c74 100644 --- a/src/plugins/debugger/debuggerruncontrol.cpp +++ b/src/plugins/debugger/debuggerruncontrol.cpp @@ -256,6 +256,7 @@ public: int snapshotCounter = 0; int engineStartsNeeded = 0; int engineStopsNeeded = 0; + QString runId; }; } // namespace Internal @@ -616,6 +617,7 @@ void DebuggerRunTool::start() } m_engine->setRunParameters(m_runParameters); + m_engine->setRunId(d->runId); m_engine->setRunTool(this); m_engine->setCompanionEngine(m_engine2); connect(m_engine, &DebuggerEngine::requestRunControlFinish, @@ -645,6 +647,7 @@ void DebuggerRunTool::start() if (m_engine2) { m_engine2->setRunParameters(m_runParameters); + m_engine2->setRunId(d->runId); m_engine2->setRunTool(this); m_engine2->setCompanionEngine(m_engine); m_engine2->setSecondaryEngine(); @@ -880,6 +883,14 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, Kit *kit, bool allowTer { setId("DebuggerRunTool"); + static int toolRunCount = 0; + + // Reset once all are gone. + if (EngineManager::engines().isEmpty()) + toolRunCount = 0; + + d->runId = QString::number(++toolRunCount); + RunConfiguration *runConfig = runControl->runConfiguration(); runControl->setIcon(ProjectExplorer::Icons::DEBUG_START_SMALL_TOOLBAR); diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index 91bd3e2e55..ac9209ae1a 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -259,7 +259,7 @@ QmlEngine::QmlEngine() : d(new QmlEnginePrivate(this, new QmlDebugConnection(this))) { setObjectName("QmlEngine"); - setDebuggerName(tr("QML Debugger")); + setDebuggerName("QML"); QmlDebugConnection *connection = d->connection(); diff --git a/src/plugins/debugger/snapshothandler.cpp b/src/plugins/debugger/snapshothandler.cpp index a38653cd92..1d98b46c2c 100644 --- a/src/plugins/debugger/snapshothandler.cpp +++ b/src/plugins/debugger/snapshothandler.cpp @@ -51,6 +51,8 @@ using namespace Utils; namespace Debugger { namespace Internal { +const bool hideSwitcherUnlessNeeded = false; + #if 0 SnapshotData::SnapshotData() {} @@ -134,12 +136,13 @@ public: m_engineModel.rootItem()->appendChild(new EngineItem); // The preset case. m_engineChooser = new QComboBox; - m_engineChooser->setVisible(false); m_engineChooser->setModel(&m_engineModel); + m_engineChooser->setIconSize(QSize(0, 0)); + if (hideSwitcherUnlessNeeded) + m_engineChooser->hide(); + connect(m_engineChooser, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated), this, &EngineManagerPrivate::activateEngineByIndex); - connect(ModeManager::instance(), &ModeManager::currentModeChanged, - this, &EngineManagerPrivate::onModeChanged); } ~EngineManagerPrivate() @@ -147,15 +150,6 @@ public: delete m_engineChooser; } - void onModeChanged(Id mode) - { - if (mode == Constants::MODE_DEBUG) { - // if (EngineManager::engines().isEmpty()) - // DebuggerMainWindow::instance()->restorePerspective(Constants::PRESET_PERSPRECTIVE_ID); - selectUiForCurrentEngine(); - } - } - EngineItem *findEngineItem(DebuggerEngine *engine); void activateEngine(DebuggerEngine *engine); void activateEngineItem(EngineItem *engineItem); @@ -226,8 +220,18 @@ QVariant EngineItem::data(int column, int role) const switch (role) { case Qt::DisplayRole: switch (column) { - case 0: - return m_engine->displayName(); + case 0: { + QString myName = m_engine->displayName(); + int count = 0; + for (TreeItem *item : *TreeItem::parent()) { + DebuggerEngine *engine = static_cast<EngineItem *>(item)->m_engine; + count += engine && engine->displayName() == myName; + } + if (count > 1) + myName += QString(" (%1)").arg(m_engine->runId()); + + return myName; + } case 1: return rp.coreFile.isEmpty() ? rp.inferior.executable : rp.coreFile; } @@ -333,18 +337,28 @@ void EngineManagerPrivate::activateEngineItem(EngineItem *engineItem) void EngineManagerPrivate::selectUiForCurrentEngine() { - Perspective *perspective = Perspective::currentPerspective(); - if (perspective && !perspective->id().startsWith("Debugger.Perspective.")) + if (ModeManager::currentModeId() != Constants::MODE_DEBUG) return; - perspective = nullptr; + + Perspective *perspective = nullptr; int row = 0; if (m_currentItem && m_currentItem->m_engine) { perspective = m_currentItem->m_engine->perspective(); - row = m_engineModel.rootItem()->indexOf(m_currentItem); + m_currentItem->m_engine->updateState(false); } + if (m_currentItem) + row = m_engineModel.rootItem()->indexOf(m_currentItem); + m_engineChooser->setCurrentIndex(row); + const int contentWidth = m_engineChooser->fontMetrics().width(m_engineChooser->currentText() + "xx"); + QStyleOptionComboBox option; + option.initFrom(m_engineChooser); + const QSize sz(contentWidth, 1); + const int width = m_engineChooser->style()->sizeFromContents( + QStyle::CT_ComboBox, &option, sz).width(); + m_engineChooser->setFixedWidth(width); if (!perspective) perspective = Perspective::findPerspective(Debugger::Constants::PRESET_PERSPECTIVE_ID); @@ -380,9 +394,11 @@ void EngineManagerPrivate::activateEngine(DebuggerEngine *engine) void EngineManagerPrivate::updateEngineChooserVisibility() { - // Show it if there's more than one option (i.e. not the the preset engine only) - const int count = m_engineModel.rootItem()->childCount(); - m_engineChooser->setVisible(count >= 2); + // Show it if there's more than one option (i.e. not the preset engine only) + if (hideSwitcherUnlessNeeded) { + const int count = m_engineModel.rootItem()->childCount(); + m_engineChooser->setVisible(count >= 2); + } } void EngineManager::registerEngine(DebuggerEngine *engine) @@ -401,8 +417,25 @@ void EngineManager::activateDebugMode() } } +bool EngineManager::isLastOf(const QString &type) +{ + int count = 0; + d->m_engineModel.rootItem()->forFirstLevelChildren([&](EngineItem *engineItem) { + if (engineItem && engineItem->m_engine) + count += (engineItem->m_engine->debuggerName() == type); + }); + return count == 1; +} + void EngineManager::unregisterEngine(DebuggerEngine *engine) { + if (ModeManager::currentModeId() == Constants::MODE_DEBUG) { + if (Perspective *parent = Perspective::findPerspective(Constants::PRESET_PERSPECTIVE_ID)) + parent->select(); + } + + d->activateEngineItem(d->m_engineModel.rootItem()->childAt(0)); // Preset. + // Could be that the run controls died before it was appended. if (auto engineItem = d->findEngineItem(engine)) d->m_engineModel.destroyItem(engineItem); diff --git a/src/plugins/debugger/snapshothandler.h b/src/plugins/debugger/snapshothandler.h index 080d4dfbe1..1107a7f100 100644 --- a/src/plugins/debugger/snapshothandler.h +++ b/src/plugins/debugger/snapshothandler.h @@ -51,6 +51,7 @@ public: static void unregisterEngine(DebuggerEngine *engine); static void activateEngine(DebuggerEngine *engine); static void activateDebugMode(); + static bool isLastOf(const QString &type); static QList<QPointer<DebuggerEngine> > engines(); static QPointer<DebuggerEngine> currentEngine(); |