forked from qt-creator/qt-creator
Debugger: Re-organize dock widget persisting
Looks like the mainwindow cannot be convinced to handle multiple sets of dockwidgets. So switch back to a single set containing everything and keep track of non-default visibility in the perspectives, and persist these sets. The following pass: 1. Start Creator with new settings Goto Debug Mode Move Break dock widget to right, switch on Global log widget Leave Creator Start Creator Goto Debug Mode Check: Debugger Selected, Break on right, Global log visible 2. Start Creator with new settings Goto Debug Mode Move Break dock widget to right, switch on Global log widget Switch to QmlProfiler sub-perspective Leave Creator Start Creator Goto Debug Mode Check QmlProfiler selected Switch to Debugger sub-perspective Check: Debugger Selected, Break on right, Global log visible 3. Start Creator with new settings Use any C++ test project Start debugging / stop at main() (F10) Wait for stop Switch to Edit mode Switch back to Debug mode Check: Only "running" debugger dock widget layout present (not the normal + preset at the same time) Quit Qt Creator while this debugger is running Check: Shuts down without crash 4. Use any C++ test project Start debugging Switch to Debugger Preset perspective Start a second debugger Kill either instance Check: Application dies, Debugger Preset perspective gets displayed Switch to perspective of second instance Check: Perspective looks ok (docks visible as before) Task-number: QTCREATORBUG-21083 Task-number: QTCREATORBUG-21669 Task-number: QTCREATORBUG-21668 Task-number: QTCREATORBUG-21813 Task-number: QTCREATORBUG-21851 Task-number: QTCREATORBUG-22110 Task-number: QTCREATORBUG-22169 Task-number: QTCREATORBUG-22189 Change-Id: Ic9eb41ff7699ac0f48a85e68376daa80b2b6847e Reviewed-by: Robert Loehning <robert.loehning@qt.io> Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
@@ -523,6 +523,21 @@ bool FancyMainWindow::autoHideTitleBars() const
|
|||||||
return d->m_autoHideTitleBars.isChecked();
|
return d->m_autoHideTitleBars.isChecked();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FancyMainWindow::setAutoHideTitleBars(bool on)
|
||||||
|
{
|
||||||
|
d->m_autoHideTitleBars.setChecked(on);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FancyMainWindow::isCentralWidgetShown() const
|
||||||
|
{
|
||||||
|
return d->m_showCentralWidget.isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FancyMainWindow::showCentralWidget(bool on)
|
||||||
|
{
|
||||||
|
d->m_showCentralWidget.setChecked(on);
|
||||||
|
}
|
||||||
|
|
||||||
void FancyMainWindow::addDockActionsToMenu(QMenu *menu)
|
void FancyMainWindow::addDockActionsToMenu(QMenu *menu)
|
||||||
{
|
{
|
||||||
QList<QAction *> actions;
|
QList<QAction *> actions;
|
||||||
|
@@ -66,6 +66,10 @@ public:
|
|||||||
void addDockActionsToMenu(QMenu *menu);
|
void addDockActionsToMenu(QMenu *menu);
|
||||||
|
|
||||||
bool autoHideTitleBars() const;
|
bool autoHideTitleBars() const;
|
||||||
|
void setAutoHideTitleBars(bool on);
|
||||||
|
|
||||||
|
bool isCentralWidgetShown() const;
|
||||||
|
void showCentralWidget(bool on);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
// Emitted by resetLayoutAction(). Connect to a slot
|
// Emitted by resetLayoutAction(). Connect to a slot
|
||||||
|
@@ -61,6 +61,7 @@
|
|||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/idocument.h>
|
#include <coreplugin/idocument.h>
|
||||||
#include <coreplugin/messagebox.h>
|
#include <coreplugin/messagebox.h>
|
||||||
|
#include <coreplugin/modemanager.h>
|
||||||
#include <coreplugin/progressmanager/progressmanager.h>
|
#include <coreplugin/progressmanager/progressmanager.h>
|
||||||
#include <coreplugin/progressmanager/futureprogress.h>
|
#include <coreplugin/progressmanager/futureprogress.h>
|
||||||
|
|
||||||
@@ -280,12 +281,16 @@ public:
|
|||||||
m_disassemblerAgent(engine),
|
m_disassemblerAgent(engine),
|
||||||
m_toolTipManager(engine)
|
m_toolTipManager(engine)
|
||||||
{
|
{
|
||||||
m_logWindow = new LogWindow(m_engine); // Needed before start()
|
|
||||||
m_logWindow->setObjectName(DOCKWIDGET_OUTPUT);
|
|
||||||
m_debuggerName = DebuggerEngine::tr("Debugger");
|
m_debuggerName = DebuggerEngine::tr("Debugger");
|
||||||
|
|
||||||
connect(action(EnableReverseDebugging), &SavedAction::valueChanged,
|
m_logWindow = new LogWindow(m_engine); // Needed before start()
|
||||||
this, [this] { updateState(true); });
|
m_logWindow->setObjectName("Debugger.Dock.Output");
|
||||||
|
|
||||||
|
connect(action(EnableReverseDebugging), &SavedAction::valueChanged, this, [this] {
|
||||||
|
updateState();
|
||||||
|
if (m_companionEngine)
|
||||||
|
m_companionEngine->d->updateState();
|
||||||
|
});
|
||||||
static int contextCount = 0;
|
static int contextCount = 0;
|
||||||
m_context = Context(Id("Debugger.Engine.").withSuffix(++contextCount));
|
m_context = Context(Id("Debugger.Engine.").withSuffix(++contextCount));
|
||||||
|
|
||||||
@@ -370,17 +375,15 @@ public:
|
|||||||
if (!m_perspective)
|
if (!m_perspective)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
delete m_perspective;
|
Perspective *perspective = m_perspective;
|
||||||
m_perspective = nullptr;
|
m_perspective = nullptr;
|
||||||
|
|
||||||
EngineManager::unregisterEngine(m_engine);
|
EngineManager::unregisterEngine(m_engine);
|
||||||
|
|
||||||
// Give up ownership on claimed breakpoints.
|
// This triggers activity in the EngineManager which
|
||||||
m_breakHandler.releaseAllBreakpoints();
|
// recognizes the rampdown by the m_perpective == nullptr above.
|
||||||
m_toolTipManager.deregisterEngine();
|
perspective->destroy();
|
||||||
m_memoryAgents.handleDebuggerFinished();
|
delete perspective;
|
||||||
|
|
||||||
setBusyCursor(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateReturnViewHeader(int section, int, int newSize)
|
void updateReturnViewHeader(int section, int, int newSize)
|
||||||
@@ -446,14 +449,14 @@ public:
|
|||||||
void setInitialActionStates();
|
void setInitialActionStates();
|
||||||
void setBusyCursor(bool on);
|
void setBusyCursor(bool on);
|
||||||
void cleanupViews();
|
void cleanupViews();
|
||||||
void updateState(bool alsoUpdateCompanion);
|
void updateState();
|
||||||
void updateReverseActions();
|
void updateReverseActions();
|
||||||
|
|
||||||
DebuggerEngine *m_engine = nullptr; // Not owned.
|
DebuggerEngine *m_engine = nullptr; // Not owned.
|
||||||
QString m_runId;
|
QString m_runId;
|
||||||
QPointer<RunConfiguration> m_runConfiguration; // Not owned.
|
QPointer<RunConfiguration> m_runConfiguration; // Not owned.
|
||||||
QString m_debuggerName;
|
QString m_debuggerName;
|
||||||
Perspective *m_perspective = nullptr;
|
QPointer<Perspective> m_perspective;
|
||||||
DebuggerRunParameters m_runParameters;
|
DebuggerRunParameters m_runParameters;
|
||||||
IDevice::ConstPtr m_device;
|
IDevice::ConstPtr m_device;
|
||||||
|
|
||||||
@@ -551,16 +554,17 @@ public:
|
|||||||
void DebuggerEnginePrivate::setupViews()
|
void DebuggerEnginePrivate::setupViews()
|
||||||
{
|
{
|
||||||
const DebuggerRunParameters &rp = m_runParameters;
|
const DebuggerRunParameters &rp = m_runParameters;
|
||||||
|
const QString engineId = EngineManager::registerEngine(m_engine);
|
||||||
|
|
||||||
QTC_CHECK(!m_perspective);
|
QTC_CHECK(!m_perspective);
|
||||||
|
|
||||||
m_perspective = new Perspective("Debugger.Perspective." + m_runId + '.' + m_debuggerName,
|
const QString perspectiveId = "Debugger.Perspective." + m_runId + '.' + m_debuggerName;
|
||||||
|
const QString settingsId = "Debugger.Perspective." + m_debuggerName;
|
||||||
|
|
||||||
|
m_perspective = new Perspective(perspectiveId,
|
||||||
m_engine->displayName(),
|
m_engine->displayName(),
|
||||||
Debugger::Constants::PRESET_PERSPECTIVE_ID,
|
Debugger::Constants::PRESET_PERSPECTIVE_ID,
|
||||||
m_debuggerName);
|
settingsId);
|
||||||
m_perspective->setShouldPersistChecker([this] {
|
|
||||||
return EngineManager::isLastOf(m_debuggerName);
|
|
||||||
});
|
|
||||||
|
|
||||||
m_progress.setProgressRange(0, 1000);
|
m_progress.setProgressRange(0, 1000);
|
||||||
FutureProgress *fp = ProgressManager::addTask(m_progress.future(),
|
FutureProgress *fp = ProgressManager::addTask(m_progress.future(),
|
||||||
@@ -628,7 +632,7 @@ void DebuggerEnginePrivate::setupViews()
|
|||||||
m_engine, &DebuggerEngine::reloadModules,
|
m_engine, &DebuggerEngine::reloadModules,
|
||||||
Qt::QueuedConnection);
|
Qt::QueuedConnection);
|
||||||
m_modulesWindow = addSearch(m_modulesView);
|
m_modulesWindow = addSearch(m_modulesView);
|
||||||
m_modulesWindow->setObjectName(DOCKWIDGET_MODULES);
|
m_modulesWindow->setObjectName("Debugger.Dock.Modules." + engineId);
|
||||||
m_modulesWindow->setWindowTitle(tr("&Modules"));
|
m_modulesWindow->setWindowTitle(tr("&Modules"));
|
||||||
|
|
||||||
m_registerView = new BaseTreeView;
|
m_registerView = new BaseTreeView;
|
||||||
@@ -639,7 +643,7 @@ void DebuggerEnginePrivate::setupViews()
|
|||||||
m_engine, &DebuggerEngine::reloadRegisters,
|
m_engine, &DebuggerEngine::reloadRegisters,
|
||||||
Qt::QueuedConnection);
|
Qt::QueuedConnection);
|
||||||
m_registerWindow = addSearch(m_registerView);
|
m_registerWindow = addSearch(m_registerView);
|
||||||
m_registerWindow->setObjectName(DOCKWIDGET_REGISTER);
|
m_registerWindow->setObjectName("Debugger.Dock.Register." + engineId);
|
||||||
m_registerWindow->setWindowTitle(tr("Reg&isters"));
|
m_registerWindow->setWindowTitle(tr("Reg&isters"));
|
||||||
|
|
||||||
m_stackView = new StackTreeView;
|
m_stackView = new StackTreeView;
|
||||||
@@ -647,7 +651,7 @@ void DebuggerEnginePrivate::setupViews()
|
|||||||
m_stackView->setSettings(settings, "Debugger.StackView");
|
m_stackView->setSettings(settings, "Debugger.StackView");
|
||||||
m_stackView->setIconSize(QSize(10, 10));
|
m_stackView->setIconSize(QSize(10, 10));
|
||||||
m_stackWindow = addSearch(m_stackView);
|
m_stackWindow = addSearch(m_stackView);
|
||||||
m_stackWindow->setObjectName(DOCKWIDGET_STACK);
|
m_stackWindow->setObjectName("Debugger.Dock.Stack." + engineId);
|
||||||
m_stackWindow->setWindowTitle(tr("&Stack"));
|
m_stackWindow->setWindowTitle(tr("&Stack"));
|
||||||
|
|
||||||
m_sourceFilesView = new BaseTreeView;
|
m_sourceFilesView = new BaseTreeView;
|
||||||
@@ -658,7 +662,7 @@ void DebuggerEnginePrivate::setupViews()
|
|||||||
m_engine, &DebuggerEngine::reloadSourceFiles,
|
m_engine, &DebuggerEngine::reloadSourceFiles,
|
||||||
Qt::QueuedConnection);
|
Qt::QueuedConnection);
|
||||||
m_sourceFilesWindow = addSearch(m_sourceFilesView);
|
m_sourceFilesWindow = addSearch(m_sourceFilesView);
|
||||||
m_sourceFilesWindow->setObjectName(DOCKWIDGET_SOURCE_FILES);
|
m_sourceFilesWindow->setObjectName("Debugger.Dock.SourceFiles." + engineId);
|
||||||
m_sourceFilesWindow->setWindowTitle(tr("Source Files"));
|
m_sourceFilesWindow->setWindowTitle(tr("Source Files"));
|
||||||
|
|
||||||
m_threadsView = new BaseTreeView;
|
m_threadsView = new BaseTreeView;
|
||||||
@@ -668,7 +672,7 @@ void DebuggerEnginePrivate::setupViews()
|
|||||||
m_threadsView->setIconSize(QSize(10, 10));
|
m_threadsView->setIconSize(QSize(10, 10));
|
||||||
m_threadsView->setSpanColumn(ThreadData::FunctionColumn);
|
m_threadsView->setSpanColumn(ThreadData::FunctionColumn);
|
||||||
m_threadsWindow = addSearch(m_threadsView);
|
m_threadsWindow = addSearch(m_threadsView);
|
||||||
m_threadsWindow->setObjectName(DOCKWIDGET_THREADS);
|
m_threadsWindow->setObjectName("Debugger.Dock.Threads." + engineId);
|
||||||
m_threadsWindow->setWindowTitle(tr("&Threads"));
|
m_threadsWindow->setWindowTitle(tr("&Threads"));
|
||||||
|
|
||||||
m_returnView = new WatchTreeView{ReturnType};
|
m_returnView = new WatchTreeView{ReturnType};
|
||||||
@@ -682,26 +686,26 @@ void DebuggerEnginePrivate::setupViews()
|
|||||||
m_localsView->setModel(m_watchHandler.model());
|
m_localsView->setModel(m_watchHandler.model());
|
||||||
m_localsView->setSettings(settings, "Debugger.LocalsView");
|
m_localsView->setSettings(settings, "Debugger.LocalsView");
|
||||||
m_localsWindow = addSearch(m_localsView);
|
m_localsWindow = addSearch(m_localsView);
|
||||||
m_localsWindow->setObjectName("CppDebugLocals");
|
m_localsWindow->setObjectName("Debugger.Dock.Locals." + engineId);
|
||||||
m_localsWindow->setWindowTitle(tr("Locals"));
|
m_localsWindow->setWindowTitle(tr("Locals"));
|
||||||
|
|
||||||
m_inspectorView = new WatchTreeView{InspectType};
|
m_inspectorView = new WatchTreeView{InspectType};
|
||||||
m_inspectorView->setModel(m_watchHandler.model());
|
m_inspectorView->setModel(m_watchHandler.model());
|
||||||
m_inspectorView->setSettings(settings, "Debugger.LocalsView"); // sic! same as locals view.
|
m_inspectorView->setSettings(settings, "Debugger.LocalsView"); // sic! same as locals view.
|
||||||
m_inspectorWindow = addSearch(m_inspectorView);
|
m_inspectorWindow = addSearch(m_inspectorView);
|
||||||
m_inspectorWindow->setObjectName("Inspector");
|
m_inspectorWindow->setObjectName("Debugger.Dock.Inspector." + engineId);
|
||||||
m_inspectorWindow->setWindowTitle(tr("Locals"));
|
m_inspectorWindow->setWindowTitle(tr("Locals"));
|
||||||
|
|
||||||
m_watchersView = new WatchTreeView{WatchersType};
|
m_watchersView = new WatchTreeView{WatchersType};
|
||||||
m_watchersView->setModel(m_watchHandler.model());
|
m_watchersView->setModel(m_watchHandler.model());
|
||||||
m_watchersView->setSettings(settings, "Debugger.WatchersView");
|
m_watchersView->setSettings(settings, "Debugger.WatchersView");
|
||||||
m_watchersWindow = addSearch(m_watchersView);
|
m_watchersWindow = addSearch(m_watchersView);
|
||||||
m_watchersWindow->setObjectName("CppDebugWatchers");
|
m_watchersWindow->setObjectName("Debugger.Dock.Watchers." + engineId);
|
||||||
m_watchersWindow->setWindowTitle(tr("&Expressions"));
|
m_watchersWindow->setWindowTitle(tr("&Expressions"));
|
||||||
|
|
||||||
m_localsAndInspectorWindow = new LocalsAndInspectorWindow(
|
m_localsAndInspectorWindow = new LocalsAndInspectorWindow(
|
||||||
m_localsWindow, m_inspectorWindow, m_returnWindow);
|
m_localsWindow, m_inspectorWindow, m_returnWindow);
|
||||||
m_localsAndInspectorWindow->setObjectName(DOCKWIDGET_LOCALS_AND_INSPECTOR);
|
m_localsAndInspectorWindow->setObjectName("Debugger.Dock.LocalsAndInspector." + engineId);
|
||||||
m_localsAndInspectorWindow->setWindowTitle(m_localsWindow->windowTitle());
|
m_localsAndInspectorWindow->setWindowTitle(m_localsWindow->windowTitle());
|
||||||
|
|
||||||
// Locals
|
// Locals
|
||||||
@@ -719,7 +723,7 @@ void DebuggerEnginePrivate::setupViews()
|
|||||||
m_breakView->setModel(m_breakHandler.model());
|
m_breakView->setModel(m_breakHandler.model());
|
||||||
m_breakView->setRootIsDecorated(true);
|
m_breakView->setRootIsDecorated(true);
|
||||||
m_breakWindow = addSearch(m_breakView);
|
m_breakWindow = addSearch(m_breakView);
|
||||||
m_breakWindow->setObjectName(DOCKWIDGET_BREAK);
|
m_breakWindow->setObjectName("Debugger.Dock.Break." + engineId);
|
||||||
m_breakWindow->setWindowTitle(tr("&Breakpoints"));
|
m_breakWindow->setWindowTitle(tr("&Breakpoints"));
|
||||||
|
|
||||||
m_perspective->useSubPerspectiveSwitcher(EngineManager::engineChooser());
|
m_perspective->useSubPerspectiveSwitcher(EngineManager::engineChooser());
|
||||||
@@ -846,7 +850,6 @@ void DebuggerEnginePrivate::setupViews()
|
|||||||
DebuggerEngine::DebuggerEngine()
|
DebuggerEngine::DebuggerEngine()
|
||||||
: d(new DebuggerEnginePrivate(this))
|
: d(new DebuggerEnginePrivate(this))
|
||||||
{
|
{
|
||||||
updateState(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DebuggerEngine::~DebuggerEngine()
|
DebuggerEngine::~DebuggerEngine()
|
||||||
@@ -1020,7 +1023,6 @@ void DebuggerEngine::setRunTool(DebuggerRunTool *runTool)
|
|||||||
|
|
||||||
void DebuggerEngine::start()
|
void DebuggerEngine::start()
|
||||||
{
|
{
|
||||||
EngineManager::registerEngine(this);
|
|
||||||
d->m_watchHandler.resetWatchers();
|
d->m_watchHandler.resetWatchers();
|
||||||
d->setInitialActionStates();
|
d->setInitialActionStates();
|
||||||
setState(EngineSetupRequested);
|
setState(EngineSetupRequested);
|
||||||
@@ -1116,7 +1118,7 @@ void DebuggerEngine::abortDebugger()
|
|||||||
|
|
||||||
void DebuggerEngine::updateUi(bool isCurrentEngine)
|
void DebuggerEngine::updateUi(bool isCurrentEngine)
|
||||||
{
|
{
|
||||||
updateState(false);
|
updateState();
|
||||||
if (isCurrentEngine) {
|
if (isCurrentEngine) {
|
||||||
gotoCurrentLocation();
|
gotoCurrentLocation();
|
||||||
} else {
|
} else {
|
||||||
@@ -1319,7 +1321,7 @@ void DebuggerEngine::notifyInferiorSpontaneousStop()
|
|||||||
{
|
{
|
||||||
showMessage("NOTE: INFERIOR SPONTANEOUS STOP");
|
showMessage("NOTE: INFERIOR SPONTANEOUS STOP");
|
||||||
QTC_ASSERT(state() == InferiorRunOk, qDebug() << this << state());
|
QTC_ASSERT(state() == InferiorRunOk, qDebug() << this << state());
|
||||||
EngineManager::activateEngine(this);
|
d->m_perspective->select();
|
||||||
showMessage(tr("Stopped."), StatusBar);
|
showMessage(tr("Stopped."), StatusBar);
|
||||||
setState(InferiorStopOk);
|
setState(InferiorStopOk);
|
||||||
if (boolSetting(RaiseOnInterrupt))
|
if (boolSetting(RaiseOnInterrupt))
|
||||||
@@ -1386,10 +1388,12 @@ void DebuggerEnginePrivate::setInitialActionStates()
|
|||||||
m_threadLabel->setEnabled(false);
|
m_threadLabel->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerEnginePrivate::updateState(bool alsoUpdateCompanion)
|
void DebuggerEnginePrivate::updateState()
|
||||||
{
|
{
|
||||||
if (!m_perspective)
|
// Can happen in mixed debugging.
|
||||||
|
if (!m_threadLabel)
|
||||||
return;
|
return;
|
||||||
|
QTC_ASSERT(m_threadLabel, return);
|
||||||
|
|
||||||
const DebuggerState state = m_state;
|
const DebuggerState state = m_state;
|
||||||
const bool companionPreventsAction = m_engine->companionPreventsActions();
|
const bool companionPreventsAction = m_engine->companionPreventsActions();
|
||||||
@@ -1399,7 +1403,7 @@ void DebuggerEnginePrivate::updateState(bool alsoUpdateCompanion)
|
|||||||
// visible, possibly disabled.
|
// visible, possibly disabled.
|
||||||
if (state == DebuggerNotReady) {
|
if (state == DebuggerNotReady) {
|
||||||
// Happens when companion starts, otherwise this should not happen.
|
// Happens when companion starts, otherwise this should not happen.
|
||||||
QTC_CHECK(m_companionEngine);
|
//QTC_CHECK(m_companionEngine);
|
||||||
m_interruptAction.setVisible(true);
|
m_interruptAction.setVisible(true);
|
||||||
m_interruptAction.setEnabled(false);
|
m_interruptAction.setEnabled(false);
|
||||||
m_continueAction.setVisible(false);
|
m_continueAction.setVisible(false);
|
||||||
@@ -1529,9 +1533,6 @@ void DebuggerEnginePrivate::updateState(bool alsoUpdateCompanion)
|
|||||||
|| state == DebuggerFinished
|
|| state == DebuggerFinished
|
||||||
|| state == InferiorUnrunnable;
|
|| state == InferiorUnrunnable;
|
||||||
setBusyCursor(!notbusy);
|
setBusyCursor(!notbusy);
|
||||||
|
|
||||||
if (alsoUpdateCompanion && m_companionEngine)
|
|
||||||
m_companionEngine->updateState(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerEnginePrivate::updateReverseActions()
|
void DebuggerEnginePrivate::updateReverseActions()
|
||||||
@@ -1690,9 +1691,9 @@ void DebuggerEngine::notifyInferiorExited()
|
|||||||
d->doShutdownEngine();
|
d->doShutdownEngine();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerEngine::updateState(bool alsoUpdateCompanion)
|
void DebuggerEngine::updateState()
|
||||||
{
|
{
|
||||||
d->updateState(alsoUpdateCompanion);
|
d->updateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
WatchTreeView *DebuggerEngine::inspectorView()
|
WatchTreeView *DebuggerEngine::inspectorView()
|
||||||
@@ -1793,17 +1794,28 @@ void DebuggerEngine::setState(DebuggerState state, bool forced)
|
|||||||
if (!forced && !isAllowedTransition(oldState, state))
|
if (!forced && !isAllowedTransition(oldState, state))
|
||||||
qDebug() << "*** UNEXPECTED STATE TRANSITION: " << this << msg;
|
qDebug() << "*** UNEXPECTED STATE TRANSITION: " << this << msg;
|
||||||
|
|
||||||
if (state == EngineRunRequested)
|
if (state == EngineRunRequested) {
|
||||||
emit engineStarted();
|
emit engineStarted();
|
||||||
|
d->m_perspective->select();
|
||||||
|
}
|
||||||
|
|
||||||
showMessage(msg, LogDebug);
|
showMessage(msg, LogDebug);
|
||||||
|
|
||||||
d->updateState(true);
|
d->updateState();
|
||||||
|
if (d->m_companionEngine)
|
||||||
|
d->m_companionEngine->d->updateState();
|
||||||
|
|
||||||
if (oldState != d->m_state)
|
if (oldState != d->m_state)
|
||||||
emit EngineManager::instance()->engineStateChanged(this);
|
emit EngineManager::instance()->engineStateChanged(this);
|
||||||
|
|
||||||
if (state == DebuggerFinished) {
|
if (state == DebuggerFinished) {
|
||||||
|
d->setBusyCursor(false);
|
||||||
|
|
||||||
|
// Give up ownership on claimed breakpoints.
|
||||||
|
d->m_breakHandler.releaseAllBreakpoints();
|
||||||
|
d->m_toolTipManager.deregisterEngine();
|
||||||
|
d->m_memoryAgents.handleDebuggerFinished();
|
||||||
|
|
||||||
d->destroyPerspective();
|
d->destroyPerspective();
|
||||||
emit engineFinished();
|
emit engineFinished();
|
||||||
}
|
}
|
||||||
|
@@ -416,7 +416,7 @@ protected:
|
|||||||
void notifyInferiorStopFailed();
|
void notifyInferiorStopFailed();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void updateState(bool alsoUpdateCompanion);
|
void updateState();
|
||||||
QString formatStartParameters() const;
|
QString formatStartParameters() const;
|
||||||
WatchTreeView *inspectorView();
|
WatchTreeView *inspectorView();
|
||||||
void updateLocalsWindow(bool showReturn);
|
void updateLocalsWindow(bool showReturn);
|
||||||
|
@@ -28,24 +28,6 @@
|
|||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
// DebuggerMainWindow dock widget names
|
|
||||||
const char DOCKWIDGET_BREAKPOINTMANAGER[] = "Debugger.Docks.BreakpointManager";
|
|
||||||
const char DOCKWIDGET_ENGINEMANAGER[] = "Debugger.Docks.Snapshots";
|
|
||||||
const char DOCKWIDGET_GLOBALLOG[] = "Debugger.Docks.GlobalLog";
|
|
||||||
|
|
||||||
const char DOCKWIDGET_BREAK[] = "Debugger.Docks.Break";
|
|
||||||
const char DOCKWIDGET_MODULES[] = "Debugger.Docks.Modules";
|
|
||||||
const char DOCKWIDGET_REGISTER[] = "Debugger.Docks.Register";
|
|
||||||
const char DOCKWIDGET_OUTPUT[] = "Debugger.Docks.Output";
|
|
||||||
const char DOCKWIDGET_STACK[] = "Debugger.Docks.Stack";
|
|
||||||
const char DOCKWIDGET_SOURCE_FILES[] = "Debugger.Docks.SourceFiles";
|
|
||||||
const char DOCKWIDGET_THREADS[] = "Debugger.Docks.Threads";
|
|
||||||
const char DOCKWIDGET_LOCALS_AND_INSPECTOR[] = "Debugger.Docks.LocalsAndInspector";
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
|
|
||||||
namespace Constants {
|
namespace Constants {
|
||||||
|
|
||||||
const char DEBUGGER_COMMON_SETTINGS_ID[] = "A.Debugger.General";
|
const char DEBUGGER_COMMON_SETTINGS_ID[] = "A.Debugger.General";
|
||||||
|
@@ -49,9 +49,10 @@
|
|||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QDebug>
|
#include <QContextMenuEvent>
|
||||||
#include <QDockWidget>
|
#include <QDockWidget>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
|
#include <QLoggingCategory>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QScrollArea>
|
#include <QScrollArea>
|
||||||
#include <QStackedWidget>
|
#include <QStackedWidget>
|
||||||
@@ -62,37 +63,57 @@
|
|||||||
using namespace Debugger;
|
using namespace Debugger;
|
||||||
using namespace Core;
|
using namespace Core;
|
||||||
|
|
||||||
|
Q_LOGGING_CATEGORY(perspectivesLog, "qtc.utils.perspectives", QtWarningMsg)
|
||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
|
|
||||||
|
const int SettingsVersion = 3;
|
||||||
|
|
||||||
const char LAST_PERSPECTIVE_KEY[] = "LastPerspective";
|
const char LAST_PERSPECTIVE_KEY[] = "LastPerspective";
|
||||||
const char OWNED_BY_PERSPECTIVE[] = "OwnedByPerspective";
|
const char MAINWINDOW_KEY[] = "Debugger.MainWindow";
|
||||||
|
const char AUTOHIDE_TITLEBARS_KEY[] = "AutoHideTitleBars";
|
||||||
|
const char SHOW_CENTRALWIDGET_KEY[] = "ShowCentralWidget";
|
||||||
|
const char STATE_KEY[] = "State";
|
||||||
|
const char CHANGED_DOCK_KEY[] = "ChangedDocks";
|
||||||
|
|
||||||
static DebuggerMainWindow *theMainWindow = nullptr;
|
static DebuggerMainWindow *theMainWindow = nullptr;
|
||||||
|
|
||||||
class DockOperation
|
class DockOperation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
void setupLayout();
|
||||||
|
QString name() const { QTC_ASSERT(widget, return QString()); return widget->objectName(); }
|
||||||
|
|
||||||
|
Core::Id commandId;
|
||||||
QPointer<QWidget> widget;
|
QPointer<QWidget> widget;
|
||||||
QString anchorDockId;
|
QPointer<QDockWidget> dock;
|
||||||
|
QPointer<QWidget> anchorWidget;
|
||||||
Perspective::OperationType operationType = Perspective::Raise;
|
Perspective::OperationType operationType = Perspective::Raise;
|
||||||
bool visibleByDefault = true;
|
bool visibleByDefault = true;
|
||||||
|
bool visibleByUser = true;
|
||||||
Qt::DockWidgetArea area = Qt::BottomDockWidgetArea;
|
Qt::DockWidgetArea area = Qt::BottomDockWidgetArea;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PerspectivePrivate
|
class PerspectivePrivate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void showToolBar();
|
void showInnerToolBar();
|
||||||
void hideToolBar();
|
void hideInnerToolBar();
|
||||||
void restoreLayout();
|
void restoreLayout();
|
||||||
void saveLayout();
|
void saveLayout();
|
||||||
|
void resetPerspective();
|
||||||
|
void populatePerspective();
|
||||||
|
void depopulatePerspective();
|
||||||
|
void saveAsLastUsedPerspective();
|
||||||
|
Context context() const;
|
||||||
|
|
||||||
QString settingsId() const;
|
QString settingsId() const;
|
||||||
QToolButton *setupToolButton(QAction *action);
|
QToolButton *setupToolButton(QAction *action);
|
||||||
|
|
||||||
QString m_id;
|
QString m_id;
|
||||||
QString m_name;
|
QString m_name;
|
||||||
QString m_parentPerspectiveId;
|
QString m_parentPerspectiveId;
|
||||||
QString m_subPerspectiveType;
|
QString m_settingsId;
|
||||||
QVector<DockOperation> m_dockOperations;
|
QVector<DockOperation> m_dockOperations;
|
||||||
QPointer<QWidget> m_centralWidget;
|
QPointer<QWidget> m_centralWidget;
|
||||||
Perspective::Callback m_aboutToActivateCallback;
|
Perspective::Callback m_aboutToActivateCallback;
|
||||||
@@ -100,8 +121,6 @@ public:
|
|||||||
QHBoxLayout *m_innerToolBarLayout = nullptr;
|
QHBoxLayout *m_innerToolBarLayout = nullptr;
|
||||||
QPointer<QWidget> m_switcher;
|
QPointer<QWidget> m_switcher;
|
||||||
QString m_lastActiveSubPerspectiveId;
|
QString m_lastActiveSubPerspectiveId;
|
||||||
QHash<QString, QVariant> m_nonPersistenSettings;
|
|
||||||
Perspective::ShouldPersistChecker m_shouldPersistChecker;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DebuggerMainWindowPrivate : public QObject
|
class DebuggerMainWindowPrivate : public QObject
|
||||||
@@ -118,20 +137,30 @@ public:
|
|||||||
void registerPerspective(Perspective *perspective);
|
void registerPerspective(Perspective *perspective);
|
||||||
void resetCurrentPerspective();
|
void resetCurrentPerspective();
|
||||||
int indexInChooser(Perspective *perspective) const;
|
int indexInChooser(Perspective *perspective) const;
|
||||||
void fixupLayoutIfNeeded();
|
|
||||||
void updatePerspectiveChooserWidth();
|
void updatePerspectiveChooserWidth();
|
||||||
|
|
||||||
|
void cleanDocks();
|
||||||
|
void setCentralWidget(QWidget *widget);
|
||||||
|
|
||||||
|
QDockWidget *dockForWidget(QWidget *widget) const;
|
||||||
|
|
||||||
|
void setCurrentPerspective(Perspective *perspective)
|
||||||
|
{
|
||||||
|
m_currentPerspective = perspective;
|
||||||
|
}
|
||||||
|
|
||||||
DebuggerMainWindow *q = nullptr;
|
DebuggerMainWindow *q = nullptr;
|
||||||
Perspective *m_currentPerspective = nullptr;
|
QPointer<Perspective> m_currentPerspective = nullptr;
|
||||||
QComboBox *m_perspectiveChooser = nullptr;
|
QComboBox *m_perspectiveChooser = nullptr;
|
||||||
QStackedWidget *m_centralWidgetStack = nullptr;
|
QStackedWidget *m_centralWidgetStack = nullptr;
|
||||||
QHBoxLayout *m_subPerspectiveSwitcherLayout = nullptr;
|
QHBoxLayout *m_subPerspectiveSwitcherLayout = nullptr;
|
||||||
QHBoxLayout *m_innerToolsLayout = nullptr;
|
QHBoxLayout *m_innerToolsLayout = nullptr;
|
||||||
QWidget *m_editorPlaceHolder = nullptr;
|
QPointer<QWidget> m_editorPlaceHolder;
|
||||||
Utils::StatusLabel *m_statusLabel = nullptr;
|
Utils::StatusLabel *m_statusLabel = nullptr;
|
||||||
QDockWidget *m_toolBarDock = nullptr;
|
QDockWidget *m_toolBarDock = nullptr;
|
||||||
|
|
||||||
QList<Perspective *> m_perspectives;
|
QList<QPointer<Perspective>> m_perspectives;
|
||||||
|
QSet<QString> m_persistentChangedDocks;
|
||||||
};
|
};
|
||||||
|
|
||||||
DebuggerMainWindowPrivate::DebuggerMainWindowPrivate(DebuggerMainWindow *parent)
|
DebuggerMainWindowPrivate::DebuggerMainWindowPrivate(DebuggerMainWindow *parent)
|
||||||
@@ -211,10 +240,9 @@ DebuggerMainWindowPrivate::DebuggerMainWindowPrivate(DebuggerMainWindow *parent)
|
|||||||
m_toolBarDock = dock;
|
m_toolBarDock = dock;
|
||||||
q->addDockWidget(Qt::BottomDockWidgetArea, m_toolBarDock);
|
q->addDockWidget(Qt::BottomDockWidgetArea, m_toolBarDock);
|
||||||
|
|
||||||
connect(viewButton, &QAbstractButton::clicked, [this, viewButton] {
|
connect(viewButton, &QAbstractButton::clicked, this, [this, viewButton] {
|
||||||
QMenu menu;
|
ActionContainer *viewsMenu = ActionManager::actionContainer(Core::Constants::M_WINDOW_VIEWS);
|
||||||
q->addDockActionsToMenu(&menu);
|
viewsMenu->menu()->exec(viewButton->mapToGlobal(QPoint()));
|
||||||
menu.exec(viewButton->mapToGlobal(QPoint()));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(closeButton, &QAbstractButton::clicked, [] {
|
connect(closeButton, &QAbstractButton::clicked, [] {
|
||||||
@@ -256,6 +284,19 @@ DebuggerMainWindow::DebuggerMainWindow()
|
|||||||
"Debugger.Views.ResetSimple", debugcontext);
|
"Debugger.Views.ResetSimple", debugcontext);
|
||||||
cmd->setAttribute(Command::CA_Hide);
|
cmd->setAttribute(Command::CA_Hide);
|
||||||
viewsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE);
|
viewsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE);
|
||||||
|
|
||||||
|
connect(ICore::instance(), &ICore::saveSettingsRequested, this, [this] {
|
||||||
|
// There's one saveSettings triggered after plugin loading intentionally.
|
||||||
|
// We do not want to save anything at that time.
|
||||||
|
static bool firstOne = true;
|
||||||
|
if (firstOne) {
|
||||||
|
qCDebug(perspectivesLog) << "FIRST SAVE SETTINGS REQUEST IGNORED";
|
||||||
|
firstOne = false;
|
||||||
|
} else {
|
||||||
|
qCDebug(perspectivesLog) << "SAVING SETTINGS";
|
||||||
|
savePersistentSettings();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
DebuggerMainWindow::~DebuggerMainWindow()
|
DebuggerMainWindow::~DebuggerMainWindow()
|
||||||
@@ -263,6 +304,12 @@ DebuggerMainWindow::~DebuggerMainWindow()
|
|||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DebuggerMainWindow::contextMenuEvent(QContextMenuEvent *ev)
|
||||||
|
{
|
||||||
|
ActionContainer *viewsMenu = ActionManager::actionContainer(Core::Constants::M_WINDOW_VIEWS);
|
||||||
|
viewsMenu->menu()->exec(ev->globalPos());
|
||||||
|
}
|
||||||
|
|
||||||
void DebuggerMainWindow::ensureMainWindowExists()
|
void DebuggerMainWindow::ensureMainWindowExists()
|
||||||
{
|
{
|
||||||
if (!theMainWindow)
|
if (!theMainWindow)
|
||||||
@@ -271,6 +318,8 @@ void DebuggerMainWindow::ensureMainWindowExists()
|
|||||||
|
|
||||||
void DebuggerMainWindow::doShutdown()
|
void DebuggerMainWindow::doShutdown()
|
||||||
{
|
{
|
||||||
|
QTC_ASSERT(theMainWindow, return);
|
||||||
|
|
||||||
delete theMainWindow;
|
delete theMainWindow;
|
||||||
theMainWindow = nullptr;
|
theMainWindow = nullptr;
|
||||||
}
|
}
|
||||||
@@ -286,9 +335,12 @@ void DebuggerMainWindowPrivate::registerPerspective(Perspective *perspective)
|
|||||||
|
|
||||||
void DebuggerMainWindowPrivate::destroyPerspective(Perspective *perspective)
|
void DebuggerMainWindowPrivate::destroyPerspective(Perspective *perspective)
|
||||||
{
|
{
|
||||||
if (perspective == m_currentPerspective) {
|
qCDebug(perspectivesLog) << "ABOUT TO DESTROY PERSPECTIVE" << perspective->id();
|
||||||
depopulateCurrentPerspective();
|
|
||||||
m_currentPerspective = nullptr;
|
const bool wasCurrent = perspective == m_currentPerspective;
|
||||||
|
if (wasCurrent) {
|
||||||
|
qCDebug(perspectivesLog) << "RAMPING IT DOWN FIRST AS IT WAS CURRENT" << perspective->id();
|
||||||
|
perspective->rampDownAsCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_perspectives.removeAll(perspective);
|
m_perspectives.removeAll(perspective);
|
||||||
@@ -298,6 +350,31 @@ void DebuggerMainWindowPrivate::destroyPerspective(Perspective *perspective)
|
|||||||
const int idx = indexInChooser(perspective);
|
const int idx = indexInChooser(perspective);
|
||||||
if (idx != -1)
|
if (idx != -1)
|
||||||
m_perspectiveChooser->removeItem(idx);
|
m_perspectiveChooser->removeItem(idx);
|
||||||
|
|
||||||
|
for (DockOperation &op : perspective->d->m_dockOperations) {
|
||||||
|
if (op.commandId.isValid())
|
||||||
|
ActionManager::unregisterAction(op.dock->toggleViewAction(), op.commandId);
|
||||||
|
if (op.dock) {
|
||||||
|
theMainWindow->removeDockWidget(op.dock);
|
||||||
|
op.widget->setParent(nullptr); // Prevent deletion
|
||||||
|
op.dock->setParent(nullptr);
|
||||||
|
delete op.dock;
|
||||||
|
op.dock = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wasCurrent) {
|
||||||
|
if (Perspective *parent = Perspective::findPerspective(perspective->d->m_parentPerspectiveId)) {
|
||||||
|
qCDebug(perspectivesLog) << "RAMPING UP PARENT PERSPECTIVE" << parent->id();
|
||||||
|
parent->rampUpAsCurrent();
|
||||||
|
} else {
|
||||||
|
qCDebug(perspectivesLog) << "RAMPED DOWN WAS ACTION, BUT NO PARENT AVAILABLE. TAKE FIRST BEST";
|
||||||
|
if (QTC_GUARD(!m_perspectives.isEmpty()))
|
||||||
|
m_perspectives.first()->rampUpAsCurrent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug(perspectivesLog) << "DESTROYED PERSPECTIVE" << perspective->id();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerMainWindow::showStatusMessage(const QString &message, int timeoutMS)
|
void DebuggerMainWindow::showStatusMessage(const QString &message, int timeoutMS)
|
||||||
@@ -309,36 +386,122 @@ void DebuggerMainWindow::showStatusMessage(const QString &message, int timeoutMS
|
|||||||
void DebuggerMainWindow::enterDebugMode()
|
void DebuggerMainWindow::enterDebugMode()
|
||||||
{
|
{
|
||||||
theMainWindow->setDockActionsVisible(true);
|
theMainWindow->setDockActionsVisible(true);
|
||||||
Perspective *perspective = theMainWindow->d->m_currentPerspective;
|
theMainWindow->restorePersistentSettings();
|
||||||
if (!perspective) {
|
QTC_CHECK(theMainWindow->d->m_currentPerspective == nullptr);
|
||||||
const QSettings *settings = ICore::settings();
|
|
||||||
const QString lastPerspectiveId = settings->value(LAST_PERSPECTIVE_KEY).toString();
|
QSettings *settings = ICore::settings();
|
||||||
perspective = Perspective::findPerspective(lastPerspectiveId);
|
const QString lastPerspectiveId = settings->value(LAST_PERSPECTIVE_KEY).toString();
|
||||||
// If we don't find a perspective with the stored name, pick any.
|
Perspective *perspective = Perspective::findPerspective(lastPerspectiveId);
|
||||||
// This can happen e.g. when a plugin was disabled that provided
|
// If we don't find a perspective with the stored name, pick any.
|
||||||
// the stored perspective, or when the save file was modified externally.
|
// This can happen e.g. when a plugin was disabled that provided
|
||||||
if (!perspective && !theMainWindow->d->m_perspectives.isEmpty())
|
// the stored perspective, or when the save file was modified externally.
|
||||||
perspective = theMainWindow->d->m_perspectives.first();
|
if (!perspective && !theMainWindow->d->m_perspectives.isEmpty())
|
||||||
}
|
perspective = theMainWindow->d->m_perspectives.first();
|
||||||
|
|
||||||
// There's at least the debugger preset perspective that should be found above.
|
// There's at least the debugger preset perspective that should be found above.
|
||||||
QTC_ASSERT(perspective, return);
|
QTC_ASSERT(perspective, return);
|
||||||
perspective->select();
|
|
||||||
|
if (auto sub = Perspective::findPerspective(perspective->d->m_lastActiveSubPerspectiveId)) {
|
||||||
|
qCDebug(perspectivesLog) << "SWITCHING TO SUBPERSPECTIVE" << sub->d->m_id;
|
||||||
|
perspective = sub;
|
||||||
|
}
|
||||||
|
|
||||||
|
perspective->rampUpAsCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerMainWindow::leaveDebugMode()
|
void DebuggerMainWindow::leaveDebugMode()
|
||||||
{
|
{
|
||||||
if (Perspective *perspective = theMainWindow->d->m_currentPerspective)
|
theMainWindow->savePersistentSettings();
|
||||||
perspective->d->saveLayout();
|
|
||||||
|
if (theMainWindow->d->m_currentPerspective)
|
||||||
|
theMainWindow->d->m_currentPerspective->rampDownAsCurrent();
|
||||||
|
QTC_CHECK(theMainWindow->d->m_currentPerspective == nullptr);
|
||||||
|
|
||||||
theMainWindow->setDockActionsVisible(false);
|
theMainWindow->setDockActionsVisible(false);
|
||||||
|
|
||||||
// Hide dock widgets manually in case they are floating.
|
// Hide dock widgets manually in case they are floating.
|
||||||
for (QDockWidget *dockWidget : theMainWindow->dockWidgets()) {
|
for (QDockWidget *dockWidget : theMainWindow->dockWidgets()) {
|
||||||
if (dockWidget->isFloating())
|
if (dockWidget->isFloating())
|
||||||
dockWidget->hide();
|
dockWidget->setVisible(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DebuggerMainWindow::restorePersistentSettings()
|
||||||
|
{
|
||||||
|
qCDebug(perspectivesLog) << "RESTORE PERSISTENT";
|
||||||
|
QSettings *settings = ICore::settings();
|
||||||
|
settings->beginGroup(MAINWINDOW_KEY);
|
||||||
|
const bool res = theMainWindow->restoreState(settings->value(STATE_KEY).toByteArray(),
|
||||||
|
SettingsVersion);
|
||||||
|
if (!res)
|
||||||
|
qCDebug(perspectivesLog) << "NO READABLE PERSISTENT SETTINGS FOUND, ASSUMING NEW CLEAN SETTINGS";
|
||||||
|
|
||||||
|
theMainWindow->setAutoHideTitleBars(settings->value(AUTOHIDE_TITLEBARS_KEY, true).toBool());
|
||||||
|
theMainWindow->showCentralWidget(settings->value(SHOW_CENTRALWIDGET_KEY, true).toBool());
|
||||||
|
theMainWindow->d->m_persistentChangedDocks
|
||||||
|
= QSet<QString>::fromList(settings->value(CHANGED_DOCK_KEY).toStringList());
|
||||||
|
settings->endGroup();
|
||||||
|
|
||||||
|
qCDebug(perspectivesLog) << "LOADED DOCKS:" << theMainWindow->d->m_persistentChangedDocks;
|
||||||
|
|
||||||
|
for (Perspective *perspective : theMainWindow->d->m_perspectives) {
|
||||||
|
qCDebug(perspectivesLog) << "RESTORING PERSPECTIVE" << perspective->d->m_id;
|
||||||
|
for (DockOperation &op : perspective->d->m_dockOperations) {
|
||||||
|
if (op.operationType != Perspective::Raise) {
|
||||||
|
QTC_ASSERT(op.dock, continue);
|
||||||
|
QTC_ASSERT(op.widget, continue);
|
||||||
|
if (theMainWindow->d->m_persistentChangedDocks.contains(op.name())) {
|
||||||
|
qCDebug(perspectivesLog) << "DOCK " << op.name() << "*** UNUSUAL";
|
||||||
|
op.visibleByUser = !op.visibleByDefault;
|
||||||
|
} else {
|
||||||
|
qCDebug(perspectivesLog) << "DOCK " << op.name() << "NORMAL";
|
||||||
|
QTC_CHECK(op.visibleByUser == op.visibleByDefault);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Perspective *DebuggerMainWindow::currentPerspective()
|
||||||
|
{
|
||||||
|
return theMainWindow->d->m_currentPerspective;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebuggerMainWindow::savePersistentSettings()
|
||||||
|
{
|
||||||
|
// The current one might have active, non saved changes.
|
||||||
|
if (Perspective *perspective = theMainWindow->d->m_currentPerspective)
|
||||||
|
perspective->d->saveLayout();
|
||||||
|
|
||||||
|
qCDebug(perspectivesLog) << "SAVE PERSISTENT";
|
||||||
|
|
||||||
|
QSet<QString> changedDocks = theMainWindow->d->m_persistentChangedDocks;
|
||||||
|
for (Perspective *perspective : theMainWindow->d->m_perspectives) {
|
||||||
|
qCDebug(perspectivesLog) << "SAVE PERSPECTIVE" << perspective->d->m_id;
|
||||||
|
for (const DockOperation &op : perspective->d->m_dockOperations) {
|
||||||
|
if (op.operationType != Perspective::Raise) {
|
||||||
|
QTC_ASSERT(op.dock, continue);
|
||||||
|
QTC_ASSERT(op.widget, continue);
|
||||||
|
qCDebug(perspectivesLog) << "DOCK " << op.name() << "ACTIVE: " << op.visibleByUser;
|
||||||
|
if (op.visibleByUser != op.visibleByDefault)
|
||||||
|
changedDocks.insert(op.name());
|
||||||
|
else
|
||||||
|
changedDocks.remove(op.name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
theMainWindow->d->m_persistentChangedDocks = changedDocks;
|
||||||
|
qCDebug(perspectivesLog) << "CHANGED DOCKS:" << changedDocks;
|
||||||
|
|
||||||
|
QSettings *settings = ICore::settings();
|
||||||
|
settings->beginGroup(MAINWINDOW_KEY);
|
||||||
|
settings->setValue(CHANGED_DOCK_KEY, QStringList(changedDocks.toList()));
|
||||||
|
settings->setValue(STATE_KEY, theMainWindow->saveState(SettingsVersion));
|
||||||
|
settings->setValue(AUTOHIDE_TITLEBARS_KEY, theMainWindow->autoHideTitleBars());
|
||||||
|
settings->setValue(SHOW_CENTRALWIDGET_KEY, theMainWindow->isCentralWidgetShown());
|
||||||
|
settings->endGroup();
|
||||||
|
}
|
||||||
|
|
||||||
QWidget *DebuggerMainWindow::centralWidgetStack()
|
QWidget *DebuggerMainWindow::centralWidgetStack()
|
||||||
{
|
{
|
||||||
return theMainWindow ? theMainWindow->d->m_centralWidgetStack : nullptr;
|
return theMainWindow ? theMainWindow->d->m_centralWidgetStack : nullptr;
|
||||||
@@ -358,21 +521,95 @@ DebuggerMainWindow *DebuggerMainWindow::instance()
|
|||||||
|
|
||||||
Perspective *Perspective::findPerspective(const QString &perspectiveId)
|
Perspective *Perspective::findPerspective(const QString &perspectiveId)
|
||||||
{
|
{
|
||||||
return Utils::findOr(theMainWindow->d->m_perspectives, nullptr, [&](Perspective *perspective) {
|
QTC_ASSERT(theMainWindow, return nullptr);
|
||||||
return perspective->d->m_id == perspectiveId;
|
return Utils::findOr(theMainWindow->d->m_perspectives, nullptr,
|
||||||
|
[perspectiveId](Perspective *perspective) {
|
||||||
|
return perspective && perspective->d->m_id == perspectiveId;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Perspective::isCurrent() const
|
||||||
|
{
|
||||||
|
return theMainWindow->d->m_currentPerspective == this;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDockWidget *DebuggerMainWindowPrivate::dockForWidget(QWidget *widget) const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(widget, return nullptr);
|
||||||
|
|
||||||
|
for (QDockWidget *dock : q->dockWidgets()) {
|
||||||
|
if (dock->widget() == widget)
|
||||||
|
return dock;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void DebuggerMainWindowPrivate::resetCurrentPerspective()
|
void DebuggerMainWindowPrivate::resetCurrentPerspective()
|
||||||
{
|
{
|
||||||
if (m_currentPerspective) {
|
QTC_ASSERT(m_currentPerspective, return);
|
||||||
m_currentPerspective->d->m_nonPersistenSettings.clear();
|
cleanDocks();
|
||||||
m_currentPerspective->d->hideToolBar();
|
m_currentPerspective->d->resetPerspective();
|
||||||
|
setCentralWidget(m_currentPerspective->d->m_centralWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebuggerMainWindowPrivate::setCentralWidget(QWidget *widget)
|
||||||
|
{
|
||||||
|
if (widget) {
|
||||||
|
m_centralWidgetStack->addWidget(widget);
|
||||||
|
q->showCentralWidgetAction()->setText(widget->windowTitle());
|
||||||
|
} else {
|
||||||
|
m_centralWidgetStack->addWidget(m_editorPlaceHolder);
|
||||||
|
q->showCentralWidgetAction()->setText(DebuggerMainWindow::tr("Editor"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PerspectivePrivate::resetPerspective()
|
||||||
|
{
|
||||||
|
showInnerToolBar();
|
||||||
|
|
||||||
|
for (DockOperation &op : m_dockOperations) {
|
||||||
|
if (op.operationType == Perspective::Raise) {
|
||||||
|
QTC_ASSERT(op.dock, qCDebug(perspectivesLog) << op.name(); continue);
|
||||||
|
op.dock->raise();
|
||||||
|
} else {
|
||||||
|
op.setupLayout();
|
||||||
|
op.dock->setVisible(op.visibleByDefault);
|
||||||
|
qCDebug(perspectivesLog) << "SETTING " << op.name()
|
||||||
|
<< " TO ACTIVE: " << op.visibleByDefault;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockOperation::setupLayout()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(widget, return);
|
||||||
|
QTC_ASSERT(operationType != Perspective::Raise, return);
|
||||||
|
QTC_ASSERT(dock, return);
|
||||||
|
|
||||||
|
QDockWidget *anchor = nullptr;
|
||||||
|
if (anchorWidget)
|
||||||
|
anchor = theMainWindow->d->dockForWidget(anchorWidget);
|
||||||
|
else if (area == Qt::BottomDockWidgetArea)
|
||||||
|
anchor = theMainWindow->d->m_toolBarDock;
|
||||||
|
|
||||||
|
if (anchor) {
|
||||||
|
switch (operationType) {
|
||||||
|
case Perspective::AddToTab:
|
||||||
|
theMainWindow->tabifyDockWidget(anchor, dock);
|
||||||
|
break;
|
||||||
|
case Perspective::SplitHorizontal:
|
||||||
|
theMainWindow->splitDockWidget(anchor, dock, Qt::Horizontal);
|
||||||
|
break;
|
||||||
|
case Perspective::SplitVertical:
|
||||||
|
theMainWindow->splitDockWidget(anchor, dock, Qt::Vertical);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
theMainWindow->addDockWidget(area, dock);
|
||||||
}
|
}
|
||||||
depopulateCurrentPerspective();
|
|
||||||
populateCurrentPerspective();
|
|
||||||
if (m_currentPerspective)
|
|
||||||
m_currentPerspective->d->saveLayout();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int DebuggerMainWindowPrivate::indexInChooser(Perspective *perspective) const
|
int DebuggerMainWindowPrivate::indexInChooser(Perspective *perspective) const
|
||||||
@@ -380,47 +617,6 @@ int DebuggerMainWindowPrivate::indexInChooser(Perspective *perspective) const
|
|||||||
return perspective ? m_perspectiveChooser->findData(perspective->d->m_id) : -1;
|
return perspective ? m_perspectiveChooser->findData(perspective->d->m_id) : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerMainWindowPrivate::fixupLayoutIfNeeded()
|
|
||||||
{
|
|
||||||
// Evil workaround for QTCREATORBUG-21455: In some so far unknown situation
|
|
||||||
// the saveLayout/restoreLayout process leads to a situation where some docks
|
|
||||||
// do not end up below the perspective toolbar even though they were there
|
|
||||||
// initially, leading to an awkward dock layout.
|
|
||||||
// This here tries to detect the situation (sonmething else in the bottom
|
|
||||||
// area is at the right of the toolbar) "corrects" that by restoring the
|
|
||||||
// default layout.
|
|
||||||
|
|
||||||
if (m_toolBarDock->width() != q->width()) {
|
|
||||||
qDebug() << "Scrambled dock layout found. Resetting it.";
|
|
||||||
resetCurrentPerspective();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebuggerMainWindowPrivate::selectPerspective(Perspective *perspective)
|
|
||||||
{
|
|
||||||
QTC_ASSERT(perspective, return);
|
|
||||||
|
|
||||||
if (m_currentPerspective) {
|
|
||||||
m_currentPerspective->d->saveLayout();
|
|
||||||
m_currentPerspective->d->hideToolBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
depopulateCurrentPerspective();
|
|
||||||
|
|
||||||
m_currentPerspective = perspective;
|
|
||||||
|
|
||||||
perspective->aboutToActivate();
|
|
||||||
|
|
||||||
populateCurrentPerspective();
|
|
||||||
|
|
||||||
if (m_currentPerspective) {
|
|
||||||
m_currentPerspective->d->restoreLayout();
|
|
||||||
fixupLayoutIfNeeded();
|
|
||||||
}
|
|
||||||
|
|
||||||
updatePerspectiveChooserWidth();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebuggerMainWindowPrivate::updatePerspectiveChooserWidth()
|
void DebuggerMainWindowPrivate::updatePerspectiveChooserWidth()
|
||||||
{
|
{
|
||||||
Perspective *perspective = m_currentPerspective;
|
Perspective *perspective = m_currentPerspective;
|
||||||
@@ -444,111 +640,72 @@ void DebuggerMainWindowPrivate::updatePerspectiveChooserWidth()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerMainWindowPrivate::depopulateCurrentPerspective()
|
void DebuggerMainWindowPrivate::cleanDocks()
|
||||||
{
|
{
|
||||||
// Clean up old perspective.
|
m_statusLabel->clear();
|
||||||
for (QDockWidget *dock : q->dockWidgets()) {
|
|
||||||
if (dock->property(OWNED_BY_PERSPECTIVE).toBool()) {
|
|
||||||
// Prevent deletion of plugin-owned widgets.
|
|
||||||
if (dock->widget())
|
|
||||||
dock->widget()->setParent(nullptr);
|
|
||||||
ActionManager::unregisterAction(dock->toggleViewAction(),
|
|
||||||
Id("Dock.").withSuffix(dock->objectName()));
|
|
||||||
delete dock;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_currentPerspective) {
|
for (QDockWidget *dock : q->dockWidgets()) {
|
||||||
ICore::removeAdditionalContext(m_currentPerspective->context());
|
if (dock != m_toolBarDock)
|
||||||
QWidget *central = m_currentPerspective->centralWidget();
|
dock->setVisible(false);
|
||||||
m_centralWidgetStack->removeWidget(central ? central : m_editorPlaceHolder);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerMainWindowPrivate::populateCurrentPerspective()
|
void PerspectivePrivate::depopulatePerspective()
|
||||||
{
|
{
|
||||||
// Create dock widgets wrapping ther perspective's widgets.
|
ICore::removeAdditionalContext(context());
|
||||||
QHash<QString, QDockWidget *> dockForDockId;
|
theMainWindow->d->m_centralWidgetStack
|
||||||
for (const DockOperation &op : m_currentPerspective->d->m_dockOperations) {
|
->removeWidget(m_centralWidget ? m_centralWidget : theMainWindow->d->m_editorPlaceHolder);
|
||||||
if (op.operationType == Perspective::Raise)
|
|
||||||
continue;
|
|
||||||
QTC_ASSERT(op.widget, continue);
|
|
||||||
const QString dockId = op.widget->objectName();
|
|
||||||
QTC_CHECK(!dockId.isEmpty());
|
|
||||||
QTC_ASSERT(!dockForDockId.contains(dockId), continue);
|
|
||||||
QDockWidget *dock = q->addDockForWidget(op.widget);
|
|
||||||
dock->setProperty(OWNED_BY_PERSPECTIVE, true);
|
|
||||||
dockForDockId[dockId] = dock;
|
|
||||||
q->addDockWidget(op.area, dock);
|
|
||||||
|
|
||||||
QAction *toggleViewAction = dock->toggleViewAction();
|
theMainWindow->d->m_statusLabel->clear();
|
||||||
toggleViewAction->setText(dock->windowTitle());
|
|
||||||
|
|
||||||
Command *cmd = ActionManager::registerAction(toggleViewAction,
|
for (QDockWidget *dock : theMainWindow->dockWidgets()) {
|
||||||
Id("Dock.").withSuffix(dock->objectName()),
|
if (dock != theMainWindow->d->m_toolBarDock)
|
||||||
m_currentPerspective->context());
|
dock->setVisible(false);
|
||||||
cmd->setAttribute(Command::CA_Hide);
|
|
||||||
ActionManager::actionContainer(Core::Constants::M_WINDOW_VIEWS)->addAction(cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_currentPerspective->d->showToolBar();
|
hideInnerToolBar();
|
||||||
|
}
|
||||||
|
|
||||||
// Pre-arrange dock widgets.
|
void PerspectivePrivate::saveAsLastUsedPerspective()
|
||||||
for (const DockOperation &op : m_currentPerspective->d->m_dockOperations) {
|
{
|
||||||
QTC_ASSERT(op.widget, continue);
|
if (Perspective *parent = Perspective::findPerspective(m_parentPerspectiveId))
|
||||||
const QString dockId = op.widget->objectName();
|
parent->d->m_lastActiveSubPerspectiveId = m_id;
|
||||||
QDockWidget *dock = dockForDockId.value(dockId);
|
else
|
||||||
QTC_ASSERT(dock, continue);
|
m_lastActiveSubPerspectiveId.clear();
|
||||||
if (op.operationType == Perspective::Raise) {
|
|
||||||
dock->raise();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
QDockWidget *anchor = dockForDockId.value(op.anchorDockId);
|
|
||||||
if (!anchor && op.area == Qt::BottomDockWidgetArea) {
|
|
||||||
anchor = m_toolBarDock;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (anchor) {
|
const QString &lastKey = m_parentPerspectiveId.isEmpty() ? m_id : m_parentPerspectiveId;
|
||||||
switch (op.operationType) {
|
qCDebug(perspectivesLog) << "SAVE LAST USED PERSPECTIVE" << lastKey;
|
||||||
case Perspective::AddToTab:
|
ICore::settings()->setValue(LAST_PERSPECTIVE_KEY, lastKey);
|
||||||
q->tabifyDockWidget(anchor, dock);
|
}
|
||||||
break;
|
|
||||||
case Perspective::SplitHorizontal:
|
void PerspectivePrivate::populatePerspective()
|
||||||
q->splitDockWidget(anchor, dock, Qt::Horizontal);
|
{
|
||||||
break;
|
showInnerToolBar();
|
||||||
case Perspective::SplitVertical:
|
|
||||||
q->splitDockWidget(anchor, dock, Qt::Vertical);
|
if (m_centralWidget) {
|
||||||
break;
|
theMainWindow->d->m_centralWidgetStack->addWidget(m_centralWidget);
|
||||||
default:
|
theMainWindow->showCentralWidgetAction()->setText(m_centralWidget->windowTitle());
|
||||||
break;
|
} else {
|
||||||
}
|
theMainWindow->d->m_centralWidgetStack->addWidget(theMainWindow->d->m_editorPlaceHolder);
|
||||||
}
|
theMainWindow->showCentralWidgetAction()->setText(DebuggerMainWindow::tr("Editor"));
|
||||||
dock->setVisible(op.visibleByDefault);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *central = m_currentPerspective->centralWidget();
|
ICore::addAdditionalContext(context());
|
||||||
m_centralWidgetStack->addWidget(central ? central : m_editorPlaceHolder);
|
|
||||||
q->showCentralWidgetAction()->setText(central ? central->windowTitle()
|
|
||||||
: DebuggerMainWindow::tr("Editor"));
|
|
||||||
|
|
||||||
m_statusLabel->clear();
|
restoreLayout();
|
||||||
|
|
||||||
ICore::addAdditionalContext(m_currentPerspective->context());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perspective
|
// Perspective
|
||||||
|
|
||||||
Perspective::Perspective(const QString &id, const QString &name,
|
Perspective::Perspective(const QString &id, const QString &name,
|
||||||
const QString &parentPerspectiveId,
|
const QString &parentPerspectiveId,
|
||||||
const QString &subPerspectiveType)
|
const QString &settingsId)
|
||||||
: d(new PerspectivePrivate)
|
: d(new PerspectivePrivate)
|
||||||
{
|
{
|
||||||
const bool shouldPersist = parentPerspectiveId.isEmpty();
|
|
||||||
d->m_id = id;
|
d->m_id = id;
|
||||||
d->m_name = name;
|
d->m_name = name;
|
||||||
d->m_parentPerspectiveId = parentPerspectiveId;
|
d->m_parentPerspectiveId = parentPerspectiveId;
|
||||||
d->m_subPerspectiveType = subPerspectiveType;
|
d->m_settingsId = settingsId;
|
||||||
d->m_shouldPersistChecker = [shouldPersist] { return shouldPersist; };
|
|
||||||
|
|
||||||
DebuggerMainWindow::ensureMainWindowExists();
|
DebuggerMainWindow::ensureMainWindowExists();
|
||||||
theMainWindow->d->registerPerspective(this);
|
theMainWindow->d->registerPerspective(this);
|
||||||
@@ -565,12 +722,8 @@ Perspective::Perspective(const QString &id, const QString &name,
|
|||||||
Perspective::~Perspective()
|
Perspective::~Perspective()
|
||||||
{
|
{
|
||||||
if (theMainWindow) {
|
if (theMainWindow) {
|
||||||
d->saveLayout();
|
|
||||||
|
|
||||||
delete d->m_innerToolBar;
|
delete d->m_innerToolBar;
|
||||||
d->m_innerToolBar = nullptr;
|
d->m_innerToolBar = nullptr;
|
||||||
|
|
||||||
theMainWindow->d->destroyPerspective(this);
|
|
||||||
}
|
}
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
@@ -596,12 +749,6 @@ void Perspective::setAboutToActivateCallback(const Perspective::Callback &cb)
|
|||||||
d->m_aboutToActivateCallback = cb;
|
d->m_aboutToActivateCallback = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Perspective::aboutToActivate() const
|
|
||||||
{
|
|
||||||
if (d->m_aboutToActivateCallback)
|
|
||||||
d->m_aboutToActivateCallback();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Perspective::setEnabled(bool enabled)
|
void Perspective::setEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(theMainWindow, return);
|
QTC_ASSERT(theMainWindow, return);
|
||||||
@@ -654,34 +801,24 @@ void Perspective::addToolbarSeparator()
|
|||||||
d->m_innerToolBarLayout->addWidget(new StyledSeparator(d->m_innerToolBar));
|
d->m_innerToolBarLayout->addWidget(new StyledSeparator(d->m_innerToolBar));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Perspective::setShouldPersistChecker(const ShouldPersistChecker &checker)
|
|
||||||
{
|
|
||||||
d->m_shouldPersistChecker = checker;
|
|
||||||
}
|
|
||||||
|
|
||||||
QWidget *Perspective::centralWidget() const
|
QWidget *Perspective::centralWidget() const
|
||||||
{
|
{
|
||||||
return d->m_centralWidget;
|
return d->m_centralWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
Perspective *Perspective::currentPerspective()
|
Context PerspectivePrivate::context() const
|
||||||
{
|
{
|
||||||
return theMainWindow ? theMainWindow->d->m_currentPerspective : nullptr;
|
return Context(Id::fromName(m_id.toUtf8()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Context Perspective::context() const
|
void PerspectivePrivate::showInnerToolBar()
|
||||||
{
|
|
||||||
return Context(Id::fromName(d->m_id.toUtf8()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PerspectivePrivate::showToolBar()
|
|
||||||
{
|
{
|
||||||
m_innerToolBar->setVisible(true);
|
m_innerToolBar->setVisible(true);
|
||||||
if (m_switcher)
|
if (m_switcher)
|
||||||
m_switcher->setVisible(true);
|
m_switcher->setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PerspectivePrivate::hideToolBar()
|
void PerspectivePrivate::hideInnerToolBar()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_innerToolBar, return);
|
QTC_ASSERT(m_innerToolBar, return);
|
||||||
m_innerToolBar->setVisible(false);
|
m_innerToolBar->setVisible(false);
|
||||||
@@ -698,63 +835,131 @@ void Perspective::addWindow(QWidget *widget,
|
|||||||
QTC_ASSERT(widget, return);
|
QTC_ASSERT(widget, return);
|
||||||
DockOperation op;
|
DockOperation op;
|
||||||
op.widget = widget;
|
op.widget = widget;
|
||||||
if (anchorWidget)
|
|
||||||
op.anchorDockId = anchorWidget->objectName();
|
|
||||||
op.operationType = type;
|
op.operationType = type;
|
||||||
|
op.anchorWidget = anchorWidget;
|
||||||
op.visibleByDefault = visibleByDefault;
|
op.visibleByDefault = visibleByDefault;
|
||||||
op.area = area;
|
op.area = area;
|
||||||
|
|
||||||
|
if (op.operationType != Perspective::Raise) {
|
||||||
|
qCDebug(perspectivesLog) << "CREATING DOCK " << op.name()
|
||||||
|
<< "DEFAULT: " << op.visibleByDefault;
|
||||||
|
op.dock = theMainWindow->addDockForWidget(op.widget);
|
||||||
|
op.commandId = Id("Dock.").withSuffix(op.name());
|
||||||
|
if (theMainWindow->restoreDockWidget(op.dock)) {
|
||||||
|
qCDebug(perspectivesLog) << "RESTORED SUCCESSFULLY";
|
||||||
|
} else {
|
||||||
|
qCDebug(perspectivesLog) << "COULD NOT RESTORE";
|
||||||
|
op.setupLayout();
|
||||||
|
}
|
||||||
|
op.dock->setVisible(false);
|
||||||
|
op.dock->toggleViewAction()->setText(op.dock->windowTitle());
|
||||||
|
|
||||||
|
QObject::connect(op.dock->toggleViewAction(), &QAction::changed, op.dock, [this, op] {
|
||||||
|
qCDebug(perspectivesLog) << "CHANGED: " << op.name()
|
||||||
|
<< "ACTION CHECKED: " << op.dock->toggleViewAction()->isChecked();
|
||||||
|
});
|
||||||
|
|
||||||
|
Command *cmd = ActionManager::registerAction(op.dock->toggleViewAction(),
|
||||||
|
op.commandId, d->context());
|
||||||
|
cmd->setAttribute(Command::CA_Hide);
|
||||||
|
ActionManager::actionContainer(Core::Constants::M_WINDOW_VIEWS)->addAction(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
op.visibleByUser = op.visibleByDefault;
|
||||||
|
if (theMainWindow->d->m_persistentChangedDocks.contains(op.name())) {
|
||||||
|
op.visibleByUser = !op.visibleByUser;
|
||||||
|
qCDebug(perspectivesLog) << "*** NON-DEFAULT USER: " << op.visibleByUser;
|
||||||
|
} else {
|
||||||
|
qCDebug(perspectivesLog) << "DEFAULT USER";
|
||||||
|
}
|
||||||
|
|
||||||
d->m_dockOperations.append(op);
|
d->m_dockOperations.append(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Perspective::destroy()
|
||||||
|
{
|
||||||
|
theMainWindow->d->destroyPerspective(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Perspective::rampDownAsCurrent()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(this == theMainWindow->d->m_currentPerspective, return);
|
||||||
|
d->saveLayout();
|
||||||
|
d->depopulatePerspective();
|
||||||
|
theMainWindow->d->setCurrentPerspective(nullptr);
|
||||||
|
|
||||||
|
Debugger::Internal::EngineManager::updatePerspectives();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Perspective::rampUpAsCurrent()
|
||||||
|
{
|
||||||
|
if (d->m_aboutToActivateCallback)
|
||||||
|
d->m_aboutToActivateCallback();
|
||||||
|
|
||||||
|
QTC_ASSERT(theMainWindow->d->m_currentPerspective == nullptr, return);
|
||||||
|
theMainWindow->d->setCurrentPerspective(this);
|
||||||
|
QTC_ASSERT(theMainWindow->d->m_currentPerspective == this, return);
|
||||||
|
|
||||||
|
d->populatePerspective();
|
||||||
|
|
||||||
|
theMainWindow->d->updatePerspectiveChooserWidth();
|
||||||
|
|
||||||
|
d->saveAsLastUsedPerspective();
|
||||||
|
|
||||||
|
Debugger::Internal::EngineManager::updatePerspectives();
|
||||||
|
}
|
||||||
|
|
||||||
void Perspective::select()
|
void Perspective::select()
|
||||||
{
|
{
|
||||||
Debugger::Internal::EngineManager::activateDebugMode();
|
Debugger::Internal::EngineManager::activateDebugMode();
|
||||||
if (Perspective::currentPerspective() == this)
|
|
||||||
return;
|
|
||||||
theMainWindow->d->selectPerspective(this);
|
|
||||||
if (Perspective *parent = Perspective::findPerspective(d->m_parentPerspectiveId))
|
|
||||||
parent->d->m_lastActiveSubPerspectiveId = d->m_id;
|
|
||||||
else
|
|
||||||
d->m_lastActiveSubPerspectiveId.clear();
|
|
||||||
|
|
||||||
const QString &lastKey = d->m_parentPerspectiveId.isEmpty() ? d->m_id : d->m_parentPerspectiveId;
|
if (theMainWindow->d->m_currentPerspective == this)
|
||||||
ICore::settings()->setValue(LAST_PERSPECTIVE_KEY, lastKey);
|
return;
|
||||||
|
|
||||||
|
if (theMainWindow->d->m_currentPerspective)
|
||||||
|
theMainWindow->d->m_currentPerspective->rampDownAsCurrent();
|
||||||
|
QTC_CHECK(theMainWindow->d->m_currentPerspective == nullptr);
|
||||||
|
|
||||||
|
rampUpAsCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PerspectivePrivate::restoreLayout()
|
void PerspectivePrivate::restoreLayout()
|
||||||
{
|
{
|
||||||
if (m_nonPersistenSettings.isEmpty()) {
|
qCDebug(perspectivesLog) << "PERSPECTIVE" << m_id << "RESTORING LAYOUT FROM " << settingsId();
|
||||||
//qDebug() << "PERSPECTIVE" << m_id << "RESTORE PERSISTENT FROM " << settingsId();
|
for (DockOperation &op : m_dockOperations) {
|
||||||
QSettings *settings = ICore::settings();
|
if (op.operationType != Perspective::Raise) {
|
||||||
settings->beginGroup(settingsId());
|
QTC_ASSERT(op.dock, continue);
|
||||||
theMainWindow->restoreSettings(settings);
|
const bool active = op.visibleByUser;
|
||||||
settings->endGroup();
|
op.dock->toggleViewAction()->setChecked(active);
|
||||||
m_nonPersistenSettings = theMainWindow->saveSettings();
|
op.dock->setVisible(active);
|
||||||
} else {
|
qCDebug(perspectivesLog) << "RESTORE DOCK " << op.name() << "ACTIVE: " << active
|
||||||
//qDebug() << "PERSPECTIVE" << m_id << "RESTORE FROM LOCAL TEMP";
|
<< (active == op.visibleByDefault ? "DEFAULT USER" : "*** NON-DEFAULT USER");
|
||||||
theMainWindow->restoreSettings(m_nonPersistenSettings);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PerspectivePrivate::saveLayout()
|
void PerspectivePrivate::saveLayout()
|
||||||
{
|
{
|
||||||
//qDebug() << "PERSPECTIVE" << m_id << "SAVE LOCAL TEMP";
|
qCDebug(perspectivesLog) << "PERSPECTIVE" << m_id << "SAVE LAYOUT TO " << settingsId();
|
||||||
m_nonPersistenSettings = theMainWindow->saveSettings();
|
for (DockOperation &op : m_dockOperations) {
|
||||||
|
if (op.operationType != Perspective::Raise) {
|
||||||
if (m_shouldPersistChecker()) {
|
QTC_ASSERT(op.dock, continue);
|
||||||
//qDebug() << "PERSPECTIVE" << m_id << "SAVE PERSISTENT TO " << settingsId();
|
QTC_ASSERT(op.widget, continue);
|
||||||
QSettings *settings = ICore::settings();
|
const bool active = op.dock->toggleViewAction()->isChecked();
|
||||||
settings->beginGroup(settingsId());
|
op.visibleByUser = active;
|
||||||
theMainWindow->saveSettings(settings);
|
if (active == op.visibleByDefault)
|
||||||
settings->endGroup();
|
theMainWindow->d->m_persistentChangedDocks.remove(op.name());
|
||||||
} else {
|
else
|
||||||
//qDebug() << "PERSPECTIVE" << m_id << "NOT PERSISTENT";
|
theMainWindow->d->m_persistentChangedDocks.insert(op.name());
|
||||||
|
qCDebug(perspectivesLog) << "SAVE DOCK " << op.name() << "ACTIVE: " << active
|
||||||
|
<< (active == op.visibleByDefault ? "DEFAULT USER" : "*** NON-DEFAULT USER");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PerspectivePrivate::settingsId() const
|
QString PerspectivePrivate::settingsId() const
|
||||||
{
|
{
|
||||||
return m_parentPerspectiveId.isEmpty() ? m_id : (m_parentPerspectiveId + '.' + m_subPerspectiveType);
|
return m_settingsId.isEmpty() ? m_id : m_settingsId;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToolbarAction
|
// ToolbarAction
|
||||||
|
@@ -59,12 +59,12 @@ public:
|
|||||||
QPointer<QToolButton> m_toolButton;
|
QPointer<QToolButton> m_toolButton;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DEBUGGER_EXPORT Perspective
|
class DEBUGGER_EXPORT Perspective : public QObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Perspective(const QString &id, const QString &name,
|
Perspective(const QString &id, const QString &name,
|
||||||
const QString &parentPerspectiveId = QString(),
|
const QString &parentPerspectiveId = QString(),
|
||||||
const QString &subPerspectiveType = QString());
|
const QString &settingId = QString());
|
||||||
~Perspective();
|
~Perspective();
|
||||||
|
|
||||||
enum OperationType { SplitVertical, SplitHorizontal, AddToTab, Raise };
|
enum OperationType { SplitVertical, SplitHorizontal, AddToTab, Raise };
|
||||||
@@ -92,26 +92,26 @@ public:
|
|||||||
|
|
||||||
using Callback = std::function<void()>;
|
using Callback = std::function<void()>;
|
||||||
void setAboutToActivateCallback(const Callback &cb);
|
void setAboutToActivateCallback(const Callback &cb);
|
||||||
void aboutToActivate() const;
|
|
||||||
|
|
||||||
void setEnabled(bool enabled);
|
void setEnabled(bool enabled);
|
||||||
|
|
||||||
void select();
|
void select();
|
||||||
|
void destroy();
|
||||||
|
|
||||||
static Perspective *currentPerspective();
|
|
||||||
static Perspective *findPerspective(const QString &perspectiveId);
|
static Perspective *findPerspective(const QString &perspectiveId);
|
||||||
|
|
||||||
Core::Context context() const;
|
bool isCurrent() const;
|
||||||
|
|
||||||
void showToolBar();
|
|
||||||
void hideToolBar();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void rampDownAsCurrent();
|
||||||
|
void rampUpAsCurrent();
|
||||||
|
|
||||||
Perspective(const Perspective &) = delete;
|
Perspective(const Perspective &) = delete;
|
||||||
void operator=(const Perspective &) = delete;
|
void operator=(const Perspective &) = delete;
|
||||||
|
|
||||||
friend class DebuggerMainWindow;
|
friend class DebuggerMainWindow;
|
||||||
friend class DebuggerMainWindowPrivate;
|
friend class DebuggerMainWindowPrivate;
|
||||||
|
friend class PerspectivePrivate;
|
||||||
class PerspectivePrivate *d = nullptr;
|
class PerspectivePrivate *d = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -132,12 +132,20 @@ public:
|
|||||||
static QWidget *centralWidgetStack();
|
static QWidget *centralWidgetStack();
|
||||||
void addSubPerspectiveSwitcher(QWidget *widget);
|
void addSubPerspectiveSwitcher(QWidget *widget);
|
||||||
|
|
||||||
|
static void savePersistentSettings();
|
||||||
|
static void restorePersistentSettings();
|
||||||
|
|
||||||
|
static Perspective *currentPerspective();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DebuggerMainWindow();
|
DebuggerMainWindow();
|
||||||
~DebuggerMainWindow() override;
|
~DebuggerMainWindow() override;
|
||||||
|
|
||||||
|
void contextMenuEvent(QContextMenuEvent *ev) override;
|
||||||
|
|
||||||
friend class Perspective;
|
friend class Perspective;
|
||||||
friend class PerspectivePrivate;
|
friend class PerspectivePrivate;
|
||||||
|
friend class DockOperation;
|
||||||
class DebuggerMainWindowPrivate *d = nullptr;
|
class DebuggerMainWindowPrivate *d = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1045,7 +1045,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
|
|||||||
m_breakpointManagerView->setSpanColumn(BreakpointFunctionColumn);
|
m_breakpointManagerView->setSpanColumn(BreakpointFunctionColumn);
|
||||||
m_breakpointManagerWindow = addSearch(m_breakpointManagerView);
|
m_breakpointManagerWindow = addSearch(m_breakpointManagerView);
|
||||||
m_breakpointManagerWindow->setWindowTitle(tr("Breakpoint Preset"));
|
m_breakpointManagerWindow->setWindowTitle(tr("Breakpoint Preset"));
|
||||||
m_breakpointManagerWindow->setObjectName(DOCKWIDGET_BREAKPOINTMANAGER);
|
m_breakpointManagerWindow->setObjectName("Debugger.Docks.BreakpointManager");
|
||||||
addLabel(m_breakpointManagerWindow, m_breakpointManagerWindow->windowTitle());
|
addLabel(m_breakpointManagerWindow, m_breakpointManagerWindow->windowTitle());
|
||||||
|
|
||||||
|
|
||||||
@@ -1057,7 +1057,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
|
|||||||
m_engineManagerView->setModel(m_engineManager.model());
|
m_engineManagerView->setModel(m_engineManager.model());
|
||||||
m_engineManagerWindow = addSearch(m_engineManagerView);
|
m_engineManagerWindow = addSearch(m_engineManagerView);
|
||||||
m_engineManagerWindow->setWindowTitle(tr("Debugger Perspectives"));
|
m_engineManagerWindow->setWindowTitle(tr("Debugger Perspectives"));
|
||||||
m_engineManagerWindow->setObjectName(DOCKWIDGET_ENGINEMANAGER);
|
m_engineManagerWindow->setObjectName("Debugger.Docks.Snapshots");
|
||||||
addLabel(m_engineManagerWindow, m_engineManagerWindow->windowTitle());
|
addLabel(m_engineManagerWindow, m_engineManagerWindow->windowTitle());
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
@@ -1356,7 +1356,8 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
|
|||||||
DebuggerMainWindow::leaveDebugMode();
|
DebuggerMainWindow::leaveDebugMode();
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(ModeManager::instance(), &ModeManager::currentModeChanged, this, [](Id mode) {
|
connect(ModeManager::instance(), &ModeManager::currentModeChanged, [](Id mode, Id oldMode) {
|
||||||
|
QTC_ASSERT(mode != oldMode, return);
|
||||||
if (mode == MODE_DEBUG) {
|
if (mode == MODE_DEBUG) {
|
||||||
DebuggerMainWindow::enterDebugMode();
|
DebuggerMainWindow::enterDebugMode();
|
||||||
if (IEditor *editor = EditorManager::currentEditor())
|
if (IEditor *editor = EditorManager::currentEditor())
|
||||||
@@ -1521,7 +1522,7 @@ void DebuggerPluginPrivate::updatePresetState()
|
|||||||
} else {
|
} else {
|
||||||
// The startup phase should be over once we are here.
|
// The startup phase should be over once we are here.
|
||||||
// But treat it as 'undisturbable if we are here by accident.
|
// But treat it as 'undisturbable if we are here by accident.
|
||||||
QTC_CHECK(state != DebuggerNotReady);
|
//QTC_CHECK(state != DebuggerNotReady);
|
||||||
// Everything else is "undisturbable".
|
// Everything else is "undisturbable".
|
||||||
m_startAction.setEnabled(false);
|
m_startAction.setEnabled(false);
|
||||||
m_debugWithoutDeployAction.setEnabled(false);
|
m_debugWithoutDeployAction.setEnabled(false);
|
||||||
@@ -1559,7 +1560,7 @@ void DebuggerPluginPrivate::onStartupProjectChanged(Project *project)
|
|||||||
}
|
}
|
||||||
for (DebuggerEngine *engine : EngineManager::engines()) {
|
for (DebuggerEngine *engine : EngineManager::engines()) {
|
||||||
// Run controls might be deleted during exit.
|
// Run controls might be deleted during exit.
|
||||||
engine->updateState(false);
|
engine->updateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
updatePresetState();
|
updatePresetState();
|
||||||
@@ -2014,11 +2015,9 @@ void DebuggerPluginPrivate::aboutToShutdown()
|
|||||||
m_shutdownTimer.setInterval(0);
|
m_shutdownTimer.setInterval(0);
|
||||||
m_shutdownTimer.setSingleShot(true);
|
m_shutdownTimer.setSingleShot(true);
|
||||||
connect(&m_shutdownTimer, &QTimer::timeout, this, &DebuggerPluginPrivate::doShutdown);
|
connect(&m_shutdownTimer, &QTimer::timeout, this, &DebuggerPluginPrivate::doShutdown);
|
||||||
for (DebuggerEngine *engine : m_engineManager.engines()) {
|
if (EngineManager::shutDown()) {
|
||||||
if (engine && engine->state() != Debugger::DebuggerNotReady) {
|
// If any engine is aborting we give them extra three seconds.
|
||||||
engine->abortDebugger();
|
m_shutdownTimer.setInterval(3000);
|
||||||
m_shutdownTimer.setInterval(3000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
m_shutdownTimer.start();
|
m_shutdownTimer.start();
|
||||||
}
|
}
|
||||||
|
@@ -728,8 +728,6 @@ void DebuggerRunTool::stop()
|
|||||||
|
|
||||||
void DebuggerRunTool::handleEngineStarted(DebuggerEngine *engine)
|
void DebuggerRunTool::handleEngineStarted(DebuggerEngine *engine)
|
||||||
{
|
{
|
||||||
EngineManager::activateEngine(engine);
|
|
||||||
|
|
||||||
// Correct:
|
// Correct:
|
||||||
// if (--d->engineStartsNeeded == 0) {
|
// if (--d->engineStartsNeeded == 0) {
|
||||||
// EngineManager::activateDebugMode();
|
// EngineManager::activateDebugMode();
|
||||||
|
@@ -155,16 +155,18 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
EngineItem *findEngineItem(DebuggerEngine *engine);
|
EngineItem *findEngineItem(DebuggerEngine *engine);
|
||||||
void activateEngine(DebuggerEngine *engine);
|
|
||||||
void activateEngineItem(EngineItem *engineItem);
|
void activateEngineItem(EngineItem *engineItem);
|
||||||
void activateEngineByIndex(int index);
|
void activateEngineByIndex(int index);
|
||||||
void selectUiForCurrentEngine();
|
void selectUiForCurrentEngine();
|
||||||
void updateEngineChooserVisibility();
|
void updateEngineChooserVisibility();
|
||||||
|
void updatePerspectives();
|
||||||
|
|
||||||
TreeModel<TypedTreeItem<EngineItem>, EngineItem> m_engineModel;
|
TreeModel<TypedTreeItem<EngineItem>, EngineItem> m_engineModel;
|
||||||
QPointer<EngineItem> m_currentItem;
|
QPointer<EngineItem> m_currentItem; // The primary information is DebuggerMainWindow::d->m_currentPerspective
|
||||||
Core::Id m_previousMode;
|
Core::Id m_previousMode;
|
||||||
QPointer<QComboBox> m_engineChooser;
|
QPointer<QComboBox> m_engineChooser;
|
||||||
|
bool m_shuttingDown = false;
|
||||||
|
Context m_currentAdditionalContext;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
@@ -192,6 +194,11 @@ QWidget *EngineManager::engineChooser()
|
|||||||
return d->m_engineChooser;
|
return d->m_engineChooser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EngineManager::updatePerspectives()
|
||||||
|
{
|
||||||
|
d->updatePerspectives();
|
||||||
|
}
|
||||||
|
|
||||||
EngineManager::~EngineManager()
|
EngineManager::~EngineManager()
|
||||||
{
|
{
|
||||||
theEngineManager = nullptr;
|
theEngineManager = nullptr;
|
||||||
@@ -208,11 +215,6 @@ QAbstractItemModel *EngineManager::model()
|
|||||||
return &d->m_engineModel;
|
return &d->m_engineModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EngineManager::activateEngine(DebuggerEngine *engine)
|
|
||||||
{
|
|
||||||
d->activateEngine(engine);
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant EngineItem::data(int column, int role) const
|
QVariant EngineItem::data(int column, int role) const
|
||||||
{
|
{
|
||||||
if (m_engine) {
|
if (m_engine) {
|
||||||
@@ -273,7 +275,7 @@ bool EngineItem::setData(int row, const QVariant &value, int role)
|
|||||||
|
|
||||||
if (role == BaseTreeView::ItemActivatedRole) {
|
if (role == BaseTreeView::ItemActivatedRole) {
|
||||||
EngineItem *engineItem = d->findEngineItem(m_engine);
|
EngineItem *engineItem = d->findEngineItem(m_engine);
|
||||||
d->activateEngineItem(engineItem);
|
d->activateEngineByIndex(engineItem->indexInParent());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,21 +318,27 @@ bool EngineItem::setData(int row, const QVariant &value, int role)
|
|||||||
|
|
||||||
void EngineManagerPrivate::activateEngineByIndex(int index)
|
void EngineManagerPrivate::activateEngineByIndex(int index)
|
||||||
{
|
{
|
||||||
activateEngineItem(m_engineModel.rootItem()->childAt(index));
|
// The actual activation is triggered indirectly via the perspective change.
|
||||||
|
Perspective *perspective = nullptr;
|
||||||
|
if (index == 0) {
|
||||||
|
perspective = Perspective::findPerspective(Debugger::Constants::PRESET_PERSPECTIVE_ID);
|
||||||
|
} else {
|
||||||
|
EngineItem *engineItem = m_engineModel.rootItem()->childAt(index);
|
||||||
|
QTC_ASSERT(engineItem, return);
|
||||||
|
QTC_ASSERT(engineItem->m_engine, return);
|
||||||
|
perspective = engineItem->m_engine->perspective();
|
||||||
|
}
|
||||||
|
|
||||||
|
QTC_ASSERT(perspective, return);
|
||||||
|
perspective->select();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EngineManagerPrivate::activateEngineItem(EngineItem *engineItem)
|
void EngineManagerPrivate::activateEngineItem(EngineItem *engineItem)
|
||||||
{
|
{
|
||||||
Context previousContext;
|
if (m_currentItem == engineItem)
|
||||||
if (m_currentItem) {
|
return;
|
||||||
if (DebuggerEngine *engine = m_currentItem->m_engine) {
|
|
||||||
previousContext.add(engine->languageContext());
|
|
||||||
previousContext.add(engine->debuggerContext());
|
|
||||||
} else {
|
|
||||||
previousContext.add(Context(Constants::C_DEBUGGER_NOTRUNNING));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
QTC_ASSERT(engineItem, return);
|
||||||
m_currentItem = engineItem;
|
m_currentItem = engineItem;
|
||||||
|
|
||||||
Context newContext;
|
Context newContext;
|
||||||
@@ -343,7 +351,13 @@ void EngineManagerPrivate::activateEngineItem(EngineItem *engineItem)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ICore::updateAdditionalContexts(previousContext, newContext);
|
ICore::updateAdditionalContexts(m_currentAdditionalContext, newContext);
|
||||||
|
m_currentAdditionalContext = newContext;
|
||||||
|
|
||||||
|
// In case this was triggered externally by some Perspective::select() call.
|
||||||
|
const int idx = engineItem->indexInParent();
|
||||||
|
m_engineChooser->setCurrentIndex(idx);
|
||||||
|
|
||||||
selectUiForCurrentEngine();
|
selectUiForCurrentEngine();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,12 +366,7 @@ void EngineManagerPrivate::selectUiForCurrentEngine()
|
|||||||
if (ModeManager::currentModeId() != Constants::MODE_DEBUG)
|
if (ModeManager::currentModeId() != Constants::MODE_DEBUG)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Perspective *perspective = nullptr;
|
|
||||||
int row = 0;
|
int row = 0;
|
||||||
|
|
||||||
if (m_currentItem && m_currentItem->m_engine)
|
|
||||||
perspective = m_currentItem->m_engine->perspective();
|
|
||||||
|
|
||||||
if (m_currentItem)
|
if (m_currentItem)
|
||||||
row = m_engineModel.rootItem()->indexOf(m_currentItem);
|
row = m_engineModel.rootItem()->indexOf(m_currentItem);
|
||||||
|
|
||||||
@@ -370,12 +379,6 @@ void EngineManagerPrivate::selectUiForCurrentEngine()
|
|||||||
QStyle::CT_ComboBox, &option, sz).width();
|
QStyle::CT_ComboBox, &option, sz).width();
|
||||||
m_engineChooser->setFixedWidth(width);
|
m_engineChooser->setFixedWidth(width);
|
||||||
|
|
||||||
if (!perspective)
|
|
||||||
perspective = Perspective::findPerspective(Debugger::Constants::PRESET_PERSPECTIVE_ID);
|
|
||||||
|
|
||||||
QTC_ASSERT(perspective, return);
|
|
||||||
perspective->select();
|
|
||||||
|
|
||||||
m_engineModel.rootItem()->forFirstLevelChildren([this](EngineItem *engineItem) {
|
m_engineModel.rootItem()->forFirstLevelChildren([this](EngineItem *engineItem) {
|
||||||
if (engineItem && engineItem->m_engine)
|
if (engineItem && engineItem->m_engine)
|
||||||
engineItem->m_engine->updateUi(engineItem == m_currentItem);
|
engineItem->m_engine->updateUi(engineItem == m_currentItem);
|
||||||
@@ -391,12 +394,6 @@ EngineItem *EngineManagerPrivate::findEngineItem(DebuggerEngine *engine)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void EngineManagerPrivate::activateEngine(DebuggerEngine *engine)
|
|
||||||
{
|
|
||||||
EngineItem *engineItem = findEngineItem(engine);
|
|
||||||
activateEngineItem(engineItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EngineManagerPrivate::updateEngineChooserVisibility()
|
void EngineManagerPrivate::updateEngineChooserVisibility()
|
||||||
{
|
{
|
||||||
// Show it if there's more than one option (i.e. not the preset engine only)
|
// Show it if there's more than one option (i.e. not the preset engine only)
|
||||||
@@ -406,12 +403,48 @@ void EngineManagerPrivate::updateEngineChooserVisibility()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EngineManager::registerEngine(DebuggerEngine *engine)
|
void EngineManagerPrivate::updatePerspectives()
|
||||||
|
{
|
||||||
|
d->updateEngineChooserVisibility();
|
||||||
|
|
||||||
|
Perspective *current = DebuggerMainWindow::currentPerspective();
|
||||||
|
if (!current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_engineModel.rootItem()->forFirstLevelChildren([this, current](EngineItem *engineItem) {
|
||||||
|
if (engineItem == m_currentItem)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool shouldBeActive = false;
|
||||||
|
if (engineItem->m_engine) {
|
||||||
|
// Normal engine.
|
||||||
|
shouldBeActive = engineItem->m_engine->perspective()->isCurrent();
|
||||||
|
} else {
|
||||||
|
// Preset.
|
||||||
|
shouldBeActive = current->id() == Debugger::Constants::PRESET_PERSPECTIVE_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldBeActive && engineItem != m_currentItem)
|
||||||
|
activateEngineItem(engineItem);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QString EngineManager::registerEngine(DebuggerEngine *engine)
|
||||||
{
|
{
|
||||||
auto engineItem = new EngineItem;
|
auto engineItem = new EngineItem;
|
||||||
engineItem->m_engine = engine;
|
engineItem->m_engine = engine;
|
||||||
d->m_engineModel.rootItem()->appendChild(engineItem);
|
d->m_engineModel.rootItem()->appendChild(engineItem);
|
||||||
d->updateEngineChooserVisibility();
|
d->updateEngineChooserVisibility();
|
||||||
|
return QString::number(d->m_engineModel.rootItem()->childCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
void EngineManager::unregisterEngine(DebuggerEngine *engine)
|
||||||
|
{
|
||||||
|
EngineItem *engineItem = d->findEngineItem(engine);
|
||||||
|
QTC_ASSERT(engineItem, return);
|
||||||
|
d->m_engineModel.destroyItem(engineItem);
|
||||||
|
d->updateEngineChooserVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EngineManager::activateDebugMode()
|
void EngineManager::activateDebugMode()
|
||||||
@@ -434,33 +467,6 @@ void EngineManager::deactivateDebugMode()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
d->updateEngineChooserVisibility();
|
|
||||||
emit theEngineManager->currentEngineChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<QPointer<DebuggerEngine>> EngineManager::engines()
|
QList<QPointer<DebuggerEngine>> EngineManager::engines()
|
||||||
{
|
{
|
||||||
QList<QPointer<DebuggerEngine>> result;
|
QList<QPointer<DebuggerEngine>> result;
|
||||||
@@ -476,5 +482,18 @@ QPointer<DebuggerEngine> EngineManager::currentEngine()
|
|||||||
return d->m_currentItem ? d->m_currentItem->m_engine : nullptr;
|
return d->m_currentItem ? d->m_currentItem->m_engine : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EngineManager::shutDown()
|
||||||
|
{
|
||||||
|
d->m_shuttingDown = true;
|
||||||
|
bool anyEngineAborting = false;
|
||||||
|
for (DebuggerEngine *engine : EngineManager::engines()) {
|
||||||
|
if (engine && engine->state() != Debugger::DebuggerNotReady) {
|
||||||
|
engine->abortDebugger();
|
||||||
|
anyEngineAborting = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return anyEngineAborting;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
@@ -45,17 +45,19 @@ public:
|
|||||||
static EngineManager *instance();
|
static EngineManager *instance();
|
||||||
static QAbstractItemModel *model();
|
static QAbstractItemModel *model();
|
||||||
|
|
||||||
static void registerEngine(DebuggerEngine *engine);
|
static QString registerEngine(DebuggerEngine *engine);
|
||||||
static void unregisterEngine(DebuggerEngine *engine);
|
static void unregisterEngine(DebuggerEngine *engine);
|
||||||
static void activateEngine(DebuggerEngine *engine);
|
|
||||||
static void activateDebugMode();
|
static void activateDebugMode();
|
||||||
static void deactivateDebugMode();
|
static void deactivateDebugMode();
|
||||||
static bool isLastOf(const QString &type);
|
|
||||||
|
|
||||||
static QList<QPointer<DebuggerEngine> > engines();
|
static QList<QPointer<DebuggerEngine> > engines();
|
||||||
static QPointer<DebuggerEngine> currentEngine();
|
static QPointer<DebuggerEngine> currentEngine();
|
||||||
|
|
||||||
static QWidget *engineChooser();
|
static QWidget *engineChooser();
|
||||||
|
static void updatePerspectives();
|
||||||
|
|
||||||
|
static bool shutDown(); // Return true if some engine is being forced to shut down.
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void engineStateChanged(DebuggerEngine *engine);
|
void engineStateChanged(DebuggerEngine *engine);
|
||||||
|
@@ -2953,7 +2953,7 @@ void GdbEngine::handleThreadInfo(const DebuggerResponse &response)
|
|||||||
if (response.resultClass == ResultDone) {
|
if (response.resultClass == ResultDone) {
|
||||||
ThreadsHandler *handler = threadsHandler();
|
ThreadsHandler *handler = threadsHandler();
|
||||||
handler->setThreads(response.data);
|
handler->setThreads(response.data);
|
||||||
updateState(false); // Adjust Threads combobox.
|
updateState(); // Adjust Threads combobox.
|
||||||
if (boolSetting(ShowThreadNames)) {
|
if (boolSetting(ShowThreadNames)) {
|
||||||
runCommand({"threadnames " + action(MaximalStackDepth)->value().toString(),
|
runCommand({"threadnames " + action(MaximalStackDepth)->value().toString(),
|
||||||
Discardable, CB(handleThreadNames)});
|
Discardable, CB(handleThreadNames)});
|
||||||
@@ -2993,7 +2993,7 @@ void GdbEngine::handleThreadNames(const DebuggerResponse &response)
|
|||||||
thread.name = decodeData(name["value"].data(), name["valueencoded"].data());
|
thread.name = decodeData(name["value"].data(), name["valueencoded"].data());
|
||||||
handler->updateThread(thread);
|
handler->updateThread(thread);
|
||||||
}
|
}
|
||||||
updateState(false);
|
updateState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user