diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp index 78498dace52e07cc0fe5c89ad2e6ffb2c01136bb..89df4c56bfb2ea19817b3c8075f8032db7ae92bc 100644 --- a/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp +++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp @@ -139,10 +139,10 @@ ClangStaticAnalyzerTool::ClangStaticAnalyzerTool(QObject *parent) const QString toolTip = tr("Clang Static Analyzer uses the analyzer from the Clang project " "to find bugs."); - Debugger::registerPerspective(ClangStaticAnalyzerPerspectiveId, { + Debugger::registerPerspective(ClangStaticAnalyzerPerspectiveId, new Perspective( tr("Clang Static Analyzer"), {{ ClangStaticAnalyzerDockId, m_diagnosticView, {}, Perspective::SplitVertical }} - }); + )); ActionDescription desc; desc.setText(tr("Clang Static Analyzer")); diff --git a/src/plugins/debugger/analyzer/analyzermanager.h b/src/plugins/debugger/analyzer/analyzermanager.h index e4fa695bddb511c03387fd656d647ca19d00ec18..e0a162358be9697d96437aa185977b1f7557430c 100644 --- a/src/plugins/debugger/analyzer/analyzermanager.h +++ b/src/plugins/debugger/analyzer/analyzermanager.h @@ -130,7 +130,7 @@ private: // Register a tool for a given start mode. DEBUGGER_EXPORT void registerAction(Core::Id actionId, const ActionDescription &desc, QAction *startAction = 0); -DEBUGGER_EXPORT void registerPerspective(const QByteArray &perspectiveId, const Utils::Perspective &perspective); +DEBUGGER_EXPORT void registerPerspective(const QByteArray &perspectiveId, const Utils::Perspective *perspective); DEBUGGER_EXPORT void registerToolbar(const QByteArray &perspectiveId, const Utils::ToolbarDescription &desc); DEBUGGER_EXPORT void enableMainWindow(bool on); diff --git a/src/plugins/debugger/debuggermainwindow.cpp b/src/plugins/debugger/debuggermainwindow.cpp index 52f97e41e8c911540e05675c0f425c249e3c8ec8..208558e895408d5c42e6a199016fbdaf757f91d8 100644 --- a/src/plugins/debugger/debuggermainwindow.cpp +++ b/src/plugins/debugger/debuggermainwindow.cpp @@ -63,7 +63,9 @@ const char LAST_PERSPECTIVE_KEY[] = "LastPerspective"; DebuggerMainWindow::DebuggerMainWindow() { m_controlsStackWidget = new QStackedWidget; + m_centralWidgetStack = new QStackedWidget; m_statusLabel = new Utils::StatusLabel; + m_editorPlaceHolder = new EditorManagerPlaceHolder; m_perspectiveChooser = new QComboBox; m_perspectiveChooser->setObjectName(QLatin1String("PerspectiveChooser")); @@ -80,6 +82,8 @@ DebuggerMainWindow::DebuggerMainWindow() DebuggerMainWindow::~DebuggerMainWindow() { + delete m_editorPlaceHolder; + m_editorPlaceHolder = 0; // As we have to setParent(0) on dock widget that are not selected, // we keep track of all and make sure we don't leak any foreach (QDockWidget *dock, m_dockForDockId) { @@ -87,24 +91,17 @@ DebuggerMainWindow::~DebuggerMainWindow() delete dock; } - foreach (const Perspective &perspective, m_perspectiveForPerspectiveId) { - foreach (const Perspective::Operation &operation, perspective.operations()) { - if (operation.widget && !operation.widget->parentWidget()) { - // These are from perspectives that never got enabled. We've taken ownership for - // those, so we need to delete them. - delete operation.widget; - } - } - } + foreach (const Perspective *perspective, m_perspectiveForPerspectiveId) + delete perspective; } -void DebuggerMainWindow::registerPerspective(const QByteArray &perspectiveId, const Perspective &perspective) +void DebuggerMainWindow::registerPerspective(const QByteArray &perspectiveId, const Perspective *perspective) { m_perspectiveForPerspectiveId.insert(perspectiveId, perspective); - m_perspectiveChooser->addItem(perspective.name(), perspectiveId); + m_perspectiveChooser->addItem(perspective->name(), perspectiveId); // adjust width if necessary const int oldWidth = m_perspectiveChooser->width(); - const int contentWidth = m_perspectiveChooser->fontMetrics().width(perspective.name()); + const int contentWidth = m_perspectiveChooser->fontMetrics().width(perspective->name()); QStyleOptionComboBox option; option.initFrom(m_perspectiveChooser); const QSize sz(contentWidth, 1); @@ -203,18 +200,15 @@ void DebuggerMainWindow::finalizeSetup() addDockWidget(Qt::BottomDockWidgetArea, dock); } -QWidget *createModeWindow(const Core::Id &mode, DebuggerMainWindow *mainWindow, QWidget *central) +QWidget *createModeWindow(const Core::Id &mode, DebuggerMainWindow *mainWindow) { - if (!central) - central = new EditorManagerPlaceHolder; - auto editorHolderLayout = new QVBoxLayout; editorHolderLayout->setMargin(0); editorHolderLayout->setSpacing(0); auto editorAndFindWidget = new QWidget; editorAndFindWidget->setLayout(editorHolderLayout); - editorHolderLayout->addWidget(central); + editorHolderLayout->addWidget(mainWindow->centralWidgetStack()); editorHolderLayout->addWidget(new FindToolBarPlaceHolder(editorAndFindWidget)); auto documentAndRightPane = new MiniSplitter; @@ -245,7 +239,7 @@ QWidget *createModeWindow(const Core::Id &mode, DebuggerMainWindow *mainWindow, // Navigation and right-side window. auto splitter = new MiniSplitter; - splitter->setFocusProxy(central); + splitter->setFocusProxy(mainWindow->centralWidgetStack()); splitter->addWidget(new NavigationWidgetPlaceHolder(mode)); splitter->addWidget(mainWindowSplitter); splitter->setStretchFactor(0, 0); @@ -271,6 +265,9 @@ void DebuggerMainWindow::loadPerspectiveHelper(const QByteArray &perspectiveId, } ICore::removeAdditionalContext(Context(Id::fromName(m_currentPerspectiveId))); + const Perspective *perspective = m_perspectiveForPerspectiveId.value(m_currentPerspectiveId); + QWidget *central = perspective->centralWidget(); + m_centralWidgetStack->removeWidget(central ? central : m_editorPlaceHolder); } m_currentPerspectiveId = perspectiveId; @@ -285,8 +282,8 @@ void DebuggerMainWindow::loadPerspectiveHelper(const QByteArray &perspectiveId, ICore::addAdditionalContext(Context(Id::fromName(m_currentPerspectiveId))); QTC_ASSERT(m_perspectiveForPerspectiveId.contains(m_currentPerspectiveId), return); - const Perspective perspective = m_perspectiveForPerspectiveId.value(m_currentPerspectiveId); - for (const Perspective::Operation &operation : perspective.operations()) { + const Perspective *perspective = m_perspectiveForPerspectiveId.value(m_currentPerspectiveId); + for (const Perspective::Operation &operation : perspective->operations()) { QDockWidget *dock = m_dockForDockId.value(operation.dockId); if (!dock) { QTC_CHECK(!operation.widget->objectName().isEmpty()); @@ -341,6 +338,9 @@ void DebuggerMainWindow::loadPerspectiveHelper(const QByteArray &perspectiveId, settings->endGroup(); } + QWidget *central = perspective->centralWidget(); + m_centralWidgetStack->addWidget(central ? central : m_editorPlaceHolder); + QTC_CHECK(m_toolbarForPerspectiveId.contains(m_currentPerspectiveId)); m_controlsStackWidget->setCurrentWidget(m_toolbarForPerspectiveId.value(m_currentPerspectiveId)); m_statusLabel->clear(); @@ -366,6 +366,13 @@ QDockWidget *DebuggerMainWindow::registerDockWidget(const QByteArray &dockId, QW return dockWidget; } +Perspective::~Perspective() +{ + foreach (const Operation &operation, m_operations) + delete operation.widget; + delete m_centralWidget; +} + QString Perspective::name() const { return m_name; @@ -401,8 +408,9 @@ Perspective::Operation::Operation(const QByteArray &dockId, QWidget *widget, con operationType(splitType), visibleByDefault(visibleByDefault), area(area) {} -Perspective::Perspective(const QString &name, const QVector &splits) - : m_name(name), m_operations(splits) +Perspective::Perspective(const QString &name, const QVector &splits, + QWidget *centralWidget) + : m_name(name), m_operations(splits), m_centralWidget(centralWidget) { for (const Operation &split : splits) m_docks.append(split.dockId); diff --git a/src/plugins/debugger/debuggermainwindow.h b/src/plugins/debugger/debuggermainwindow.h index 6bcba50274884554573904599f6d4f31a9b8f5b0..d7dd6460be9b0414a1f2278173c0f0be51d90e78 100644 --- a/src/plugins/debugger/debuggermainwindow.h +++ b/src/plugins/debugger/debuggermainwindow.h @@ -68,20 +68,28 @@ public: }; Perspective() = default; - Perspective(const QString &name, const QVector &operations); + // Takes ownership of \a centralWidget and all dock widgets in \a operations. + Perspective(const QString &name, const QVector &operations, + QWidget *centralWidget = 0); + ~Perspective(); void addOperation(const Operation &operation); QVector operations() const { return m_operations; } QVector docks() const { return m_docks; } + QWidget *centralWidget() const { return m_centralWidget; } QString name() const; void setName(const QString &name); private: + Perspective(const Perspective &) = delete; + void operator=(const Perspective &) = delete; + QString m_name; QVector m_docks; QVector m_operations; + QPointer m_centralWidget; }; class DEBUGGER_EXPORT ToolbarDescription @@ -107,7 +115,7 @@ public: DebuggerMainWindow(); ~DebuggerMainWindow() override; - void registerPerspective(const QByteArray &perspectiveId, const Perspective &perspective); + void registerPerspective(const QByteArray &perspectiveId, const Perspective *perspective); void registerToolbar(const QByteArray &perspectiveId, QWidget *widget); void saveCurrentPerspective(); @@ -119,6 +127,7 @@ public: void showStatusMessage(const QString &message, int timeoutMS); QDockWidget *dockWidget(const QByteArray &dockId) const; QByteArray currentPerspective() const { return m_currentPerspectiveId; } + QStackedWidget *centralWidgetStack() const { return m_centralWidgetStack; } private: QDockWidget *registerDockWidget(const QByteArray &dockId, QWidget *widget); @@ -127,14 +136,16 @@ private: QByteArray m_currentPerspectiveId; QComboBox *m_perspectiveChooser; QStackedWidget *m_controlsStackWidget; + QStackedWidget *m_centralWidgetStack; + QWidget *m_editorPlaceHolder; Utils::StatusLabel *m_statusLabel; QDockWidget *m_toolbarDock; QHash m_dockForDockId; QHash m_toolbarForPerspectiveId; - QHash m_perspectiveForPerspectiveId; + QHash m_perspectiveForPerspectiveId; }; -DEBUGGER_EXPORT QWidget *createModeWindow(const Core::Id &mode, DebuggerMainWindow *mainWindow, QWidget *central); +DEBUGGER_EXPORT QWidget *createModeWindow(const Core::Id &mode, DebuggerMainWindow *mainWindow); } // Utils diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 905b39933b8e51004e37613972e95f33601142fa..3707aec9936f954bcb4e40eaa6838d57e7d31385 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -1756,7 +1756,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments, // Debug mode setup m_mode = new DebugMode; - m_modeWindow = createModeWindow(Constants::MODE_DEBUG, m_mainWindow, 0); + m_modeWindow = createModeWindow(Constants::MODE_DEBUG, m_mainWindow); m_mode->setWidget(m_modeWindow); m_plugin->addAutoReleasedObject(new DebugModeContext(m_mainWindow)); @@ -1835,7 +1835,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments, // qmlToolbar.addAction(qmlSelectDummyAction, Icons::SELECT_TOOLBAR.icon()); // qmlToolbar.addWidget(new StyledSeparator); - Perspective basePerspective({}, { + auto createBasePerspective = [this] { return new Perspective({}, { { DOCKWIDGET_STACK, m_stackWindow, {}, Perspective::SplitVertical }, { DOCKWIDGET_BREAK, m_breakWindow, DOCKWIDGET_STACK, Perspective::SplitHorizontal }, { DOCKWIDGET_THREADS, m_threadsWindow, DOCKWIDGET_BREAK, Perspective::AddToTab, false }, @@ -1846,19 +1846,19 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments, Qt::RightDockWidgetArea }, { DOCKWIDGET_OUTPUT, m_logWindow, {}, Perspective::AddToTab, false, Qt::TopDockWidgetArea }, { DOCKWIDGET_BREAK, 0, {}, Perspective::Raise } - }); + }); }; - Perspective cppPerspective = basePerspective; - cppPerspective.setName(tr("Debugger")); - cppPerspective.addOperation({ DOCKWIDGET_REGISTER, m_registerWindow, DOCKWIDGET_SNAPSHOTS, + Perspective *cppPerspective = createBasePerspective(); + cppPerspective->setName(tr("Debugger")); + cppPerspective->addOperation({ DOCKWIDGET_REGISTER, m_registerWindow, DOCKWIDGET_SNAPSHOTS, Perspective::AddToTab, false }); Debugger::registerToolbar(CppPerspectiveId, toolbar); Debugger::registerPerspective(CppPerspectiveId, cppPerspective); -// Perspective qmlPerspective = basePerspective; -// qmlPerspective.setName(tr("QML Debugger")); -// qmlPerspective.addOperation({ DOCKWIDGET_REGISTER, DOCKWIDGET_SNAPSHOTS, +// Perspective *qmlPerspective = createBasePerspective(); +// qmlPerspective->setName(tr("QML Debugger")); +// qmlPerspective->addOperation({ DOCKWIDGET_REGISTER, DOCKWIDGET_SNAPSHOTS, // Perspective::AddToTab, false }); // // Debugger::registerToolbar(QmlPerspectiveId, toolbarContainer); @@ -3582,7 +3582,7 @@ QAction *createStopAction() return action; } -void registerPerspective(const QByteArray &perspectiveId, const Perspective &perspective) +void registerPerspective(const QByteArray &perspectiveId, const Perspective *perspective) { dd->m_mainWindow->registerPerspective(perspectiveId, perspective); } diff --git a/src/plugins/qmlprofiler/qmlprofilerviewmanager.cpp b/src/plugins/qmlprofiler/qmlprofilerviewmanager.cpp index 032d2f8465f62b8baf0156153ba6bb40a83be16c..cba27c62130c4b12dc499ddb7dd6e7d95082f4d8 100644 --- a/src/plugins/qmlprofiler/qmlprofilerviewmanager.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerviewmanager.cpp @@ -89,10 +89,10 @@ void QmlProfilerViewManager::createViews() new QmlProfilerStateWidget(d->profilerState, d->profilerModelManager, d->traceView); - Utils::Perspective perspective; - perspective.setName(tr("QML Profiler")); - perspective.addOperation({Constants::QmlProfilerTimelineDockId, d->traceView, {}, - Perspective::SplitVertical}); + auto perspective = new Utils::Perspective; + perspective->setName(tr("QML Profiler")); + perspective->addOperation({Constants::QmlProfilerTimelineDockId, d->traceView, {}, + Perspective::SplitVertical}); d->eventsViews << new QmlProfilerStatisticsView(0, d->profilerModelManager); d->eventsViews << new FlameGraphView(0, d->profilerModelManager); @@ -109,10 +109,10 @@ void QmlProfilerViewManager::createViews() connect(view, &QmlProfilerEventsView::showFullRange, this, [this](){restrictEventsToRange(-1, -1);}); QByteArray dockId = view->objectName().toLatin1(); - perspective.addOperation({dockId, view, Constants::QmlProfilerTimelineDockId, Perspective::AddToTab}); + perspective->addOperation({dockId, view, Constants::QmlProfilerTimelineDockId, Perspective::AddToTab}); new QmlProfilerStateWidget(d->profilerState, d->profilerModelManager, view); } - perspective.addOperation({Constants::QmlProfilerTimelineDockId, 0, {}, Perspective::Raise}); + perspective->addOperation({Constants::QmlProfilerTimelineDockId, 0, {}, Perspective::Raise}); Debugger::registerPerspective(Constants::QmlProfilerPerspectiveId, perspective); } diff --git a/src/plugins/valgrind/callgrindtool.cpp b/src/plugins/valgrind/callgrindtool.cpp index ece0c27ae0ff19040360980ad682349fde4f4154..917703743c5aced34e8b82e9a82299eccb2186ca 100644 --- a/src/plugins/valgrind/callgrindtool.cpp +++ b/src/plugins/valgrind/callgrindtool.cpp @@ -501,13 +501,13 @@ CallgrindTool::CallgrindTool(QObject *parent) toolbar.addWidget(m_searchFilter); Debugger::registerToolbar(CallgrindPerspectiveId, toolbar); - Debugger::registerPerspective(CallgrindPerspectiveId, { tr("Callgrind"), { + Debugger::registerPerspective(CallgrindPerspectiveId, new Perspective(tr("Callgrind"), { { CallgrindFlatDockId, m_flatView, {}, Perspective::SplitVertical }, { CallgrindCalleesDockId, m_calleesView, {}, Perspective::SplitVertical }, { CallgrindCallersDockId, m_callersView, CallgrindCalleesDockId, Perspective::SplitHorizontal }, { CallgrindVisualizationDockId, m_visualization, {}, Perspective::SplitVertical, false, Qt::RightDockWidgetArea } - }}); + })); connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::updateRunActions, this, &CallgrindTool::updateRunActions); diff --git a/src/plugins/valgrind/memchecktool.cpp b/src/plugins/valgrind/memchecktool.cpp index b3b378cc4bd3882b5d539aa29b431de5c5ff5746..9a69bf1cb6efe4894a834ec67f145b81582635ba 100644 --- a/src/plugins/valgrind/memchecktool.cpp +++ b/src/plugins/valgrind/memchecktool.cpp @@ -336,9 +336,9 @@ MemcheckTool::MemcheckTool(QObject *parent) m_errorView->setObjectName(QLatin1String("Valgrind.MemcheckTool.ErrorView")); m_errorView->setWindowTitle(tr("Memory Issues")); - Debugger::registerPerspective(MemcheckPerspectiveId, { tr("Memcheck"), { + Debugger::registerPerspective(MemcheckPerspectiveId, new Perspective (tr("Memcheck"), { { MemcheckErrorDockId, m_errorView, {}, Perspective::SplitVertical } - }}); + })); connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::updateRunActions, this, &MemcheckTool::maybeActiveRunConfigurationChanged);