Commit df8e3b59 authored by hjk's avatar hjk

Debugger: Let perspectives specify their central widget

The default 0 value will be interpreted as 'use the editor stack'.

Also, drop the idea of value semantics for Perspective objects
to get a simpler approach to the destruction of owned widgets
(tools docks + central widget)

Change-Id: Ic6470411ee5d387c43447f95b5a12c81c6658ff8
Reviewed-by: Eike Ziller's avatarEike Ziller <eike.ziller@qt.io>
parent 602d899e
......@@ -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"));
......
......@@ -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);
......
......@@ -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<Operation> &splits)
: m_name(name), m_operations(splits)
Perspective::Perspective(const QString &name, const QVector<Operation> &splits,
QWidget *centralWidget)
: m_name(name), m_operations(splits), m_centralWidget(centralWidget)
{
for (const Operation &split : splits)
m_docks.append(split.dockId);
......
......@@ -68,20 +68,28 @@ public:
};
Perspective() = default;
Perspective(const QString &name, const QVector<Operation> &operations);
// Takes ownership of \a centralWidget and all dock widgets in \a operations.
Perspective(const QString &name, const QVector<Operation> &operations,
QWidget *centralWidget = 0);
~Perspective();
void addOperation(const Operation &operation);
QVector<Operation> operations() const { return m_operations; }
QVector<QByteArray> 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<QByteArray> m_docks;
QVector<Operation> m_operations;
QPointer<QWidget> 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<QByteArray, QDockWidget *> m_dockForDockId;
QHash<QByteArray, QWidget *> m_toolbarForPerspectiveId;
QHash<QByteArray, Perspective> m_perspectiveForPerspectiveId;
QHash<QByteArray, const Perspective *> 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
......@@ -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);
}
......
......@@ -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);
}
......
......@@ -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);
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment