DebuggerSettings *m_debuggerSettings;
QSettings *m_coreSettings;
bool m_gdbBinariesChanged;
+ uint m_cmdLineEnabledEngines;
};
DebuggerPluginPrivate::DebuggerPluginPrivate(DebuggerPlugin *plugin)
m_logWindow = 0;
m_scriptConsoleWindow = 0;
- m_debugMode = 0;
-
m_continuableContext = Context(0);
m_interruptibleContext = Context(0);
m_undisturbableContext = Context(0);
m_debuggerSettings = 0;
m_gdbBinariesChanged = true;
+ m_cmdLineEnabledEngines = AllEngineTypes;
}
DebuggerPluginPrivate::~DebuggerPluginPrivate()
bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
QString *errorMessage)
{
- m_coreSettings = ICore::instance()->settings();
- m_debuggerSettings = new DebuggerSettings(m_coreSettings);
-
- m_continuableContext = Context("Gdb.Continuable");
- m_interruptibleContext = Context("Gdb.Interruptible");
- m_undisturbableContext = Context("Gdb.Undisturbable");
- m_finishedContext = Context("Gdb.Finished");
- m_anyContext.add(m_continuableContext);
- m_anyContext.add(m_interruptibleContext);
- m_anyContext.add(m_undisturbableContext);
- m_anyContext.add(m_finishedContext);
-
- // FIXME: Move part of this to extensionsInitialized()?
- ICore *core = ICore::instance();
- QTC_ASSERT(core, return false);
- connect(core, SIGNAL(coreAboutToClose()), this, SLOT(coreShutdown()));
+ // Do not fail to load the whole plugin if something goes wrong here.
+ if (!parseArguments(arguments, &m_attachRemoteParameters,
+ &m_cmdLineEnabledEngines, errorMessage)) {
+ *errorMessage = tr("Error evaluating command line arguments: %1")
+ .arg(*errorMessage);
+ qWarning("%s\n", qPrintable(*errorMessage));
+ errorMessage->clear();
+ }
- Core::ActionManager *am = core->actionManager();
- QTC_ASSERT(am, return false);
+ return true;
+}
- const Context globalcontext(CC::C_GLOBAL);
- const Context cppDebuggercontext(C_CPPDEBUGGER);
- const Context qmlDebuggerContext(C_QMLDEBUGGER);
- const Context cppeditorcontext(CppEditor::Constants::C_CPPEDITOR);
+void DebuggerPluginPrivate::setConfigValue(const QString &name, const QVariant &value)
+{
+ m_coreSettings->setValue(_("DebugMode/") + name, value);
+}
- m_startIcon = QIcon(_(":/debugger/images/debugger_start_small.png"));
- m_startIcon.addFile(__(":/debugger/images/debugger_start.png"));
- m_exitIcon = QIcon(_(":/debugger/images/debugger_stop_small.png"));
- m_exitIcon.addFile(__(":/debugger/images/debugger_stop.png"));
- m_continueIcon = QIcon(__(":/debugger/images/debugger_continue_small.png"));
- m_continueIcon.addFile(__(":/debugger/images/debugger_continue.png"));
- m_interruptIcon = QIcon(_(":/debugger/images/debugger_interrupt_small.png"));
- m_interruptIcon.addFile(__(":/debugger/images/debugger_interrupt.png"));
- m_locationMarkIcon = QIcon(_(":/debugger/images/location_16.png"));
+QVariant DebuggerPluginPrivate::configValue(const QString &name) const
+{
+ const QVariant value = m_coreSettings->value(_("DebugMode/") + name);
+ if (value.isValid())
+ return value;
+ // Legacy (pre-2.1): Check old un-namespaced-settings.
+ return m_coreSettings->value(name);
+}
- m_busy = false;
+void DebuggerPluginPrivate::onCurrentProjectChanged(Project *project)
+{
+ RunConfiguration *activeRc = 0;
+ if (project) {
+ Target *target = project->activeTarget();
+ QTC_ASSERT(target, return);
+ activeRc = target->activeRunConfiguration();
+ QTC_ASSERT(activeRc, /**/);
+ }
+ for (int i = 0, n = m_snapshotHandler->size(); i != n; ++i) {
+ // Run controls might be deleted during exit.
+ if (DebuggerRunControl *runControl = m_snapshotHandler->at(i)) {
+ RunConfiguration *rc = runControl->runConfiguration();
+ if (rc == activeRc) {
+ m_snapshotHandler->setCurrentIndex(i);
+ DebuggerEngine *engine = runControl->engine();
+ updateState(engine);
+ return;
+ }
+ }
+ }
+ // No corresponding debugger found. So we are ready to start one.
+ ICore *core = ICore::instance();
+ core->updateAdditionalContexts(m_anyContext, Context());
+}
- m_statusLabel = new QLabel;
- m_statusLabel->setMinimumSize(QSize(30, 10));
+void DebuggerPluginPrivate::languagesChanged(const DebuggerLanguages &languages)
+{
+ const bool debuggerIsCPP = (languages & CppLanguage);
+ //qDebug() << "DEBUGGER IS CPP: " << debuggerIsCPP;
- m_breakHandler = new BreakHandler;
- m_breakWindow = new BreakWindow;
- m_breakWindow->setObjectName(QLatin1String("CppDebugBreakpoints"));
- m_breakWindow->setModel(m_breakHandler->model());
+ m_startExternalAction->setVisible(debuggerIsCPP);
+ m_attachExternalAction->setVisible(debuggerIsCPP);
+ m_attachCoreAction->setVisible(debuggerIsCPP);
+ m_startRemoteAction->setVisible(debuggerIsCPP);
+ m_detachAction->setVisible(debuggerIsCPP);
+}
- //m_consoleWindow = new ConsoleWindow;
- //m_consoleWindow->setObjectName(QLatin1String("CppDebugConsole"));
- m_modulesWindow = new ModulesWindow;
- m_modulesWindow->setObjectName(QLatin1String("CppDebugModules"));
- m_logWindow = new LogWindow;
- m_logWindow->setObjectName(QLatin1String("CppDebugOutput"));
+void DebuggerPluginPrivate::debugProject()
+{
+ ProjectExplorerPlugin *pe = ProjectExplorerPlugin::instance();
+ if (Project *pro = pe->startupProject())
+ pe->runProject(pro, Constants::DEBUGMODE);
+}
- m_registerWindow = new RegisterWindow;
- m_registerWindow->setObjectName(QLatin1String("CppDebugRegisters"));
- m_stackWindow = new StackWindow;
- m_stackWindow->setObjectName(QLatin1String("CppDebugStack"));
- m_sourceFilesWindow = new SourceFilesWindow;
- m_sourceFilesWindow->setObjectName(QLatin1String("CppDebugSources"));
- m_threadsWindow = new ThreadsWindow;
- m_threadsWindow->setObjectName(QLatin1String("CppDebugThreads"));
- m_returnWindow = new WatchWindow(WatchWindow::ReturnType);
- m_returnWindow->setObjectName(QLatin1String("CppDebugReturn"));
- m_localsWindow = new WatchWindow(WatchWindow::LocalsType);
- m_localsWindow->setObjectName(QLatin1String("CppDebugLocals"));
- m_watchersWindow = new WatchWindow(WatchWindow::WatchersType);
- m_watchersWindow->setObjectName(QLatin1String("CppDebugWatchers"));
- m_scriptConsoleWindow = new ScriptConsole;
- m_scriptConsoleWindow->setWindowTitle(tr("QML Script Console"));
- m_scriptConsoleWindow->setObjectName(QLatin1String("QMLScriptConsole"));
- connect(m_scriptConsoleWindow, SIGNAL(expressionEntered(QString)),
- SLOT(scriptExpressionEntered(QString)));
+void DebuggerPluginPrivate::startExternalApplication()
+{
+ DebuggerStartParameters sp;
+ StartExternalDialog dlg(mainWindow());
+ dlg.setExecutableFile(
+ configValue(_("LastExternalExecutableFile")).toString());
+ dlg.setExecutableArguments(
+ configValue(_("LastExternalExecutableArguments")).toString());
+ dlg.setWorkingDirectory(
+ configValue(_("LastExternalWorkingDirectory")).toString());
+ if (dlg.exec() != QDialog::Accepted)
+ return;
- // Snapshot
- m_snapshotHandler = new SnapshotHandler;
- m_snapshotWindow = new SnapshotWindow(m_snapshotHandler);
- m_snapshotWindow->setObjectName(QLatin1String("CppDebugSnapshots"));
- m_snapshotWindow->setModel(m_snapshotHandler->model());
+ setConfigValue(_("LastExternalExecutableFile"),
+ dlg.executableFile());
+ setConfigValue(_("LastExternalExecutableArguments"),
+ dlg.executableArguments());
+ setConfigValue(_("LastExternalWorkingDirectory"),
+ dlg.workingDirectory());
+ sp.executable = dlg.executableFile();
+ sp.startMode = StartExternal;
+ sp.workingDirectory = dlg.workingDirectory();
+ sp.breakAtMain = dlg.breakAtMain();
+ if (!dlg.executableArguments().isEmpty())
+ sp.processArgs = dlg.executableArguments();
+ // Fixme: 1 of 3 testing hacks.
+ if (sp.processArgs.startsWith(__("@tcf@ ")) || sp.processArgs.startsWith(__("@sym@ ")))
+ sp.toolChainType = ToolChain_RVCT2_ARMV5;
- // Debug mode setup
- m_debugMode = new DebugMode(this);
- // Watchers
- connect(m_localsWindow->header(), SIGNAL(sectionResized(int,int,int)),
- SLOT(updateWatchersHeader(int,int,int)), Qt::QueuedConnection);
+ if (RunControl *rc = m_debuggerRunControlFactory->create(sp))
+ startDebugger(rc);
+}
- QAction *act = 0;
+void DebuggerPluginPrivate::attachExternalApplication()
+{
+ AttachExternalDialog dlg(mainWindow());
+ if (dlg.exec() == QDialog::Accepted)
+ attachExternalApplication(dlg.attachPID(), dlg.executable(), QString());
+}
- act = m_actions.continueAction = new QAction(tr("Continue"), this);
- act->setIcon(m_continueIcon);
- connect(act, SIGNAL(triggered()), SLOT(handleExecContinue()));
+void DebuggerPluginPrivate::attachExternalApplication
+ (qint64 pid, const QString &binary, const QString &crashParameter)
+{
+ if (pid == 0) {
+ QMessageBox::warning(mainWindow(), tr("Warning"),
+ tr("Cannot attach to PID 0"));
+ return;
+ }
+ DebuggerStartParameters sp;
+ sp.attachPID = pid;
+ sp.displayName = tr("Process %1").arg(pid);
+ sp.executable = binary;
+ sp.crashParameter = crashParameter;
+ sp.startMode = crashParameter.isEmpty() ? AttachExternal : AttachCrashedExternal;
+ if (DebuggerRunControl *rc = createDebugger(sp))
+ startDebugger(rc);
+}
- act = m_actions.exitAction = new QAction(tr("Exit Debugger"), this);
- act->setIcon(m_exitIcon);
- connect(act, SIGNAL(triggered()), SLOT(handleExecExit()));
+void DebuggerPluginPrivate::attachCore()
+{
+ AttachCoreDialog dlg(mainWindow());
+ dlg.setExecutableFile(configValue(_("LastExternalExecutableFile")).toString());
+ dlg.setCoreFile(configValue(_("LastExternalCoreFile")).toString());
+ if (dlg.exec() != QDialog::Accepted)
+ return;
+ setConfigValue(_("LastExternalExecutableFile"), dlg.executableFile());
+ setConfigValue(_("LastExternalCoreFile"), dlg.coreFile());
+ attachCore(dlg.coreFile(), dlg.executableFile());
+}
- act = m_actions.interruptAction = new QAction(tr("Interrupt"), this);
- act->setIcon(m_interruptIcon);
- connect(act, SIGNAL(triggered()), SLOT(handleExecInterrupt()));
+void DebuggerPluginPrivate::attachCore(const QString &core, const QString &exe)
+{
+ DebuggerStartParameters sp;
+ sp.executable = exe;
+ sp.coreFile = core;
+ sp.displayName = tr("Core file \"%1\"").arg(core);
+ sp.startMode = AttachCore;
+ if (DebuggerRunControl *rc = createDebugger(sp))
+ startDebugger(rc);
+}
- // A "disabled pause" seems to be a good choice.
- act = m_actions.undisturbableAction = new QAction(tr("Debugger is Busy"), this);
- act->setIcon(m_interruptIcon);
- act->setEnabled(false);
+void DebuggerPluginPrivate::attachRemote(const QString &spec)
+{
+ // spec is: executable@server:port@architecture
+ DebuggerStartParameters sp;
+ sp.executable = spec.section('@', 0, 0);
+ sp.remoteChannel = spec.section('@', 1, 1);
+ sp.remoteArchitecture = spec.section('@', 2, 2);
+ sp.displayName = tr("Remote: \"%1\"").arg(sp.remoteChannel);
+ sp.startMode = AttachToRemote;
+ if (DebuggerRunControl *rc = createDebugger(sp))
+ startDebugger(rc);
+}
- act = m_actions.resetAction = new QAction(tr("Abort Debugging"), this);
- act->setToolTip(tr("Aborts debugging and "
- "resets the debugger to the initial state."));
- connect(act, SIGNAL(triggered()), SLOT(handleExecReset()));
+void DebuggerPluginPrivate::startRemoteCdbSession()
+{
+ const QString connectionKey = _("CdbRemoteConnection");
+ DebuggerStartParameters sp;
+ sp.toolChainType = ToolChain_MSVC;
+ sp.startMode = AttachToRemote;
+ StartRemoteCdbDialog dlg(mainWindow());
+ QString previousConnection = configValue(connectionKey).toString();
+ if (previousConnection.isEmpty())
+ previousConnection = QLatin1String("localhost:1234");
+ dlg.setConnection(previousConnection);
+ if (dlg.exec() != QDialog::Accepted)
+ return;
+ sp.remoteChannel = dlg.connection();
+ setConfigValue(connectionKey, sp.remoteChannel);
+ if (RunControl *rc = createDebugger(sp))
+ startDebugger(rc);
+}
- act = m_actions.nextAction = new QAction(tr("Step Over"), this);
- act->setIcon(QIcon(__(":/debugger/images/debugger_stepover_small.png")));
- connect(act, SIGNAL(triggered()), SLOT(handleExecNext()));
-
- act = m_actions.stepAction = new QAction(tr("Step Into"), this);
- act->setIcon(QIcon(__(":/debugger/images/debugger_stepinto_small.png")));
- connect(act, SIGNAL(triggered()), SLOT(handleExecStep()));
-
- act = m_actions.stepOutAction = new QAction(tr("Step Out"), this);
- act->setIcon(QIcon(__(":/debugger/images/debugger_stepout_small.png")));
- connect(act, SIGNAL(triggered()), SLOT(handleExecStepOut()));
-
- act = m_actions.runToLineAction = new QAction(tr("Run to Line"), this);
- connect(act, SIGNAL(triggered()), SLOT(handleExecRunToLine()));
-
- act = m_actions.runToFunctionAction =
- new QAction(tr("Run to Outermost Function"), this);
- connect(act, SIGNAL(triggered()), SLOT(handleExecRunToFunction()));
-
- act = m_actions.returnFromFunctionAction =
- new QAction(tr("Immediately Return From Inner Function"), this);
- connect(act, SIGNAL(triggered()), SLOT(handleExecReturn()));
-
- act = m_actions.jumpToLineAction = new QAction(tr("Jump to Line"), this);
- connect(act, SIGNAL(triggered()), SLOT(handleExecJumpToLine()));
-
- act = m_actions.breakAction = new QAction(tr("Toggle Breakpoint"), this);
-
- act = m_actions.watchAction1 = new QAction(tr("Add to Watch Window"), this);
- connect(act, SIGNAL(triggered()), SLOT(handleAddToWatchWindow()));
-
- act = m_actions.watchAction2 = new QAction(tr("Add to Watch Window"), this);
- connect(act, SIGNAL(triggered()), SLOT(handleAddToWatchWindow()));
-
- //m_actions.snapshotAction = new QAction(tr("Create Snapshot"), this);
- //m_actions.snapshotAction->setProperty(Role, RequestCreateSnapshotRole);
- //m_actions.snapshotAction->setIcon(
- // QIcon(__(":/debugger/images/debugger_snapshot_small.png")));
-
- act = m_actions.reverseDirectionAction =
- new QAction(tr("Reverse Direction"), this);
- act->setCheckable(true);
- act->setChecked(false);
- act->setCheckable(false);
- act->setIcon(QIcon(__(":/debugger/images/debugger_reversemode_16.png")));
- act->setIconVisibleInMenu(false);
-
- act = m_actions.frameDownAction = new QAction(tr("Move to Called Frame"), this);
- connect(act, SIGNAL(triggered()), SLOT(handleFrameDown()));
-
- act = m_actions.frameUpAction = new QAction(tr("Move to Calling Frame"), this);
- connect(act, SIGNAL(triggered()), SLOT(handleFrameUp()));
-
- connect(action(OperateByInstruction), SIGNAL(triggered(bool)),
- SLOT(handleOperateByInstructionTriggered(bool)));
-
- connect(&m_statusTimer, SIGNAL(timeout()), SLOT(clearStatusMessage()));
+void DebuggerPluginPrivate::startRemoteApplication()
+{
+ DebuggerStartParameters sp;
+ StartRemoteDialog dlg(mainWindow());
+ QStringList arches;
+ arches.append(_("i386:x86-64:intel"));
+ arches.append(_("i386"));
+ arches.append(_("arm"));
+ QString lastUsed = configValue(_("LastRemoteArchitecture")).toString();
+ if (!arches.contains(lastUsed))
+ arches.prepend(lastUsed);
+ dlg.setRemoteArchitectures(arches);
+ QStringList gnuTargets;
+ gnuTargets.append(_("auto"));
+ gnuTargets.append(_("i686-linux-gnu"));
+ gnuTargets.append(_("x86_64-linux-gnu"));
+ gnuTargets.append(_("arm-none-linux-gnueabi"));
+ const QString lastUsedGnuTarget
+ = configValue(_("LastGnuTarget")).toString();
+ if (!gnuTargets.contains(lastUsedGnuTarget))
+ gnuTargets.prepend(lastUsedGnuTarget);
+ dlg.setGnuTargets(gnuTargets);
+ dlg.setRemoteChannel(
+ configValue(_("LastRemoteChannel")).toString());
+ dlg.setLocalExecutable(
+ configValue(_("LastLocalExecutable")).toString());
+ dlg.setDebugger(configValue(_("LastDebugger")).toString());
+ dlg.setRemoteArchitecture(lastUsed);
+ dlg.setGnuTarget(lastUsedGnuTarget);
+ dlg.setServerStartScript(
+ configValue(_("LastServerStartScript")).toString());
+ dlg.setUseServerStartScript(
+ configValue(_("LastUseServerStartScript")).toBool());
+ dlg.setSysRoot(configValue(_("LastSysroot")).toString());
+ if (dlg.exec() != QDialog::Accepted)
+ return;
+ setConfigValue(_("LastRemoteChannel"), dlg.remoteChannel());
+ setConfigValue(_("LastLocalExecutable"), dlg.localExecutable());
+ setConfigValue(_("LastDebugger"), dlg.debugger());
+ setConfigValue(_("LastRemoteArchitecture"), dlg.remoteArchitecture());
+ setConfigValue(_("LastGnuTarget"), dlg.gnuTarget());
+ setConfigValue(_("LastServerStartScript"), dlg.serverStartScript());
+ setConfigValue(_("LastUseServerStartScript"), dlg.useServerStartScript());
+ setConfigValue(_("LastSysroot"), dlg.sysRoot());
+ sp.remoteChannel = dlg.remoteChannel();
+ sp.remoteArchitecture = dlg.remoteArchitecture();
+ sp.gnuTarget = dlg.gnuTarget();
+ sp.executable = dlg.localExecutable();
+ sp.displayName = dlg.localExecutable();
+ sp.debuggerCommand = dlg.debugger(); // Override toolchain-detection.
+ if (!sp.debuggerCommand.isEmpty())
+ sp.toolChainType = ToolChain_INVALID;
+ sp.startMode = AttachToRemote;
+ sp.useServerStartScript = dlg.useServerStartScript();
+ sp.serverStartScript = dlg.serverStartScript();
+ sp.sysRoot = dlg.sysRoot();
+ if (RunControl *rc = createDebugger(sp))
+ startDebugger(rc);
+}
- connect(action(ExecuteCommand), SIGNAL(triggered()),
- SLOT(executeDebuggerCommand()));
+void DebuggerPluginPrivate::startRemoteEngine()
+{
+ DebuggerStartParameters sp;
+ StartRemoteEngineDialog dlg(mainWindow());
+ if (dlg.exec() != QDialog::Accepted)
+ return;
- // Cpp/Qml ui setup
- m_uiSwitcher = new DebuggerUISwitcher(m_debugMode, this);
- ExtensionSystem::PluginManager::instance()->addObject(m_uiSwitcher);
- m_uiSwitcher->addLanguage(CppLanguage, cppDebuggercontext);
- m_uiSwitcher->addLanguage(QmlLanguage, qmlDebuggerContext);
- m_uiSwitcher->initialize(m_coreSettings);
+ sp.connParams.host = dlg.host();
+ sp.connParams.uname = dlg.username();
+ sp.connParams.pwd = dlg.password();
- readSettings();
+ sp.connParams.timeout = 5;
+ sp.connParams.authType = SshConnectionParameters::AuthByPwd;
+ sp.connParams.port = 22;
+ sp.connParams.proxyType = SshConnectionParameters::NoProxy;
- // Dock widgets
- m_breakDock = m_uiSwitcher->createDockWidget(CppLanguage, m_breakWindow);
- m_breakDock->setObjectName(QString(DOCKWIDGET_BREAK));
+ sp.executable = dlg.inferiorPath();
+ sp.serverStartScript = dlg.enginePath();
+ sp.startMode = StartRemoteEngine;
+ if (RunControl *rc = createDebugger(sp))
+ startDebugger(rc);
+}
- //m_consoleDock = m_uiSwitcher->createDockWidget(CppLanguage, m_consoleWindow,
- // Qt::TopDockWidgetArea);
- //m_consoleDock->setObjectName(QString(DOCKWIDGET_OUTPUT));
+void DebuggerPluginPrivate::enableReverseDebuggingTriggered(const QVariant &value)
+{
+ QTC_ASSERT(m_reverseToolButton, return);
+ m_reverseToolButton->setVisible(value.toBool());
+ m_actions.reverseDirectionAction->setChecked(false);
+ m_actions.reverseDirectionAction->setEnabled(value.toBool());
+}
- m_modulesDock = m_uiSwitcher->createDockWidget(CppLanguage, m_modulesWindow,
- Qt::TopDockWidgetArea);
- m_modulesDock->setObjectName(QString(DOCKWIDGET_MODULES));
- connect(m_modulesDock->toggleViewAction(), SIGNAL(toggled(bool)),
- SLOT(modulesDockToggled(bool)), Qt::QueuedConnection);
+void DebuggerPluginPrivate::attachRemoteTcf()
+{
+ DebuggerStartParameters sp;
+ AttachTcfDialog dlg(mainWindow());
+ QStringList arches;
+ arches.append(_("i386:x86-64:intel"));
+ dlg.setRemoteArchitectures(arches);
+ dlg.setRemoteChannel(
+ configValue(_("LastTcfRemoteChannel")).toString());
+ dlg.setRemoteArchitecture(
+ configValue(_("LastTcfRemoteArchitecture")).toString());
+ dlg.setServerStartScript(
+ configValue(_("LastTcfServerStartScript")).toString());
+ dlg.setUseServerStartScript(
+ configValue(_("LastTcfUseServerStartScript")).toBool());
+ if (dlg.exec() != QDialog::Accepted)
+ return;
+ setConfigValue(_("LastTcfRemoteChannel"), dlg.remoteChannel());
+ setConfigValue(_("LastTcfRemoteArchitecture"), dlg.remoteArchitecture());
+ setConfigValue(_("LastTcfServerStartScript"), dlg.serverStartScript());
+ setConfigValue(_("LastTcfUseServerStartScript"), dlg.useServerStartScript());
+ sp.remoteChannel = dlg.remoteChannel();
+ sp.remoteArchitecture = dlg.remoteArchitecture();
+ sp.serverStartScript = dlg.serverStartScript();
+ sp.startMode = AttachTcf;
+ if (dlg.useServerStartScript())
+ sp.serverStartScript = dlg.serverStartScript();
+ if (RunControl *rc = createDebugger(sp))
+ startDebugger(rc);
+}
- m_registerDock = m_uiSwitcher->createDockWidget(CppLanguage, m_registerWindow,
- Qt::TopDockWidgetArea);
- m_registerDock->setObjectName(QString(DOCKWIDGET_REGISTER));
- connect(m_registerDock->toggleViewAction(), SIGNAL(toggled(bool)),
- SLOT(registerDockToggled(bool)), Qt::QueuedConnection);
+bool DebuggerPluginPrivate::attachCmdLine()
+{
+ if (m_attachRemoteParameters.attachPid) {
+ showStatusMessage(tr("Attaching to PID %1.")
+ .arg(m_attachRemoteParameters.attachPid));
+ const QString crashParameter = m_attachRemoteParameters.winCrashEvent
+ ? QString::number(m_attachRemoteParameters.winCrashEvent) : QString();
+ attachExternalApplication(m_attachRemoteParameters.attachPid,
+ QString(), crashParameter);
+ return true;
+ }
+ const QString target = m_attachRemoteParameters.attachTarget;
+ if (target.isEmpty())
+ return false;
+ if (target.indexOf(':') > 0) {
+ showStatusMessage(tr("Attaching to remote server %1.").arg(target));
+ attachRemote(target);
+ } else {
+ showStatusMessage(tr("Attaching to core %1.").arg(target));
+ attachCore(target, QString());
+ }
+ return true;
+}
- m_outputDock = m_uiSwitcher->createDockWidget(AnyLanguage, m_logWindow,
- Qt::TopDockWidgetArea);
- m_outputDock->setObjectName(QString(DOCKWIDGET_OUTPUT));
+void DebuggerPluginPrivate::editorOpened(Core::IEditor *editor)
+{
+ if (!isDebuggable(editor))
+ return;
+ ITextEditor *textEditor = qobject_cast<ITextEditor *>(editor);
+ if (!textEditor)
+ return;
+ connect(textEditor,
+ SIGNAL(markRequested(TextEditor::ITextEditor*,int)),
+ SLOT(requestMark(TextEditor::ITextEditor*,int)));
+ connect(editor,
+ SIGNAL(tooltipRequested(TextEditor::ITextEditor*,QPoint,int)),
+ SLOT(showToolTip(TextEditor::ITextEditor*,QPoint,int)));
+ connect(textEditor,
+ SIGNAL(markContextMenuRequested(TextEditor::ITextEditor*,int,QMenu*)),
+ SLOT(requestContextMenu(TextEditor::ITextEditor*,int,QMenu*)));
+}
- m_snapshotDock = m_uiSwitcher->createDockWidget(CppLanguage, m_snapshotWindow);
- m_snapshotDock->setObjectName(QString(DOCKWIDGET_SNAPSHOTS));
+void DebuggerPluginPrivate::editorAboutToClose(Core::IEditor *editor)
+{
+ if (!isDebuggable(editor))
+ return;
+ ITextEditor *textEditor = qobject_cast<ITextEditor *>(editor);
+ if (!textEditor)
+ return;
+ disconnect(textEditor,
+ SIGNAL(markRequested(TextEditor::ITextEditor*,int)),
+ this, SLOT(requestMark(TextEditor::ITextEditor*,int)));
+ disconnect(editor,
+ SIGNAL(tooltipRequested(TextEditor::ITextEditor*,QPoint,int)),
+ this, SLOT(showToolTip(TextEditor::ITextEditor*,QPoint,int)));
+ disconnect(textEditor,
+ SIGNAL(markContextMenuRequested(TextEditor::ITextEditor*,int,QMenu*)),
+ this, SLOT(requestContextMenu(TextEditor::ITextEditor*,int,QMenu*)));
+}
- m_stackDock = m_uiSwitcher->createDockWidget(CppLanguage, m_stackWindow);
- m_stackDock->setObjectName(QString(DOCKWIDGET_STACK));
+void DebuggerPluginPrivate::requestContextMenu(TextEditor::ITextEditor *editor,
+ int lineNumber, QMenu *menu)
+{
+ if (!isDebuggable(editor))
+ return;
- m_sourceFilesDock = m_uiSwitcher->createDockWidget(CppLanguage,
- m_sourceFilesWindow, Qt::TopDockWidgetArea);
- m_sourceFilesDock->setObjectName(QString(DOCKWIDGET_SOURCE_FILES));
- connect(m_sourceFilesDock->toggleViewAction(), SIGNAL(toggled(bool)),
- SLOT(sourceFilesDockToggled(bool)), Qt::QueuedConnection);
+ BreakpointId id = BreakpointId();
+ QString fileName;
+ quint64 address = 0;
- m_threadsDock = m_uiSwitcher->createDockWidget(CppLanguage, m_threadsWindow);
- m_threadsDock->setObjectName(QString(DOCKWIDGET_THREADS));
+ if (editor->property("DisassemblerView").toBool()) {
+ fileName = editor->file()->fileName();
+ QString line = editor->contents()
+ .section('\n', lineNumber - 1, lineNumber - 1);
+ BreakpointResponse needle;
+ needle.type = BreakpointByAddress;
+ needle.address = DisassemblerViewAgent::addressFromDisassemblyLine(line);
+ address = needle.address;
+ needle.lineNumber = -1;
+ id = breakHandler()->findSimilarBreakpoint(needle);
+ } else {
+ fileName = editor->file()->fileName();
+ id = breakHandler()->findBreakpointByFileAndLine(fileName, lineNumber);
+ }
- QSplitter *localsAndWatchers = new Core::MiniSplitter(Qt::Vertical);
- localsAndWatchers->setObjectName(QLatin1String("CppDebugLocalsAndWatchers"));
- localsAndWatchers->setWindowTitle(m_localsWindow->windowTitle());
- localsAndWatchers->addWidget(m_localsWindow);
- localsAndWatchers->addWidget(m_returnWindow);
- localsAndWatchers->addWidget(m_watchersWindow);
- localsAndWatchers->setStretchFactor(0, 3);
- localsAndWatchers->setStretchFactor(1, 1);
- localsAndWatchers->setStretchFactor(2, 1);
+ QList<QVariant> args;
+ args.append(fileName);
+ args.append(lineNumber);
+ args.append(address);
- m_watchDock = m_uiSwitcher->createDockWidget(CppLanguage, localsAndWatchers);
- m_watchDock->setObjectName(QString(DOCKWIDGET_WATCHERS));
+ if (id) {
+ // Remove existing breakpoint.
+ QAction *act = new QAction(menu);
+ act->setData(int(id));
+ act->setText(tr("Remove Breakpoint %1").arg(id));
+ connect(act, SIGNAL(triggered()),
+ SLOT(breakpointRemoveMarginActionTriggered()));
+ menu->addAction(act);
- m_scriptConsoleDock =
- m_uiSwitcher->createDockWidget(QmlLanguage, m_scriptConsoleWindow);
- m_scriptConsoleDock->setObjectName(QString(DOCKWIDGET_QML_SCRIPTCONSOLE));
+ // Enable/disable existing breakpoint.
+ act = new QAction(menu);
+ act->setData(int(id));
+ if (breakHandler()->isEnabled(id)) {
+ act->setText(tr("Disable Breakpoint %1").arg(id));
+ connect(act, SIGNAL(triggered()),
+ SLOT(breakpointDisableMarginActionTriggered()));
+ } else {
+ act->setText(tr("Enable Breakpoint %1").arg(id));
+ connect(act, SIGNAL(triggered()),
+ SLOT(breakpointEnableMarginActionTriggered()));
+ }
+ menu->addAction(act);
- // Do not fail to load the whole plugin if something goes wrong here.
- uint cmdLineEnabledEngines = AllEngineTypes;
- if (!parseArguments(arguments, &m_attachRemoteParameters,
- &cmdLineEnabledEngines, errorMessage)) {
- *errorMessage = tr("Error evaluating command line arguments: %1")
- .arg(*errorMessage);
- qWarning("%s\n", qPrintable(*errorMessage));
- errorMessage->clear();
+ // Edit existing breakpoint.
+ act = new QAction(menu);
+ act->setText(tr("Edit Breakpoint %1...").arg(id));
+ connect(act, SIGNAL(triggered()), SLOT(slotEditBreakpoint()));
+ act->setData(int(id));
+ menu->addAction(act);
+ } else {
+ // Handle non-existing breakpoint.
+ const QString text = address ?
+ tr("Set Breakpoint at 0x%1").arg(address, 0, 16) :
+ tr("Set Breakpoint at line %1").arg(lineNumber);
+ QAction *act = new QAction(text, menu);
+ act->setData(args);
+ connect(act, SIGNAL(triggered()),
+ SLOT(breakpointSetMarginActionTriggered()));
+ menu->addAction(act);
+ }
+ // Run to, jump to line below in stopped state.
+ if (state() == InferiorStopOk) {
+ menu->addSeparator();
+ const QString runText =
+ DebuggerEngine::tr("Run to Line %1").arg(lineNumber);
+ QAction *runToLineAction = new QAction(runText, menu);
+ runToLineAction->setData(args);
+ connect(runToLineAction, SIGNAL(triggered()), SLOT(slotRunToLine()));
+ menu->addAction(runToLineAction);
+ if (currentEngine()->debuggerCapabilities() & JumpToLineCapability) {
+ const QString jumpText =
+ DebuggerEngine::tr("Jump to Line %1").arg(lineNumber);
+ QAction *jumpToLineAction = new QAction(jumpText, menu);
+ menu->addAction(runToLineAction);
+ jumpToLineAction->setData(args);
+ connect(jumpToLineAction, SIGNAL(triggered()), SLOT(slotJumpToLine()));
+ menu->addAction(jumpToLineAction);
+ }
}
+}
- // Register factory of DebuggerRunControl.
- m_debuggerRunControlFactory = new DebuggerRunControlFactory
- (m_plugin, DebuggerEngineType(cmdLineEnabledEngines));
- m_plugin->addAutoReleasedObject(m_debuggerRunControlFactory);
+void DebuggerPluginPrivate::toggleBreakpoint()
+{
+ ITextEditor *textEditor = currentTextEditor();
+ QTC_ASSERT(textEditor, return);
+ const int lineNumber = textEditor->currentLine();
+ if (textEditor->property("DisassemblerView").toBool()) {
+ QString line = textEditor->contents()
+ .section('\n', lineNumber - 1, lineNumber - 1);
+ quint64 address = DisassemblerViewAgent::addressFromDisassemblyLine(line);
+ toggleBreakpointByAddress(address);
+ } else if (lineNumber >= 0) {
+ toggleBreakpointByFileAndLine(textEditor->file()->fileName(), lineNumber);
+ }
+}
- m_debugMode->setContext(
- Context(CC::C_EDITORMANAGER, C_DEBUGMODE, CC::C_NAVIGATION_PANE));
+void DebuggerPluginPrivate::toggleBreakpointByFileAndLine(const QString &fileName,
+ int lineNumber)
+{
+ BreakHandler *handler = m_breakHandler;
+ BreakpointId id =
+ handler->findBreakpointByFileAndLine(fileName, lineNumber, true);
+ if (!id)
+ id = handler->findBreakpointByFileAndLine(fileName, lineNumber, false);
- m_reverseToolButton = 0;
+ if (id) {
+ handler->removeBreakpoint(id);
+ } else {
+ BreakpointParameters data(BreakpointByFileAndLine);
+ data.fileName = fileName;
+ data.lineNumber = lineNumber;
+ handler->appendBreakpoint(data);
+ }
+ synchronizeBreakpoints();
+}
- // debug action
- act = m_debugAction = new QAction(this);
- QIcon debuggerIcon(":/projectexplorer/images/debugger_start_small.png");
- debuggerIcon.addFile(":/projectexplorer/images/debugger_start.png");
- act->setIcon(debuggerIcon);
- act->setText(tr("Start Debugging"));
- connect(act, SIGNAL(triggered()), this, SLOT(debugProject()));
+void DebuggerPluginPrivate::toggleBreakpointByAddress(quint64 address)
+{
+ BreakHandler *handler = m_breakHandler;
+ BreakpointId id = handler->findBreakpointByAddress(address);
- // Handling of external applications.
- act = m_startExternalAction = new QAction(this);
- act->setText(tr("Start and Debug External Application..."));
- connect(act, SIGNAL(triggered()), SLOT(startExternalApplication()));
+ if (id) {
+ handler->removeBreakpoint(id);
+ } else {
+ BreakpointParameters data(BreakpointByAddress);
+ data.address = address;
+ handler->appendBreakpoint(data);
+ }
+ synchronizeBreakpoints();
+}
- act = m_startRemoteLldbAction = new QAction(this);
- act->setText(tr("Start and Debug External Application with External Engine..."));
- connect(act, SIGNAL(triggered()), SLOT(startRemoteEngine()));
+void DebuggerPluginPrivate::requestMark(ITextEditor *editor, int lineNumber)
+{
+ if (editor->property("DisassemblerView").toBool()) {
+ QString line = editor->contents()
+ .section('\n', lineNumber - 1, lineNumber - 1);
+ quint64 address = DisassemblerViewAgent::addressFromDisassemblyLine(line);
+ toggleBreakpointByAddress(address);
+ } else if (editor->file()) {
+ toggleBreakpointByFileAndLine(editor->file()->fileName(), lineNumber);
+ }
+}
- act = m_attachExternalAction = new QAction(this);
- act->setText(tr("Attach to Running External Application..."));
- connect(act, SIGNAL(triggered()), SLOT(attachExternalApplication()));
+void DebuggerPluginPrivate::showToolTip(ITextEditor *editor,
+ const QPoint &point, int pos)
+{
+ if (!isDebuggable(editor))
+ return;
+ if (!boolSetting(UseToolTipsInMainEditor))
+ return;
+ if (state() != InferiorStopOk)
+ return;
+ currentEngine()->setToolTipExpression(point, editor, pos);
+}
- act = m_attachCoreAction = new QAction(this);
- act->setText(tr("Attach to Core..."));
- connect(act, SIGNAL(triggered()), SLOT(attachCore()));
+DebuggerRunControl *DebuggerPluginPrivate::createDebugger
+ (const DebuggerStartParameters &sp, RunConfiguration *rc)
+{
+ return m_debuggerRunControlFactory->create(sp, rc);
+}
- act = m_attachTcfAction = new QAction(this);
- act->setText(tr("Attach to Running Tcf Agent..."));
- act->setToolTip(tr("This attaches to a running "
- "'Target Communication Framework' agent."));
- connect(act, SIGNAL(triggered()), SLOT(attachRemoteTcf()));
+// If updateEngine is set, the engine will update its threads/modules and so forth.
+void DebuggerPluginPrivate::displayDebugger(DebuggerEngine *engine, bool updateEngine)
+{
+ QTC_ASSERT(engine, return);
+ disconnectEngine();
+ connectEngine(engine);
+ if (updateEngine)
+ engine->updateAll();
+ engine->updateViews();
+}
- act = m_startRemoteAction = new QAction(this);
- act->setText(tr("Start and Attach to Remote Application..."));
- connect(act, SIGNAL(triggered()), SLOT(startRemoteApplication()));
+void DebuggerPluginPrivate::startDebugger(RunControl *rc)
+{
+ QTC_ASSERT(rc, return);
+ ProjectExplorerPlugin::instance()->startRunControl(rc, Constants::DEBUGMODE);
+}
-#ifdef Q_OS_WIN
- m_startRemoteCdbAction = new QAction(tr("Attach to Remote CDB Session..."), this);
- connect(m_startRemoteCdbAction, SIGNAL(triggered()), SLOT(startRemoteCdbSession()));
-#endif
- act = m_detachAction = new QAction(this);
- act->setText(tr("Detach Debugger"));
- connect(act, SIGNAL(triggered()), SLOT(handleExecDetach()));
+void DebuggerPluginPrivate::connectEngine(DebuggerEngine *engine)
+{
+ if (!engine)
+ engine = dummyEngine();
- Core::Command *cmd = 0;
+ if (m_currentEngine == engine)
+ return;
- Core::ActionContainer *mstart =
- am->actionContainer(PE::M_DEBUG_STARTDEBUGGING);
+ m_currentEngine = engine;
- cmd = am->registerAction(m_debugAction, Constants::DEBUG, globalcontext);
- cmd->setAttribute(Core::Command::CA_UpdateText);
- cmd->setAttribute(Core::Command::CA_UpdateIcon);
- cmd->setDefaultText(tr("Start Debugging"));
- cmd->setDefaultKeySequence(QKeySequence(Constants::DEBUG_KEY));
- mstart->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
- Core::ICore::instance()->modeManager()->addAction(cmd, Constants::P_ACTION_DEBUG);
+ m_localsWindow->setModel(engine->localsModel());
+ m_modulesWindow->setModel(engine->modulesModel());
+ m_registerWindow->setModel(engine->registerModel());
+ m_returnWindow->setModel(engine->returnModel());
+ m_sourceFilesWindow->setModel(engine->sourceFilesModel());
+ m_stackWindow->setModel(engine->stackModel());
+ m_threadsWindow->setModel(engine->threadsModel());
+ m_threadBox->setModel(engine->threadsModel());
+ m_threadBox->setModelColumn(ThreadData::NameColumn);
+ m_watchersWindow->setModel(engine->watchersModel());
+}
- cmd = am->registerAction(m_actions.continueAction,
- Constants::DEBUG, m_continuableContext);
- mstart->addAction(cmd, CC::G_DEFAULT_ONE);
+static void changeFontSize(QWidget *widget, qreal size)
+{
+ QFont font = widget->font();
+ font.setPointSizeF(size);
+ widget->setFont(font);
+}
- cmd = am->registerAction(m_startExternalAction,
- Constants::STARTEXTERNAL, globalcontext);
- cmd->setAttribute(Command::CA_Hide);
- mstart->addAction(cmd, CC::G_DEFAULT_ONE);
+void DebuggerPluginPrivate::fontSettingsChanged
+ (const TextEditor::FontSettings &settings)
+{
+ qreal size = settings.fontZoom() * settings.fontSize() / 100.;
+ changeFontSize(m_breakWindow, size);
+ changeFontSize(m_logWindow, size);
+ changeFontSize(m_localsWindow, size);
+ changeFontSize(m_modulesWindow, size);
+ //changeFontSize(m_consoleWindow, size);
+ changeFontSize(m_registerWindow, size);
+ changeFontSize(m_returnWindow, size);
+ changeFontSize(m_sourceFilesWindow, size);
+ changeFontSize(m_stackWindow, size);
+ changeFontSize(m_threadsWindow, size);
+ changeFontSize(m_watchersWindow, size);
+}
- cmd = am->registerAction(m_startRemoteLldbAction,
- Constants::STARTREMOTELLDB, globalcontext);
- cmd->setAttribute(Command::CA_Hide);
- mstart->addAction(cmd, CC::G_DEFAULT_ONE);
+void DebuggerPluginPrivate::cleanupViews()
+{
+ m_actions.reverseDirectionAction->setChecked(false);
+ m_actions.reverseDirectionAction->setEnabled(false);
+ hideDebuggerToolTip();
- cmd = am->registerAction(m_attachExternalAction,
- Constants::ATTACHEXTERNAL, globalcontext);
- cmd->setAttribute(Command::CA_Hide);
- mstart->addAction(cmd, CC::G_DEFAULT_ONE);
+ if (!boolSetting(CloseBuffersOnExit))
+ return;
- cmd = am->registerAction(m_attachCoreAction,
- Constants::ATTACHCORE, globalcontext);
+ EditorManager *editorManager = EditorManager::instance();
+ QTC_ASSERT(editorManager, return);
+ QList<IEditor *> toClose;
+ foreach (IEditor *editor, editorManager->openedEditors()) {
+ if (editor->property(Constants::OPENED_BY_DEBUGGER).toBool()) {
+ // Close disassembly views. Close other opened files
+ // if they are not modified and not current editor.
+ if (editor->property(Constants::OPENED_WITH_DISASSEMBLY).toBool()
+ || (!editor->file()->isModified()
+ && editor != editorManager->currentEditor())) {
+ toClose.append(editor);
+ } else {
+ editor->setProperty(Constants::OPENED_BY_DEBUGGER, false);
+ }
+ }
+ }
+ editorManager->closeEditors(toClose);
+}
- cmd->setAttribute(Command::CA_Hide);
- mstart->addAction(cmd, CC::G_DEFAULT_ONE);
+void DebuggerPluginPrivate::setBusyCursor(bool busy)
+{
+ //STATE_DEBUG("BUSY FROM: " << m_busy << " TO: " << busy);
+ if (busy == m_busy)
+ return;
+ m_busy = busy;
+ QCursor cursor(busy ? Qt::BusyCursor : Qt::ArrowCursor);
+ m_breakWindow->setCursor(cursor);
+ //m_consoleWindow->setCursor(cursor);
+ m_localsWindow->setCursor(cursor);
+ m_modulesWindow->setCursor(cursor);
+ m_logWindow->setCursor(cursor);
+ m_registerWindow->setCursor(cursor);
+ m_returnWindow->setCursor(cursor);
+ m_sourceFilesWindow->setCursor(cursor);
+ m_stackWindow->setCursor(cursor);
+ m_threadsWindow->setCursor(cursor);
+ m_watchersWindow->setCursor(cursor);
+ m_snapshotWindow->setCursor(cursor);
+ m_scriptConsoleWindow->setCursor(cursor);
+}
- cmd = am->registerAction(m_attachTcfAction,
- Constants::ATTACHTCF, globalcontext);
- mstart->addAction(cmd, CC::G_DEFAULT_ONE);
+void DebuggerPluginPrivate::setSimpleDockWidgetArrangement
+ (Debugger::DebuggerLanguages activeLanguages)
+{
+ DebuggerMainWindow *mw = debuggerMainWindow();
+ QTC_ASSERT(mw, return);
+ mw->setTrackingEnabled(false);
+
+ QList<QDockWidget *> dockWidgets = mw->dockWidgets();
+ foreach (QDockWidget *dockWidget, dockWidgets) {
+ dockWidget->setFloating(false);
+ mw->removeDockWidget(dockWidget);
+ }
- cmd = am->registerAction(m_startRemoteAction,
- Constants::ATTACHREMOTE, globalcontext);
- cmd->setAttribute(Command::CA_Hide);
- mstart->addAction(cmd, CC::G_DEFAULT_ONE);
+ foreach (QDockWidget *dockWidget, dockWidgets) {
+ if (dockWidget == m_outputDock /*|| dockWidget == m_consoleDock*/) {
+ mw->addDockWidget(Qt::TopDockWidgetArea, dockWidget);
+ } else {
+ mw->addDockWidget(Qt::BottomDockWidgetArea, dockWidget);
+ }
+ dockWidget->hide();
+ }
- if (m_startRemoteCdbAction) {
- cmd = am->registerAction(m_startRemoteCdbAction,
- Constants::ATTACHREMOTECDB, globalcontext);
- cmd->setAttribute(Command::CA_Hide);
- mstart->addAction(cmd, CC::G_DEFAULT_ONE);
+ if ((activeLanguages.testFlag(CppLanguage)
+ && !activeLanguages.testFlag(QmlLanguage))
+ || activeLanguages == AnyLanguage) {
+ m_stackDock->show();
+ m_breakDock->show();
+ m_watchDock->show();
+ m_threadsDock->show();
+ m_snapshotDock->show();
+ } else {
+ m_stackDock->show();
+ m_breakDock->show();
+ m_watchDock->show();
+ m_scriptConsoleDock->show();
+ if (m_uiSwitcher->qmlInspectorWindow())
+ m_uiSwitcher->qmlInspectorWindow()->show();
}
+ mw->splitDockWidget(mw->toolBarDockWidget(), m_stackDock, Qt::Vertical);
+ mw->splitDockWidget(m_stackDock, m_watchDock, Qt::Horizontal);
+ mw->tabifyDockWidget(m_watchDock, m_breakDock);
+ mw->tabifyDockWidget(m_watchDock, m_modulesDock);
+ mw->tabifyDockWidget(m_watchDock, m_registerDock);
+ mw->tabifyDockWidget(m_watchDock, m_threadsDock);
+ mw->tabifyDockWidget(m_watchDock, m_sourceFilesDock);
+ mw->tabifyDockWidget(m_watchDock, m_snapshotDock);
+ mw->tabifyDockWidget(m_watchDock, m_scriptConsoleDock);
+ if (m_uiSwitcher->qmlInspectorWindow())
+ mw->tabifyDockWidget(m_watchDock, m_uiSwitcher->qmlInspectorWindow());
- cmd = am->registerAction(m_detachAction,
- Constants::DETACH, globalcontext);
- cmd->setAttribute(Command::CA_Hide);
- m_uiSwitcher->addMenuAction(cmd, AnyLanguage, CC::G_DEFAULT_ONE);
+ mw->setTrackingEnabled(true);
+}
- cmd = am->registerAction(m_actions.exitAction,
- Constants::STOP, globalcontext);
- //cmd->setDefaultKeySequence(QKeySequence(Constants::STOP_KEY));
- cmd->setDefaultText(tr("Stop Debugger"));
- m_uiSwitcher->addMenuAction(cmd, AnyLanguage, CC::G_DEFAULT_ONE);
+void DebuggerPluginPrivate::setInitialState()
+{
+ m_watchersWindow->setVisible(false);
+ m_returnWindow->setVisible(false);
+ setBusyCursor(false);
+ m_actions.reverseDirectionAction->setChecked(false);
+ m_actions.reverseDirectionAction->setEnabled(false);
+ hideDebuggerToolTip();
- cmd = am->registerAction(m_actions.interruptAction,
- Constants::DEBUG, m_interruptibleContext);
- cmd->setDefaultText(tr("Interrupt Debugger"));
+ m_startExternalAction->setEnabled(true);
+ m_attachExternalAction->setEnabled(true);
+#ifdef Q_OS_WIN
+ m_attachCoreAction->setEnabled(false);
+#else
+ m_attachCoreAction->setEnabled(true);
+#endif
+ m_startRemoteAction->setEnabled(true);
+ m_detachAction->setEnabled(false);
- cmd = am->registerAction(m_actions.undisturbableAction,
- Constants::DEBUG, m_undisturbableContext);
- cmd->setDefaultText(tr("Debugger is Busy"));
+ m_actions.watchAction1->setEnabled(true);
+ m_actions.watchAction2->setEnabled(true);
+ m_actions.breakAction->setEnabled(true);
+ //m_actions.snapshotAction->setEnabled(false);
+ action(OperateByInstruction)->setEnabled(false);
- cmd = am->registerAction(m_actions.resetAction,
- Constants::RESET, globalcontext);
- //cmd->setDefaultKeySequence(QKeySequence(Constants::RESET_KEY));
- cmd->setDefaultText(tr("Reset Debugger"));
- m_uiSwitcher->addMenuAction(cmd, AnyLanguage, CC::G_DEFAULT_ONE);
+ m_actions.exitAction->setEnabled(false);
+ m_actions.resetAction->setEnabled(false);
- QAction *sep = new QAction(this);
- sep->setSeparator(true);
- cmd = am->registerAction(sep, _("Debugger.Sep.Step"), globalcontext);
- m_uiSwitcher->addMenuAction(cmd, CppLanguage);
+ m_actions.stepAction->setEnabled(false);
+ m_actions.stepOutAction->setEnabled(false);
+ m_actions.runToLineAction->setEnabled(false);
+ m_actions.runToFunctionAction->setEnabled(false);
+ m_actions.returnFromFunctionAction->setEnabled(false);
+ m_actions.jumpToLineAction->setEnabled(false);
+ m_actions.nextAction->setEnabled(false);
- cmd = am->registerAction(m_actions.nextAction,
- Constants::NEXT, cppDebuggercontext);
- cmd->setDefaultKeySequence(QKeySequence(Constants::NEXT_KEY));
- cmd->setAttribute(Command::CA_Hide);
- m_uiSwitcher->addMenuAction(cmd, CppLanguage);
+ action(AutoDerefPointers)->setEnabled(true);
+ action(ExpandStack)->setEnabled(false);
+ action(ExecuteCommand)->setEnabled(m_state == InferiorStopOk);
- cmd = am->registerAction(m_actions.stepAction,
- Constants::STEP, cppDebuggercontext);
- cmd->setDefaultKeySequence(QKeySequence(Constants::STEP_KEY));
- cmd->setAttribute(Command::CA_Hide);
- m_uiSwitcher->addMenuAction(cmd, CppLanguage);
+ m_scriptConsoleWindow->setEnabled(false);
+ //emit m_plugin->stateChanged(m_state);
+}
- cmd = am->registerAction(m_actions.stepOutAction,
- Constants::STEPOUT, cppDebuggercontext);
- cmd->setDefaultKeySequence(QKeySequence(Constants::STEPOUT_KEY));
- cmd->setAttribute(Command::CA_Hide);
- m_uiSwitcher->addMenuAction(cmd, CppLanguage);
+void DebuggerPluginPrivate::updateWatchersWindow()
+{
+ m_watchersWindow->setVisible(
+ m_watchersWindow->model()->rowCount(QModelIndex()) > 0);
+ m_returnWindow->setVisible(
+ m_returnWindow->model()->rowCount(QModelIndex()) > 0);
+}
+void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
+{
+ QTC_ASSERT(engine, return);
+ QTC_ASSERT(m_watchersWindow->model(), return);
+ QTC_ASSERT(m_returnWindow->model(), return);
+ QTC_ASSERT(!engine->isSlaveEngine(), return);
- cmd = am->registerAction(m_actions.runToLineAction,
- Constants::RUN_TO_LINE1, cppDebuggercontext);
- cmd->setDefaultKeySequence(QKeySequence(Constants::RUN_TO_LINE_KEY));
- cmd->setAttribute(Command::CA_Hide);
- m_uiSwitcher->addMenuAction(cmd, CppLanguage);
+ m_threadBox->setCurrentIndex(engine->threadsHandler()->currentThread());
+ updateWatchersWindow();
- cmd = am->registerAction(m_actions.runToFunctionAction,
- Constants::RUN_TO_FUNCTION, cppDebuggercontext);
- cmd->setDefaultKeySequence(QKeySequence(Constants::RUN_TO_FUNCTION_KEY));
- cmd->setAttribute(Command::CA_Hide);
- m_uiSwitcher->addMenuAction(cmd, CppLanguage);
+ //m_plugin->showMessage(QString("PLUGIN SET STATE: ")
+ // + DebuggerEngine::stateName(engine->state()), LogStatus);
+ //qDebug() << "PLUGIN SET STATE: " << engine->state();
+ if (m_state == engine->state())
+ return;
- cmd = am->registerAction(m_actions.jumpToLineAction,
- Constants::JUMP_TO_LINE1, cppDebuggercontext);
- cmd->setAttribute(Command::CA_Hide);
- m_uiSwitcher->addMenuAction(cmd, CppLanguage);
+ m_state = engine->state();
+ bool actionsEnabled = DebuggerEngine::debuggerActionsEnabled(m_state);
+
+ ICore *core = ICore::instance();
+ ActionManager *am = core->actionManager();
+ if (m_state == DebuggerNotReady) {
+ QTC_ASSERT(false, /* We use the Core m_debugAction here */);
+ // F5 starts debugging. It is "startable".
+ m_actions.interruptAction->setEnabled(false);
+ m_actions.continueAction->setEnabled(false);
+ m_actions.exitAction->setEnabled(false);
+ am->command(Constants::STOP)->setKeySequence(QKeySequence());
+ am->command(Constants::DEBUG)->setKeySequence(QKeySequence(DEBUG_KEY));
+ core->updateAdditionalContexts(m_anyContext, Context());
+ } else if (m_state == InferiorStopOk) {
+ // F5 continues, Shift-F5 kills. It is "continuable".
+ m_actions.interruptAction->setEnabled(false);
+ m_actions.continueAction->setEnabled(true);
+ m_actions.exitAction->setEnabled(true);
+ am->command(Constants::STOP)->setKeySequence(QKeySequence(STOP_KEY));
+ am->command(Constants::DEBUG)->setKeySequence(QKeySequence(DEBUG_KEY));
+ core->updateAdditionalContexts(m_anyContext, m_continuableContext);
+ } else if (m_state == InferiorRunOk) {
+ // Shift-F5 interrupts. It is also "interruptible".
+ m_actions.interruptAction->setEnabled(true);
+ m_actions.continueAction->setEnabled(false);
+ m_actions.exitAction->setEnabled(false);
+ am->command(Constants::STOP)->setKeySequence(QKeySequence());
+ am->command(Constants::DEBUG)->setKeySequence(QKeySequence(STOP_KEY));
+ core->updateAdditionalContexts(m_anyContext, m_interruptibleContext);
+ } else if (m_state == DebuggerFinished) {
+ // We don't want to do anything anymore.
+ m_actions.interruptAction->setEnabled(false);
+ m_actions.continueAction->setEnabled(false);
+ m_actions.exitAction->setEnabled(false);
+ am->command(Constants::STOP)->setKeySequence(QKeySequence());
+ am->command(Constants::DEBUG)->setKeySequence(QKeySequence(DEBUG_KEY));
+ //core->updateAdditionalContexts(m_anyContext, m_finishedContext);
+ m_codeModelSnapshot = CPlusPlus::Snapshot();
+ core->updateAdditionalContexts(m_anyContext, Context());
+ setBusyCursor(false);
+ cleanupViews();
+ } else if (m_state == InferiorUnrunnable) {
+ // We don't want to do anything anymore.
+ m_actions.interruptAction->setEnabled(false);
+ m_actions.continueAction->setEnabled(false);
+ m_actions.exitAction->setEnabled(true);
+ am->command(Constants::STOP)->setKeySequence(QKeySequence(STOP_KEY));
+ am->command(Constants::DEBUG)->setKeySequence(QKeySequence(STOP_KEY));
+ core->updateAdditionalContexts(m_anyContext, m_finishedContext);
+ } else {
+ // Everything else is "undisturbable".
+ m_actions.interruptAction->setEnabled(false);
+ m_actions.continueAction->setEnabled(false);
+ m_actions.exitAction->setEnabled(false);
+ am->command(Constants::STOP)->setKeySequence(QKeySequence());
+ am->command(Constants::DEBUG)->setKeySequence(QKeySequence());
+ core->updateAdditionalContexts(m_anyContext, m_undisturbableContext);
+ }
+ m_startExternalAction->setEnabled(true);
+ m_attachExternalAction->setEnabled(true);
+#ifdef Q_OS_WIN
+ m_attachCoreAction->setEnabled(false);
+#else
+ m_attachCoreAction->setEnabled(true);
+#endif
+ m_startRemoteAction->setEnabled(true);
- cmd = am->registerAction(m_actions.returnFromFunctionAction,
- Constants::RETURN_FROM_FUNCTION, cppDebuggercontext);
- cmd->setAttribute(Command::CA_Hide);
- m_uiSwitcher->addMenuAction(cmd, CppLanguage);
+ const bool isCore = engine->startParameters().startMode == AttachCore;
+ const bool stopped = m_state == InferiorStopOk;
+ const bool detachable = stopped && !isCore;
+ m_detachAction->setEnabled(detachable);
+ if (stopped)
+ QApplication::alert(mainWindow(), 3000);
- cmd = am->registerAction(m_actions.reverseDirectionAction,
- Constants::REVERSE, cppDebuggercontext);
- cmd->setDefaultKeySequence(QKeySequence(Constants::REVERSE_KEY));
- cmd->setAttribute(Command::CA_Hide);
- m_uiSwitcher->addMenuAction(cmd, CppLanguage);
+ const uint caps = engine->debuggerCapabilities();
+ const bool canReverse = (caps & ReverseSteppingCapability)
+ && boolSetting(EnableReverseDebugging);
+ m_actions.reverseDirectionAction->setEnabled(canReverse);
+ m_actions.watchAction1->setEnabled(true);
+ m_actions.watchAction2->setEnabled(true);
+ m_actions.breakAction->setEnabled(true);
+ //m_actions.snapshotAction->setEnabled(stopped && (caps & SnapshotCapability));
- sep = new QAction(this);
- sep->setSeparator(true);
- cmd = am->registerAction(sep, _("Debugger.Sep.Break"), globalcontext);
- m_uiSwitcher->addMenuAction(cmd, CppLanguage);
+ action(OperateByInstruction)->setEnabled(stopped || isCore);
+ m_actions.resetAction->setEnabled(m_state != DebuggerNotReady
+ && m_state != DebuggerFinished);
- //cmd = am->registerAction(m_actions.snapshotAction,
- // Constants::SNAPSHOT, cppDebuggercontext);
- //cmd->setDefaultKeySequence(QKeySequence(Constants::SNAPSHOT_KEY));
- //cmd->setAttribute(Command::CA_Hide);
- //m_uiSwitcher->addMenuAction(cmd, CppLanguage);
+ m_actions.stepAction->setEnabled(stopped);
+ m_actions.stepOutAction->setEnabled(stopped);
+ m_actions.runToLineAction->setEnabled(stopped);
+ m_actions.runToFunctionAction->setEnabled(stopped);
+ m_actions.returnFromFunctionAction->
+ setEnabled(stopped && (caps & ReturnFromFunctionCapability));
- cmd = am->registerAction(m_actions.frameDownAction,
- Constants::FRAME_DOWN, cppDebuggercontext);
- cmd = am->registerAction(m_actions.frameUpAction,
- Constants::FRAME_UP, cppDebuggercontext);
+ const bool canJump = stopped && (caps & JumpToLineCapability);
+ m_actions.jumpToLineAction->setEnabled(canJump);
+ m_actions.nextAction->setEnabled(stopped);
- cmd = am->registerAction(action(OperateByInstruction),
- Constants::OPERATE_BY_INSTRUCTION, cppDebuggercontext);
- cmd->setAttribute(Command::CA_Hide);
- m_uiSwitcher->addMenuAction(cmd, CppLanguage);
+ const bool canDeref = actionsEnabled && (caps & AutoDerefPointersCapability);
+ action(AutoDerefPointers)->setEnabled(canDeref);
+ action(AutoDerefPointers)->setEnabled(true);
+ action(ExpandStack)->setEnabled(actionsEnabled);
+ action(ExecuteCommand)->setEnabled(m_state == InferiorStopOk);
+ const bool notbusy = m_state == InferiorStopOk
+ || m_state == DebuggerNotReady
+ || m_state == DebuggerFinished
+ || m_state == InferiorUnrunnable;
+ setBusyCursor(!notbusy);
- cmd = am->registerAction(m_actions.breakAction,
- Constants::TOGGLE_BREAK, globalcontext);
- cmd->setDefaultKeySequence(QKeySequence(Constants::TOGGLE_BREAK_KEY));
- m_uiSwitcher->addMenuAction(cmd, CppLanguage);
- connect(m_actions.breakAction, SIGNAL(triggered()),
- SLOT(toggleBreakpoint()));
+ m_scriptConsoleWindow->setEnabled(stopped);
+}
- //mcppcontext->addAction(cmd);
+void DebuggerPluginPrivate::updateDebugActions()
+{
+ ProjectExplorerPlugin *pe = ProjectExplorerPlugin::instance();
+ Project *project = pe->startupProject();
+ m_debugAction->setEnabled(pe->canRun(project, Constants::DEBUGMODE));
+}
- sep = new QAction(this);
- sep->setSeparator(true);
- cmd = am->registerAction(sep, _("Debugger.Sep.Watch"), globalcontext);
- m_uiSwitcher->addMenuAction(cmd, CppLanguage);
+void DebuggerPluginPrivate::gotoLocation(const QString &file, int line, bool setMarker)
+{
+ // CDB might hit on breakpoints while shutting down.
+ if (m_shuttingDown)
+ return;
+ doRemoveLocationMark();
- cmd = am->registerAction(m_actions.watchAction1,
- Constants::ADD_TO_WATCH1, cppeditorcontext);
- cmd->action()->setEnabled(true);
- //cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+D,Ctrl+W")));
- m_uiSwitcher->addMenuAction(cmd, CppLanguage);
+ bool newEditor = false;
+ ITextEditor *editor =
+ BaseTextEditor::openEditorAt(file, line, 0, QString(),
+ EditorManager::IgnoreNavigationHistory, &newEditor);
+ if (!editor)
+ return;
+ if (newEditor)
+ editor->setProperty(Debugger::Constants::OPENED_BY_DEBUGGER, true);
+ if (setMarker)
+ m_locationMark.reset(new LocationMark(file, line));
+}
+void DebuggerPluginPrivate::onModeChanged(IMode *mode)
+{
+ // FIXME: This one gets always called, even if switching between modes
+ // different then the debugger mode. E.g. Welcome and Help mode and
+ // also on shutdown.
- // Editor context menu
- ActionContainer *editorContextMenu =
- am->actionContainer(CppEditor::Constants::M_CONTEXT);
- cmd = am->registerAction(sep, _("Debugger.Sep.Views"),
- cppDebuggercontext);
- editorContextMenu->addAction(cmd);
- cmd->setAttribute(Command::CA_Hide);
+ m_uiSwitcher->onModeChanged(mode);
- cmd = am->registerAction(m_actions.watchAction2,
- Constants::ADD_TO_WATCH2, cppDebuggercontext);
- cmd->action()->setEnabled(true);
- editorContextMenu->addAction(cmd);
- cmd->setAttribute(Command::CA_Hide);
+ if (mode != m_debugMode)
+ return;
- m_plugin->addAutoReleasedObject(new CommonOptionsPage);
- QList<Core::IOptionsPage *> engineOptionPages;
- if (cmdLineEnabledEngines & GdbEngineType)
- addGdbOptionPages(&engineOptionPages);
-#ifdef CDB_ENABLED
- if (cmdLineEnabledEngines & CdbEngineType)
- addCdbOptionPages(&engineOptionPages);
-#endif
-#ifdef Q_OS_WIN
- Debugger::Cdb::addCdb2OptionPages(&engineOptionPages);
-#endif
-#ifdef WITH_LLDB
- if (cmdLineEnabledEngines & LldbEngineType)
- addLldbOptionPages(&engineOptionPages);
-#endif
+ EditorManager *editorManager = EditorManager::instance();
+ if (editorManager->currentEditor())
+ editorManager->currentEditor()->widget()->setFocus();
+}
- //if (cmdLineEnabledEngines & ScriptEngineType)
- // addScriptOptionPages(&engineOptionPages);
- //if (cmdLineEnabledEngines & TcfEngineType)
- // addTcfOptionPages(&engineOptionPages);
- foreach (Core::IOptionsPage *op, engineOptionPages)
- m_plugin->addAutoReleasedObject(op);
- m_plugin->addAutoReleasedObject(new DebuggingHelperOptionPage);
+void DebuggerPluginPrivate::showSettingsDialog()
+{
+ ICore::instance()->showOptionsDialog(
+ _(DEBUGGER_SETTINGS_CATEGORY),
+ _(DEBUGGER_COMMON_SETTINGS_ID));
+}
- //setSimpleDockWidgetArrangement(Lang_Cpp);
+void DebuggerPluginPrivate::dumpLog()
+{
+ QString fileName = QFileDialog::getSaveFileName(mainWindow(),
+ tr("Save Debugger Log"), QDir::tempPath());
+ if (fileName.isEmpty())
+ return;
+ QFile file(fileName);
+ if (!file.open(QIODevice::WriteOnly))
+ return;
+ QTextStream ts(&file);
+ ts << m_logWindow->inputContents();
+ ts << "\n\n=======================================\n\n";
+ ts << m_logWindow->combinedContents();
+}
- connect(ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode*)),
- SLOT(onModeChanged(Core::IMode*)));
- m_debugMode->widget()->setFocusProxy(EditorManager::instance());
- m_plugin->addObject(m_debugMode);
+void DebuggerPluginPrivate::clearStatusMessage()
+{
+ m_statusLabel->setText(m_lastPermanentStatusMessage);
+}
+/*! Activates the previous mode when the current mode is the debug mode. */
+void DebuggerPluginPrivate::activatePreviousMode()
+{
+ ModeManager *modeManager = ICore::instance()->modeManager();
- //
- // Connections
- //
+ if (modeManager->currentMode() == modeManager->mode(MODE_DEBUG)
+ && !m_previousMode.isEmpty()) {
+ modeManager->activateMode(m_previousMode);
+ m_previousMode.clear();
+ }
+}
- // TextEditor
- connect(TextEditorSettings::instance(),
- SIGNAL(fontSettingsChanged(TextEditor::FontSettings)),
- SLOT(fontSettingsChanged(TextEditor::FontSettings)));
+void DebuggerPluginPrivate::activateDebugMode()
+{
+ m_actions.reverseDirectionAction->setChecked(false);
+ m_actions.reverseDirectionAction->setEnabled(false);
+ ModeManager *modeManager = ModeManager::instance();
+ m_previousMode = modeManager->currentMode()->id();
+ modeManager->activateMode(_(MODE_DEBUG));
+}
- // ProjectExplorer
- connect(sessionManager(), SIGNAL(sessionLoaded()),
- SLOT(sessionLoaded()));
- connect(sessionManager(), SIGNAL(aboutToSaveSession()),
- SLOT(aboutToSaveSession()));
- connect(sessionManager(), SIGNAL(aboutToUnloadSession()),
- SLOT(aboutToUnloadSession()));
- connect(ProjectExplorerPlugin::instance(), SIGNAL(updateRunActions()),
- SLOT(updateDebugActions()));
+void DebuggerPluginPrivate::sessionLoaded()
+{
+ m_breakHandler->loadSessionData();
+ dummyEngine()->watchHandler()->loadSessionData();
+}
- // EditorManager
- QObject *editorManager = core->editorManager();
- connect(editorManager, SIGNAL(editorAboutToClose(Core::IEditor*)),
- SLOT(editorAboutToClose(Core::IEditor*)));
- connect(editorManager, SIGNAL(editorOpened(Core::IEditor*)),
- SLOT(editorOpened(Core::IEditor*)));
+void DebuggerPluginPrivate::aboutToUnloadSession()
+{
+ m_breakHandler->removeSessionData();
+ // Stop debugging the active project when switching sessions.
+ // Note that at startup, session switches may occur, which interfere
+ // with command-line debugging startup.
+ // FIXME ABC: Still wanted? Iterate?
+ //if (d->m_engine && state() != DebuggerNotReady
+ // && runControl()->sp().startMode == StartInternal)
+ // d->m_engine->shutdown();
+}
- // Application interaction
- connect(action(SettingsDialog), SIGNAL(triggered()),
- SLOT(showSettingsDialog()));
+void DebuggerPluginPrivate::aboutToSaveSession()
+{
+ dummyEngine()->watchHandler()->loadSessionData();
+ m_breakHandler->saveSessionData();
+}
- // Toolbar
- QWidget *toolbarContainer = new QWidget;
+void DebuggerPluginPrivate::executeDebuggerCommand()
+{
+ if (QAction *action = qobject_cast<QAction *>(sender()))
+ currentEngine()->executeDebuggerCommand(action->data().toString());
+}
- QHBoxLayout *hbox = new QHBoxLayout(toolbarContainer);
- hbox->setMargin(0);
- hbox->setSpacing(0);
- hbox->addWidget(toolButton(am->command(Constants::DEBUG)->action()));
- hbox->addWidget(toolButton(am->command(STOP)->action()));
- hbox->addWidget(toolButton(am->command(NEXT)->action()));
- hbox->addWidget(toolButton(am->command(STEP)->action()));
- hbox->addWidget(toolButton(am->command(STEPOUT)->action()));
- hbox->addWidget(toolButton(am->command(OPERATE_BY_INSTRUCTION)->action()));
+void DebuggerPluginPrivate::showStatusMessage(const QString &msg0, int timeout)
+{
+ showMessage(msg0, LogStatus);
+ QString msg = msg0;
+ msg.replace(QLatin1Char('\n'), QString());
+ m_statusLabel->setText(msg);
+ if (timeout > 0) {
+ m_statusTimer.setSingleShot(true);
+ m_statusTimer.start(timeout);
+ } else {
+ m_lastPermanentStatusMessage = msg;
+ m_statusTimer.stop();
+ }
+}
- //hbox->addWidget(new Utils::StyledSeparator);
- m_reverseToolButton = toolButton(am->command(REVERSE)->action());
- hbox->addWidget(m_reverseToolButton);
- //m_reverseToolButton->hide();
+void DebuggerPluginPrivate::scriptExpressionEntered(const QString &expression)
+{
+ currentEngine()->executeDebuggerCommand(expression);
+}
- hbox->addWidget(new Utils::StyledSeparator);
- hbox->addWidget(new QLabel(tr("Threads:")));
+void DebuggerPluginPrivate::openMemoryEditor()
+{
+ AddressDialog dialog;
+ if (dialog.exec() == QDialog::Accepted)
+ (void) new MemoryViewAgent(currentEngine(), dialog.address());
+}
- m_threadBox = new QComboBox;
- connect(m_threadBox, SIGNAL(activated(int)), SLOT(selectThread(int)));
+void DebuggerPluginPrivate::coreShutdown()
+{
+ m_shuttingDown = true;
+}
- hbox->addWidget(m_threadBox);
- hbox->addSpacerItem(new QSpacerItem(4, 0));
- hbox->addWidget(m_statusLabel, 10);
+void DebuggerPluginPrivate::writeSettings() const
+{
+ m_debuggerSettings->writeSettings();
+ m_uiSwitcher->writeSettings();
+ if (GdbOptionsPage::gdbBinariesChanged)
+ GdbOptionsPage::writeGdbBinarySettings();
+}
- m_uiSwitcher->setToolbar(CppLanguage, toolbarContainer);
- connect(m_uiSwitcher,
- SIGNAL(dockResetRequested(Debugger::DebuggerLanguages)),
- SLOT(setSimpleDockWidgetArrangement(Debugger::DebuggerLanguages)));
+void DebuggerPluginPrivate::readSettings()
+{
+ //qDebug() << "PLUGIN READ SETTINGS";
+ m_debuggerSettings->readSettings();
+ m_uiSwitcher->readSettings();
+ GdbOptionsPage::readGdbBinarySettings();
+}
- connect(action(EnableReverseDebugging),
- SIGNAL(valueChanged(QVariant)),
- SLOT(enableReverseDebuggingTriggered(QVariant)));
+const CPlusPlus::Snapshot &DebuggerPluginPrivate::cppCodeModelSnapshot() const
+{
+ using namespace CppTools;
+ if (m_codeModelSnapshot.isEmpty() && action(UseCodeModel)->isChecked())
+ m_codeModelSnapshot = CppModelManagerInterface::instance()->snapshot();
+ return m_codeModelSnapshot;
+}
- // UI Switcher
- connect(m_uiSwitcher,
- SIGNAL(activeLanguagesChanged(Debugger::DebuggerLanguages)),
- SLOT(languagesChanged(Debugger::DebuggerLanguages)));
+void DebuggerPluginPrivate::resetLocation()
+{
+ currentEngine()->resetLocation();
+}
- setInitialState();
- connectEngine(0);
+void DebuggerPluginPrivate::removeLocationMark()
+{
+ m_locationTimer.setSingleShot(true);
+ m_locationTimer.start(80);
+}
- connect(sessionManager(),
- SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
- SLOT(onCurrentProjectChanged(ProjectExplorer::Project*)));
+void DebuggerPluginPrivate::doRemoveLocationMark()
+{
+ m_locationTimer.stop();
+ m_locationMark.reset();
+}
- connect(&m_locationTimer,
- SIGNAL(timeout()),
- SLOT(doRemoveLocationMark()));
+void DebuggerPluginPrivate::setSessionValue(const QString &name, const QVariant &value)
+{
+ QTC_ASSERT(sessionManager(), return);
+ sessionManager()->setValue(name, value);
+ //qDebug() << "SET SESSION VALUE: " << name;
+}
- return true;
+QVariant DebuggerPluginPrivate::sessionValue(const QString &name)
+{
+ QTC_ASSERT(sessionManager(), return QVariant());
+ //qDebug() << "GET SESSION VALUE: " << name;
+ return sessionManager()->value(name);
}
-void DebuggerPluginPrivate::setConfigValue(const QString &name, const QVariant &value)
+void DebuggerPluginPrivate::openTextEditor(const QString &titlePattern0,
+ const QString &contents)
{
- m_coreSettings->setValue(_("DebugMode/") + name, value);
+ if (m_shuttingDown)
+ return;
+ QString titlePattern = titlePattern0;
+ EditorManager *editorManager = EditorManager::instance();
+ QTC_ASSERT(editorManager, return);
+ IEditor *editor = editorManager->openEditorWithContents(
+ CC::K_DEFAULT_TEXT_EDITOR_ID, &titlePattern, contents);
+ QTC_ASSERT(editor, return);
+ editorManager->activateEditor(editor, EditorManager::IgnoreNavigationHistory);
}
-QVariant DebuggerPluginPrivate::configValue(const QString &name) const
+
+void DebuggerPluginPrivate::clearCppCodeModelSnapshot()
{
- const QVariant value = m_coreSettings->value(_("DebugMode/") + name);
- if (value.isValid())
- return value;
- // Legacy (pre-2.1): Check old un-namespaced-settings.
- return m_coreSettings->value(name);
+ m_codeModelSnapshot = CPlusPlus::Snapshot();
}
-void DebuggerPluginPrivate::onCurrentProjectChanged(Project *project)
+void DebuggerPluginPrivate::showMessage(const QString &msg, int channel, int timeout)
{
- RunConfiguration *activeRc = 0;
- if (project) {
- Target *target = project->activeTarget();
- QTC_ASSERT(target, return);
- activeRc = target->activeRunConfiguration();
- QTC_ASSERT(activeRc, /**/);
- }
- for (int i = 0, n = m_snapshotHandler->size(); i != n; ++i) {
- // Run controls might be deleted during exit.
- if (DebuggerRunControl *runControl = m_snapshotHandler->at(i)) {
- RunConfiguration *rc = runControl->runConfiguration();
- if (rc == activeRc) {
- m_snapshotHandler->setCurrentIndex(i);
- DebuggerEngine *engine = runControl->engine();
- updateState(engine);
- return;
- }
- }
+ //qDebug() << "PLUGIN OUTPUT: " << channel << msg;
+ //ConsoleWindow *cw = m_consoleWindow;
+ QTC_ASSERT(m_logWindow, return);
+ switch (channel) {
+ case StatusBar:
+ // This will append to m_logWindow's output pane, too.
+ showStatusMessage(msg, timeout);
+ break;
+ case LogMiscInput:
+ m_logWindow->showInput(LogMisc, msg);
+ m_logWindow->showOutput(LogMisc, msg);
+ break;
+ case LogInput:
+ m_logWindow->showInput(LogInput, msg);
+ m_logWindow->showOutput(LogInput, msg);
+ break;
+ case ScriptConsoleOutput:
+ m_scriptConsoleWindow->appendResult(msg);
+ break;
+ case LogError:
+ m_logWindow->showOutput(channel, msg);
+ ensureLogVisible();
+ break;
+ default:
+ m_logWindow->showOutput(channel, msg);
+ break;
}
- // No corresponding debugger found. So we are ready to start one.
- ICore *core = ICore::instance();
- core->updateAdditionalContexts(m_anyContext, Context());
}
-void DebuggerPluginPrivate::languagesChanged(const DebuggerLanguages &languages)
+DebuggerMainWindow *DebuggerPluginPrivate::debuggerMainWindow() const
{
- const bool debuggerIsCPP = (languages & CppLanguage);
- //qDebug() << "DEBUGGER IS CPP: " << debuggerIsCPP;
-
- m_startExternalAction->setVisible(debuggerIsCPP);
- m_attachExternalAction->setVisible(debuggerIsCPP);
- m_attachCoreAction->setVisible(debuggerIsCPP);
- m_startRemoteAction->setVisible(debuggerIsCPP);
- m_detachAction->setVisible(debuggerIsCPP);
+ return qobject_cast<DebuggerMainWindow*>(mainWindow());
}
-void DebuggerPluginPrivate::debugProject()
+void DebuggerPluginPrivate::showQtDumperLibraryWarning(const QString &details)
{
- ProjectExplorerPlugin *pe = ProjectExplorerPlugin::instance();
- if (Project *pro = pe->startupProject())
- pe->runProject(pro, Constants::DEBUGMODE);
+ QMessageBox dialog(mainWindow());
+ QPushButton *qtPref = dialog.addButton(tr("Open Qt4 Options"),
+ QMessageBox::ActionRole);
+ QPushButton *helperOff = dialog.addButton(tr("Turn off Helper Usage"),
+ QMessageBox::ActionRole);
+ QPushButton *justContinue = dialog.addButton(tr("Continue Anyway"),
+ QMessageBox::AcceptRole);
+ dialog.setDefaultButton(justContinue);
+ dialog.setWindowTitle(tr("Debugging Helper Missing"));
+ dialog.setText(tr("The debugger could not load the debugging helper library."));
+ dialog.setInformativeText(tr(
+ "The debugging helper is used to nicely format the values of some Qt "
+ "and Standard Library data types. "
+ "It must be compiled for each used Qt version separately. "
+ "On the Qt4 options page, select a Qt installation "
+ "and click Rebuild."));
+ if (!details.isEmpty())
+ dialog.setDetailedText(details);
+ dialog.exec();
+ if (dialog.clickedButton() == qtPref) {
+ ICore::instance()->showOptionsDialog(
+ _(Qt4ProjectManager::Constants::QT_SETTINGS_CATEGORY),
+ _(Qt4ProjectManager::Constants::QTVERSION_SETTINGS_PAGE_ID));
+ } else if (dialog.clickedButton() == helperOff) {
+ action(UseDebuggingHelpers)->setValue(qVariantFromValue(false), false);
+ }
}
-void DebuggerPluginPrivate::startExternalApplication()
+bool DebuggerPluginPrivate::isRegisterViewVisible() const
{
- DebuggerStartParameters sp;
- StartExternalDialog dlg(mainWindow());
- dlg.setExecutableFile(
- configValue(_("LastExternalExecutableFile")).toString());
- dlg.setExecutableArguments(
- configValue(_("LastExternalExecutableArguments")).toString());
- dlg.setWorkingDirectory(
- configValue(_("LastExternalWorkingDirectory")).toString());
- if (dlg.exec() != QDialog::Accepted)
- return;
+ return m_registerDock->toggleViewAction()->isChecked();
+}
- setConfigValue(_("LastExternalExecutableFile"),
- dlg.executableFile());
- setConfigValue(_("LastExternalExecutableArguments"),
- dlg.executableArguments());
- setConfigValue(_("LastExternalWorkingDirectory"),
- dlg.workingDirectory());
- sp.executable = dlg.executableFile();
- sp.startMode = StartExternal;
- sp.workingDirectory = dlg.workingDirectory();
- sp.breakAtMain = dlg.breakAtMain();
- if (!dlg.executableArguments().isEmpty())
- sp.processArgs = dlg.executableArguments();
- // Fixme: 1 of 3 testing hacks.
- if (sp.processArgs.startsWith(__("@tcf@ ")) || sp.processArgs.startsWith(__("@sym@ ")))
- sp.toolChainType = ToolChain_RVCT2_ARMV5;
+void DebuggerPluginPrivate::createNewDock(QWidget *widget)
+{
+ QDockWidget *dockWidget =
+ m_uiSwitcher->createDockWidget(CppLanguage, widget);
+ dockWidget->setWindowTitle(widget->windowTitle());
+ dockWidget->setObjectName(widget->windowTitle());
+ dockWidget->setFeatures(QDockWidget::DockWidgetClosable);
+ //dockWidget->setWidget(widget);
+ //mainWindow()->addDockWidget(Qt::TopDockWidgetArea, dockWidget);
+ dockWidget->show();
+}
+void DebuggerPluginPrivate::runControlStarted(DebuggerRunControl *runControl)
+{
+ activateDebugMode();
+ if (!hasSnapshots())
+ m_uiSwitcher->updateActiveLanguages();
- if (RunControl *rc = m_debuggerRunControlFactory->create(sp))
- startDebugger(rc);
+ const QString message = runControl->idString();
+ showMessage(message, StatusBar);
+ showMessage(m_debuggerSettings->dump(), LogDebug);
+ m_snapshotHandler->appendSnapshot(runControl);
+ connectEngine(runControl->engine());
}
-void DebuggerPluginPrivate::attachExternalApplication()
+void DebuggerPluginPrivate::runControlFinished(DebuggerRunControl *runControl)
{
- AttachExternalDialog dlg(mainWindow());
- if (dlg.exec() == QDialog::Accepted)
- attachExternalApplication(dlg.attachPID(), dlg.executable(), QString());
+ m_snapshotHandler->removeSnapshot(runControl);
+ if (m_snapshotHandler->size() == 0) {
+ // Last engine quits.
+ disconnectEngine();
+ if (boolSetting(SwitchModeOnExit))
+ activatePreviousMode();
+ } else {
+ // Connect to some existing engine.
+ m_snapshotHandler->activateSnapshot(0);
+ }
}
-void DebuggerPluginPrivate::attachExternalApplication
- (qint64 pid, const QString &binary, const QString &crashParameter)
+void DebuggerPluginPrivate::remoteCommand(const QStringList &options,
+ const QStringList &)
{
- if (pid == 0) {
- QMessageBox::warning(mainWindow(), tr("Warning"),
- tr("Cannot attach to PID 0"));
+ if (options.isEmpty())
+ return;
+
+ unsigned enabledEngines = 0;
+ QString errorMessage;
+
+ if (!parseArguments(options,
+ &m_attachRemoteParameters, &enabledEngines, &errorMessage)) {
+ qWarning("%s", qPrintable(errorMessage));
return;
}
- DebuggerStartParameters sp;
- sp.attachPID = pid;
- sp.displayName = tr("Process %1").arg(pid);
- sp.executable = binary;
- sp.crashParameter = crashParameter;
- sp.startMode = crashParameter.isEmpty() ? AttachExternal : AttachCrashedExternal;
- if (DebuggerRunControl *rc = createDebugger(sp))
- startDebugger(rc);
+
+ if (!attachCmdLine())
+ qWarning("%s", qPrintable(
+ _("Incomplete remote attach command received: %1").
+ arg(options.join(QString(QLatin1Char(' '))))));
}
-void DebuggerPluginPrivate::attachCore()
+QString DebuggerPluginPrivate::gdbBinaryForToolChain(int toolChain) const
{
- AttachCoreDialog dlg(mainWindow());
- dlg.setExecutableFile(configValue(_("LastExternalExecutableFile")).toString());
- dlg.setCoreFile(configValue(_("LastExternalCoreFile")).toString());
- if (dlg.exec() != QDialog::Accepted)
- return;
- setConfigValue(_("LastExternalExecutableFile"), dlg.executableFile());
- setConfigValue(_("LastExternalCoreFile"), dlg.coreFile());
- attachCore(dlg.coreFile(), dlg.executableFile());
+ return GdbOptionsPage::gdbBinaryToolChainMap.key(toolChain);
}
-void DebuggerPluginPrivate::attachCore(const QString &core, const QString &exe)
+DebuggerLanguages DebuggerPluginPrivate::activeLanguages() const
{
- DebuggerStartParameters sp;
- sp.executable = exe;
- sp.coreFile = core;
- sp.displayName = tr("Core file \"%1\"").arg(core);
- sp.startMode = AttachCore;
- if (DebuggerRunControl *rc = createDebugger(sp))
- startDebugger(rc);
+ return m_uiSwitcher->activeDebugLanguages();
}
-void DebuggerPluginPrivate::attachRemote(const QString &spec)
+bool DebuggerPluginPrivate::isReverseDebugging() const
{
- // spec is: executable@server:port@architecture
- DebuggerStartParameters sp;
- sp.executable = spec.section('@', 0, 0);
- sp.remoteChannel = spec.section('@', 1, 1);
- sp.remoteArchitecture = spec.section('@', 2, 2);
- sp.displayName = tr("Remote: \"%1\"").arg(sp.remoteChannel);
- sp.startMode = AttachToRemote;
- if (DebuggerRunControl *rc = createDebugger(sp))
- startDebugger(rc);
+ return m_actions.reverseDirectionAction->isChecked();
}
-void DebuggerPluginPrivate::startRemoteCdbSession()
+QMessageBox *showMessageBox(int icon, const QString &title,
+ const QString &text, int buttons)
{
- const QString connectionKey = _("CdbRemoteConnection");
- DebuggerStartParameters sp;
- sp.toolChainType = ToolChain_MSVC;
- sp.startMode = AttachToRemote;
- StartRemoteCdbDialog dlg(mainWindow());
- QString previousConnection = configValue(connectionKey).toString();
- if (previousConnection.isEmpty())
- previousConnection = QLatin1String("localhost:1234");
- dlg.setConnection(previousConnection);
- if (dlg.exec() != QDialog::Accepted)
- return;
- sp.remoteChannel = dlg.connection();
- setConfigValue(connectionKey, sp.remoteChannel);
- if (RunControl *rc = createDebugger(sp))
- startDebugger(rc);
+ QMessageBox *mb = new QMessageBox(QMessageBox::Icon(icon),
+ title, text, QMessageBox::StandardButtons(buttons),
+ debuggerCore()->mainWindow());
+ mb->setAttribute(Qt::WA_DeleteOnClose);
+ mb->show();
+ return mb;
}
-void DebuggerPluginPrivate::startRemoteApplication()
+void DebuggerPluginPrivate::ensureLogVisible()
{
- DebuggerStartParameters sp;
- StartRemoteDialog dlg(mainWindow());
- QStringList arches;
- arches.append(_("i386:x86-64:intel"));
- arches.append(_("i386"));
- arches.append(_("arm"));
- QString lastUsed = configValue(_("LastRemoteArchitecture")).toString();
- if (!arches.contains(lastUsed))
- arches.prepend(lastUsed);
- dlg.setRemoteArchitectures(arches);
- QStringList gnuTargets;
- gnuTargets.append(_("auto"));
- gnuTargets.append(_("i686-linux-gnu"));
- gnuTargets.append(_("x86_64-linux-gnu"));
- gnuTargets.append(_("arm-none-linux-gnueabi"));
- const QString lastUsedGnuTarget
- = configValue(_("LastGnuTarget")).toString();
- if (!gnuTargets.contains(lastUsedGnuTarget))
- gnuTargets.prepend(lastUsedGnuTarget);
- dlg.setGnuTargets(gnuTargets);
- dlg.setRemoteChannel(
- configValue(_("LastRemoteChannel")).toString());
- dlg.setLocalExecutable(
- configValue(_("LastLocalExecutable")).toString());
- dlg.setDebugger(configValue(_("LastDebugger")).toString());
- dlg.setRemoteArchitecture(lastUsed);
- dlg.setGnuTarget(lastUsedGnuTarget);
- dlg.setServerStartScript(
- configValue(_("LastServerStartScript")).toString());
- dlg.setUseServerStartScript(
- configValue(_("LastUseServerStartScript")).toBool());
- dlg.setSysRoot(configValue(_("LastSysroot")).toString());
- if (dlg.exec() != QDialog::Accepted)
- return;
- setConfigValue(_("LastRemoteChannel"), dlg.remoteChannel());
- setConfigValue(_("LastLocalExecutable"), dlg.localExecutable());
- setConfigValue(_("LastDebugger"), dlg.debugger());
- setConfigValue(_("LastRemoteArchitecture"), dlg.remoteArchitecture());
- setConfigValue(_("LastGnuTarget"), dlg.gnuTarget());
- setConfigValue(_("LastServerStartScript"), dlg.serverStartScript());
- setConfigValue(_("LastUseServerStartScript"), dlg.useServerStartScript());
- setConfigValue(_("LastSysroot"), dlg.sysRoot());
- sp.remoteChannel = dlg.remoteChannel();
- sp.remoteArchitecture = dlg.remoteArchitecture();
- sp.gnuTarget = dlg.gnuTarget();
- sp.executable = dlg.localExecutable();
- sp.displayName = dlg.localExecutable();
- sp.debuggerCommand = dlg.debugger(); // Override toolchain-detection.
- if (!sp.debuggerCommand.isEmpty())
- sp.toolChainType = ToolChain_INVALID;
- sp.startMode = AttachToRemote;
- sp.useServerStartScript = dlg.useServerStartScript();
- sp.serverStartScript = dlg.serverStartScript();
- sp.sysRoot = dlg.sysRoot();
- if (RunControl *rc = createDebugger(sp))
- startDebugger(rc);
+ QAction *action = m_outputDock->toggleViewAction();
+ if (!action->isChecked())
+ action->trigger();
}
-void DebuggerPluginPrivate::startRemoteEngine()
+void DebuggerPluginPrivate::extensionsInitialized()
{
- DebuggerStartParameters sp;
- StartRemoteEngineDialog dlg(mainWindow());
- if (dlg.exec() != QDialog::Accepted)
- return;
+ ICore *core = ICore::instance();
+ QTC_ASSERT(core, return);
+ m_coreSettings = core->settings();
+ m_debuggerSettings = new DebuggerSettings(m_coreSettings);
- sp.connParams.host = dlg.host();
- sp.connParams.uname = dlg.username();
- sp.connParams.pwd = dlg.password();
+ m_continuableContext = Context("Gdb.Continuable");
+ m_interruptibleContext = Context("Gdb.Interruptible");
+ m_undisturbableContext = Context("Gdb.Undisturbable");
+ m_finishedContext = Context("Gdb.Finished");
+ m_anyContext.add(m_continuableContext);
+ m_anyContext.add(m_interruptibleContext);
+ m_anyContext.add(m_undisturbableContext);
+ m_anyContext.add(m_finishedContext);
- sp.connParams.timeout = 5;
- sp.connParams.authType = SshConnectionParameters::AuthByPwd;
- sp.connParams.port = 22;
- sp.connParams.proxyType = SshConnectionParameters::NoProxy;
+ connect(core, SIGNAL(coreAboutToClose()), this, SLOT(coreShutdown()));
- sp.executable = dlg.inferiorPath();
- sp.serverStartScript = dlg.enginePath();
- sp.startMode = StartRemoteEngine;
- if (RunControl *rc = createDebugger(sp))
- startDebugger(rc);
-}
+ Core::ActionManager *am = core->actionManager();
+ QTC_ASSERT(am, return);
-void DebuggerPluginPrivate::enableReverseDebuggingTriggered(const QVariant &value)
-{
- QTC_ASSERT(m_reverseToolButton, return);
- m_reverseToolButton->setVisible(value.toBool());
- m_actions.reverseDirectionAction->setChecked(false);
- m_actions.reverseDirectionAction->setEnabled(value.toBool());
-}
+ const Context globalcontext(CC::C_GLOBAL);
+ const Context cppDebuggercontext(C_CPPDEBUGGER);
+ const Context qmlDebuggerContext(C_QMLDEBUGGER);
+ const Context cppeditorcontext(CppEditor::Constants::C_CPPEDITOR);
-void DebuggerPluginPrivate::attachRemoteTcf()
-{
- DebuggerStartParameters sp;
- AttachTcfDialog dlg(mainWindow());
- QStringList arches;
- arches.append(_("i386:x86-64:intel"));
- dlg.setRemoteArchitectures(arches);
- dlg.setRemoteChannel(
- configValue(_("LastTcfRemoteChannel")).toString());
- dlg.setRemoteArchitecture(
- configValue(_("LastTcfRemoteArchitecture")).toString());
- dlg.setServerStartScript(
- configValue(_("LastTcfServerStartScript")).toString());
- dlg.setUseServerStartScript(
- configValue(_("LastTcfUseServerStartScript")).toBool());
- if (dlg.exec() != QDialog::Accepted)
- return;
- setConfigValue(_("LastTcfRemoteChannel"), dlg.remoteChannel());
- setConfigValue(_("LastTcfRemoteArchitecture"), dlg.remoteArchitecture());
- setConfigValue(_("LastTcfServerStartScript"), dlg.serverStartScript());
- setConfigValue(_("LastTcfUseServerStartScript"), dlg.useServerStartScript());
- sp.remoteChannel = dlg.remoteChannel();
- sp.remoteArchitecture = dlg.remoteArchitecture();
- sp.serverStartScript = dlg.serverStartScript();
- sp.startMode = AttachTcf;
- if (dlg.useServerStartScript())
- sp.serverStartScript = dlg.serverStartScript();
- if (RunControl *rc = createDebugger(sp))
- startDebugger(rc);
-}
+ m_startIcon = QIcon(_(":/debugger/images/debugger_start_small.png"));
+ m_startIcon.addFile(__(":/debugger/images/debugger_start.png"));
+ m_exitIcon = QIcon(_(":/debugger/images/debugger_stop_small.png"));
+ m_exitIcon.addFile(__(":/debugger/images/debugger_stop.png"));
+ m_continueIcon = QIcon(__(":/debugger/images/debugger_continue_small.png"));
+ m_continueIcon.addFile(__(":/debugger/images/debugger_continue.png"));
+ m_interruptIcon = QIcon(_(":/debugger/images/debugger_interrupt_small.png"));
+ m_interruptIcon.addFile(__(":/debugger/images/debugger_interrupt.png"));
+ m_locationMarkIcon = QIcon(_(":/debugger/images/location_16.png"));
+
+ m_busy = false;
+
+ m_statusLabel = new QLabel;
+ m_statusLabel->setMinimumSize(QSize(30, 10));
+
+ m_breakHandler = new BreakHandler;
+ m_breakWindow = new BreakWindow;
+ m_breakWindow->setObjectName(QLatin1String("CppDebugBreakpoints"));
+ m_breakWindow->setModel(m_breakHandler->model());
+
+ //m_consoleWindow = new ConsoleWindow;
+ //m_consoleWindow->setObjectName(QLatin1String("CppDebugConsole"));
+ m_modulesWindow = new ModulesWindow;
+ m_modulesWindow->setObjectName(QLatin1String("CppDebugModules"));
+ m_logWindow = new LogWindow;
+ m_logWindow->setObjectName(QLatin1String("CppDebugOutput"));
+
+ m_registerWindow = new RegisterWindow;
+ m_registerWindow->setObjectName(QLatin1String("CppDebugRegisters"));
+ m_stackWindow = new StackWindow;
+ m_stackWindow->setObjectName(QLatin1String("CppDebugStack"));
+ m_sourceFilesWindow = new SourceFilesWindow;
+ m_sourceFilesWindow->setObjectName(QLatin1String("CppDebugSources"));
+ m_threadsWindow = new ThreadsWindow;
+ m_threadsWindow->setObjectName(QLatin1String("CppDebugThreads"));
+ m_returnWindow = new WatchWindow(WatchWindow::ReturnType);
+ m_returnWindow->setObjectName(QLatin1String("CppDebugReturn"));
+ m_localsWindow = new WatchWindow(WatchWindow::LocalsType);
+ m_localsWindow->setObjectName(QLatin1String("CppDebugLocals"));
+ m_watchersWindow = new WatchWindow(WatchWindow::WatchersType);
+ m_watchersWindow->setObjectName(QLatin1String("CppDebugWatchers"));
+ m_scriptConsoleWindow = new ScriptConsole;
+ m_scriptConsoleWindow->setWindowTitle(tr("QML Script Console"));
+ m_scriptConsoleWindow->setObjectName(QLatin1String("QMLScriptConsole"));
+ connect(m_scriptConsoleWindow, SIGNAL(expressionEntered(QString)),
+ SLOT(scriptExpressionEntered(QString)));
-bool DebuggerPluginPrivate::attachCmdLine()
-{
- if (m_attachRemoteParameters.attachPid) {
- showStatusMessage(tr("Attaching to PID %1.")
- .arg(m_attachRemoteParameters.attachPid));
- const QString crashParameter = m_attachRemoteParameters.winCrashEvent
- ? QString::number(m_attachRemoteParameters.winCrashEvent) : QString();
- attachExternalApplication(m_attachRemoteParameters.attachPid,
- QString(), crashParameter);
- return true;
- }
- const QString target = m_attachRemoteParameters.attachTarget;
- if (target.isEmpty())
- return false;
- if (target.indexOf(':') > 0) {
- showStatusMessage(tr("Attaching to remote server %1.").arg(target));
- attachRemote(target);
- } else {
- showStatusMessage(tr("Attaching to core %1.").arg(target));
- attachCore(target, QString());
- }
- return true;
-}
+ // Snapshot
+ m_snapshotHandler = new SnapshotHandler;
+ m_snapshotWindow = new SnapshotWindow(m_snapshotHandler);
+ m_snapshotWindow->setObjectName(QLatin1String("CppDebugSnapshots"));
+ m_snapshotWindow->setModel(m_snapshotHandler->model());
-void DebuggerPluginPrivate::editorOpened(Core::IEditor *editor)
-{
- if (!isDebuggable(editor))
- return;
- ITextEditor *textEditor = qobject_cast<ITextEditor *>(editor);
- if (!textEditor)
- return;
- connect(textEditor,
- SIGNAL(markRequested(TextEditor::ITextEditor*,int)),
- SLOT(requestMark(TextEditor::ITextEditor*,int)));
- connect(editor,
- SIGNAL(tooltipRequested(TextEditor::ITextEditor*,QPoint,int)),
- SLOT(showToolTip(TextEditor::ITextEditor*,QPoint,int)));
- connect(textEditor,
- SIGNAL(markContextMenuRequested(TextEditor::ITextEditor*,int,QMenu*)),
- SLOT(requestContextMenu(TextEditor::ITextEditor*,int,QMenu*)));
-}
+ // Debug mode setup
+ m_debugMode = new DebugMode(this);
-void DebuggerPluginPrivate::editorAboutToClose(Core::IEditor *editor)
-{
- if (!isDebuggable(editor))
- return;
- ITextEditor *textEditor = qobject_cast<ITextEditor *>(editor);
- if (!textEditor)
- return;
- disconnect(textEditor,
- SIGNAL(markRequested(TextEditor::ITextEditor*,int)),
- this, SLOT(requestMark(TextEditor::ITextEditor*,int)));
- disconnect(editor,
- SIGNAL(tooltipRequested(TextEditor::ITextEditor*,QPoint,int)),
- this, SLOT(showToolTip(TextEditor::ITextEditor*,QPoint,int)));
- disconnect(textEditor,
- SIGNAL(markContextMenuRequested(TextEditor::ITextEditor*,int,QMenu*)),
- this, SLOT(requestContextMenu(TextEditor::ITextEditor*,int,QMenu*)));
-}
+ // Watchers
+ connect(m_localsWindow->header(), SIGNAL(sectionResized(int,int,int)),
+ SLOT(updateWatchersHeader(int,int,int)), Qt::QueuedConnection);
-void DebuggerPluginPrivate::requestContextMenu(TextEditor::ITextEditor *editor,
- int lineNumber, QMenu *menu)
-{
- if (!isDebuggable(editor))
- return;
+ QAction *act = 0;
- BreakpointId id = BreakpointId();
- QString fileName;
- quint64 address = 0;
+ act = m_actions.continueAction = new QAction(tr("Continue"), this);
+ act->setIcon(m_continueIcon);
+ connect(act, SIGNAL(triggered()), SLOT(handleExecContinue()));
- if (editor->property("DisassemblerView").toBool()) {
- fileName = editor->file()->fileName();
- QString line = editor->contents()
- .section('\n', lineNumber - 1, lineNumber - 1);
- BreakpointResponse needle;
- needle.type = BreakpointByAddress;
- needle.address = DisassemblerViewAgent::addressFromDisassemblyLine(line);
- address = needle.address;
- needle.lineNumber = -1;
- id = breakHandler()->findSimilarBreakpoint(needle);
- } else {
- fileName = editor->file()->fileName();
- id = breakHandler()->findBreakpointByFileAndLine(fileName, lineNumber);
- }
+ act = m_actions.exitAction = new QAction(tr("Exit Debugger"), this);
+ act->setIcon(m_exitIcon);
+ connect(act, SIGNAL(triggered()), SLOT(handleExecExit()));
- QList<QVariant> args;
- args.append(fileName);
- args.append(lineNumber);
- args.append(address);
+ act = m_actions.interruptAction = new QAction(tr("Interrupt"), this);
+ act->setIcon(m_interruptIcon);
+ connect(act, SIGNAL(triggered()), SLOT(handleExecInterrupt()));
- if (id) {
- // Remove existing breakpoint.
- QAction *act = new QAction(menu);
- act->setData(int(id));
- act->setText(tr("Remove Breakpoint %1").arg(id));
- connect(act, SIGNAL(triggered()),
- SLOT(breakpointRemoveMarginActionTriggered()));
- menu->addAction(act);
+ // A "disabled pause" seems to be a good choice.
+ act = m_actions.undisturbableAction = new QAction(tr("Debugger is Busy"), this);
+ act->setIcon(m_interruptIcon);
+ act->setEnabled(false);
- // Enable/disable existing breakpoint.
- act = new QAction(menu);
- act->setData(int(id));
- if (breakHandler()->isEnabled(id)) {
- act->setText(tr("Disable Breakpoint %1").arg(id));
- connect(act, SIGNAL(triggered()),
- SLOT(breakpointDisableMarginActionTriggered()));
- } else {
- act->setText(tr("Enable Breakpoint %1").arg(id));
- connect(act, SIGNAL(triggered()),
- SLOT(breakpointEnableMarginActionTriggered()));
- }
- menu->addAction(act);
+ act = m_actions.resetAction = new QAction(tr("Abort Debugging"), this);
+ act->setToolTip(tr("Aborts debugging and "
+ "resets the debugger to the initial state."));
+ connect(act, SIGNAL(triggered()), SLOT(handleExecReset()));
- // Edit existing breakpoint.
- act = new QAction(menu);
- act->setText(tr("Edit Breakpoint %1...").arg(id));
- connect(act, SIGNAL(triggered()), SLOT(slotEditBreakpoint()));
- act->setData(int(id));
- menu->addAction(act);
- } else {
- // Handle non-existing breakpoint.
- const QString text = address ?
- tr("Set Breakpoint at 0x%1").arg(address, 0, 16) :
- tr("Set Breakpoint at line %1").arg(lineNumber);
- QAction *act = new QAction(text, menu);
- act->setData(args);
- connect(act, SIGNAL(triggered()),
- SLOT(breakpointSetMarginActionTriggered()));
- menu->addAction(act);
- }
- // Run to, jump to line below in stopped state.
- if (state() == InferiorStopOk) {
- menu->addSeparator();
- const QString runText =
- DebuggerEngine::tr("Run to Line %1").arg(lineNumber);
- QAction *runToLineAction = new QAction(runText, menu);
- runToLineAction->setData(args);
- connect(runToLineAction, SIGNAL(triggered()), SLOT(slotRunToLine()));
- menu->addAction(runToLineAction);
- if (currentEngine()->debuggerCapabilities() & JumpToLineCapability) {
- const QString jumpText =
- DebuggerEngine::tr("Jump to Line %1").arg(lineNumber);
- QAction *jumpToLineAction = new QAction(jumpText, menu);
- menu->addAction(runToLineAction);
- jumpToLineAction->setData(args);
- connect(jumpToLineAction, SIGNAL(triggered()), SLOT(slotJumpToLine()));
- menu->addAction(jumpToLineAction);
- }
- }
-}
+ act = m_actions.nextAction = new QAction(tr("Step Over"), this);
+ act->setIcon(QIcon(__(":/debugger/images/debugger_stepover_small.png")));
+ connect(act, SIGNAL(triggered()), SLOT(handleExecNext()));
-void DebuggerPluginPrivate::toggleBreakpoint()
-{
- ITextEditor *textEditor = currentTextEditor();
- QTC_ASSERT(textEditor, return);
- const int lineNumber = textEditor->currentLine();
- if (textEditor->property("DisassemblerView").toBool()) {
- QString line = textEditor->contents()
- .section('\n', lineNumber - 1, lineNumber - 1);
- quint64 address = DisassemblerViewAgent::addressFromDisassemblyLine(line);
- toggleBreakpointByAddress(address);
- } else if (lineNumber >= 0) {
- toggleBreakpointByFileAndLine(textEditor->file()->fileName(), lineNumber);
- }
-}
+ act = m_actions.stepAction = new QAction(tr("Step Into"), this);
+ act->setIcon(QIcon(__(":/debugger/images/debugger_stepinto_small.png")));
+ connect(act, SIGNAL(triggered()), SLOT(handleExecStep()));
-void DebuggerPluginPrivate::toggleBreakpointByFileAndLine(const QString &fileName,
- int lineNumber)
-{
- BreakHandler *handler = m_breakHandler;
- BreakpointId id =
- handler->findBreakpointByFileAndLine(fileName, lineNumber, true);
- if (!id)
- id = handler->findBreakpointByFileAndLine(fileName, lineNumber, false);
+ act = m_actions.stepOutAction = new QAction(tr("Step Out"), this);
+ act->setIcon(QIcon(__(":/debugger/images/debugger_stepout_small.png")));
+ connect(act, SIGNAL(triggered()), SLOT(handleExecStepOut()));
- if (id) {
- handler->removeBreakpoint(id);
- } else {
- BreakpointParameters data(BreakpointByFileAndLine);
- data.fileName = fileName;
- data.lineNumber = lineNumber;
- handler->appendBreakpoint(data);
- }
- synchronizeBreakpoints();
-}
+ act = m_actions.runToLineAction = new QAction(tr("Run to Line"), this);
+ connect(act, SIGNAL(triggered()), SLOT(handleExecRunToLine()));
-void DebuggerPluginPrivate::toggleBreakpointByAddress(quint64 address)
-{
- BreakHandler *handler = m_breakHandler;
- BreakpointId id = handler->findBreakpointByAddress(address);
+ act = m_actions.runToFunctionAction =
+ new QAction(tr("Run to Outermost Function"), this);
+ connect(act, SIGNAL(triggered()), SLOT(handleExecRunToFunction()));
- if (id) {
- handler->removeBreakpoint(id);
- } else {
- BreakpointParameters data(BreakpointByAddress);
- data.address = address;
- handler->appendBreakpoint(data);
- }
- synchronizeBreakpoints();
-}
+ act = m_actions.returnFromFunctionAction =
+ new QAction(tr("Immediately Return From Inner Function"), this);
+ connect(act, SIGNAL(triggered()), SLOT(handleExecReturn()));
+
+ act = m_actions.jumpToLineAction = new QAction(tr("Jump to Line"), this);
+ connect(act, SIGNAL(triggered()), SLOT(handleExecJumpToLine()));
+
+ act = m_actions.breakAction = new QAction(tr("Toggle Breakpoint"), this);
+
+ act = m_actions.watchAction1 = new QAction(tr("Add to Watch Window"), this);
+ connect(act, SIGNAL(triggered()), SLOT(handleAddToWatchWindow()));
+
+ act = m_actions.watchAction2 = new QAction(tr("Add to Watch Window"), this);
+ connect(act, SIGNAL(triggered()), SLOT(handleAddToWatchWindow()));
+
+ //m_actions.snapshotAction = new QAction(tr("Create Snapshot"), this);
+ //m_actions.snapshotAction->setProperty(Role, RequestCreateSnapshotRole);
+ //m_actions.snapshotAction->setIcon(
+ // QIcon(__(":/debugger/images/debugger_snapshot_small.png")));
+
+ act = m_actions.reverseDirectionAction =
+ new QAction(tr("Reverse Direction"), this);
+ act->setCheckable(true);
+ act->setChecked(false);
+ act->setCheckable(false);
+ act->setIcon(QIcon(__(":/debugger/images/debugger_reversemode_16.png")));
+ act->setIconVisibleInMenu(false);
-void DebuggerPluginPrivate::requestMark(ITextEditor *editor, int lineNumber)
-{
- if (editor->property("DisassemblerView").toBool()) {
- QString line = editor->contents()
- .section('\n', lineNumber - 1, lineNumber - 1);
- quint64 address = DisassemblerViewAgent::addressFromDisassemblyLine(line);
- toggleBreakpointByAddress(address);
- } else if (editor->file()) {
- toggleBreakpointByFileAndLine(editor->file()->fileName(), lineNumber);
- }
-}
+ act = m_actions.frameDownAction = new QAction(tr("Move to Called Frame"), this);
+ connect(act, SIGNAL(triggered()), SLOT(handleFrameDown()));
-void DebuggerPluginPrivate::showToolTip(ITextEditor *editor,
- const QPoint &point, int pos)
-{
- if (!isDebuggable(editor))
- return;
- if (!boolSetting(UseToolTipsInMainEditor))
- return;
- if (state() != InferiorStopOk)
- return;
- currentEngine()->setToolTipExpression(point, editor, pos);
-}
+ act = m_actions.frameUpAction = new QAction(tr("Move to Calling Frame"), this);
+ connect(act, SIGNAL(triggered()), SLOT(handleFrameUp()));
-DebuggerRunControl *DebuggerPluginPrivate::createDebugger
- (const DebuggerStartParameters &sp, RunConfiguration *rc)
-{
- return m_debuggerRunControlFactory->create(sp, rc);
-}
+ connect(action(OperateByInstruction), SIGNAL(triggered(bool)),
+ SLOT(handleOperateByInstructionTriggered(bool)));
-// If updateEngine is set, the engine will update its threads/modules and so forth.
-void DebuggerPluginPrivate::displayDebugger(DebuggerEngine *engine, bool updateEngine)
-{
- QTC_ASSERT(engine, return);
- disconnectEngine();
- connectEngine(engine);
- if (updateEngine)
- engine->updateAll();
- engine->updateViews();
-}
+ connect(&m_statusTimer, SIGNAL(timeout()), SLOT(clearStatusMessage()));
-void DebuggerPluginPrivate::startDebugger(RunControl *rc)
-{
- QTC_ASSERT(rc, return);
- ProjectExplorerPlugin::instance()->startRunControl(rc, Constants::DEBUGMODE);
-}
+ connect(action(ExecuteCommand), SIGNAL(triggered()),
+ SLOT(executeDebuggerCommand()));
+ // Cpp/Qml ui setup
+ m_uiSwitcher = new DebuggerUISwitcher(m_debugMode, this);
+ ExtensionSystem::PluginManager::instance()->addObject(m_uiSwitcher);
+ m_uiSwitcher->addLanguage(CppLanguage, cppDebuggercontext);
+ m_uiSwitcher->addLanguage(QmlLanguage, qmlDebuggerContext);
+ m_uiSwitcher->initialize(m_coreSettings);
-void DebuggerPluginPrivate::connectEngine(DebuggerEngine *engine)
-{
- if (!engine)
- engine = dummyEngine();
+ readSettings();
- if (m_currentEngine == engine)
- return;
+ // Dock widgets
+ m_breakDock = m_uiSwitcher->createDockWidget(CppLanguage, m_breakWindow);
+ m_breakDock->setObjectName(QString(DOCKWIDGET_BREAK));
- m_currentEngine = engine;
+ //m_consoleDock = m_uiSwitcher->createDockWidget(CppLanguage, m_consoleWindow,
+ // Qt::TopDockWidgetArea);
+ //m_consoleDock->setObjectName(QString(DOCKWIDGET_OUTPUT));
- m_localsWindow->setModel(engine->localsModel());
- m_modulesWindow->setModel(engine->modulesModel());
- m_registerWindow->setModel(engine->registerModel());
- m_returnWindow->setModel(engine->returnModel());
- m_sourceFilesWindow->setModel(engine->sourceFilesModel());
- m_stackWindow->setModel(engine->stackModel());
- m_threadsWindow->setModel(engine->threadsModel());
- m_threadBox->setModel(engine->threadsModel());
- m_threadBox->setModelColumn(ThreadData::NameColumn);
- m_watchersWindow->setModel(engine->watchersModel());
-}
+ m_modulesDock = m_uiSwitcher->createDockWidget(CppLanguage, m_modulesWindow,
+ Qt::TopDockWidgetArea);
+ m_modulesDock->setObjectName(QString(DOCKWIDGET_MODULES));
+ connect(m_modulesDock->toggleViewAction(), SIGNAL(toggled(bool)),
+ SLOT(modulesDockToggled(bool)), Qt::QueuedConnection);
-static void changeFontSize(QWidget *widget, qreal size)
-{
- QFont font = widget->font();
- font.setPointSizeF(size);
- widget->setFont(font);
-}
+ m_registerDock = m_uiSwitcher->createDockWidget(CppLanguage, m_registerWindow,
+ Qt::TopDockWidgetArea);
+ m_registerDock->setObjectName(QString(DOCKWIDGET_REGISTER));
+ connect(m_registerDock->toggleViewAction(), SIGNAL(toggled(bool)),
+ SLOT(registerDockToggled(bool)), Qt::QueuedConnection);
-void DebuggerPluginPrivate::fontSettingsChanged
- (const TextEditor::FontSettings &settings)
-{
- qreal size = settings.fontZoom() * settings.fontSize() / 100.;
- changeFontSize(m_breakWindow, size);
- changeFontSize(m_logWindow, size);
- changeFontSize(m_localsWindow, size);
- changeFontSize(m_modulesWindow, size);
- //changeFontSize(m_consoleWindow, size);
- changeFontSize(m_registerWindow, size);
- changeFontSize(m_returnWindow, size);
- changeFontSize(m_sourceFilesWindow, size);
- changeFontSize(m_stackWindow, size);
- changeFontSize(m_threadsWindow, size);
- changeFontSize(m_watchersWindow, size);
-}
+ m_outputDock = m_uiSwitcher->createDockWidget(AnyLanguage, m_logWindow,
+ Qt::TopDockWidgetArea);
+ m_outputDock->setObjectName(QString(DOCKWIDGET_OUTPUT));
-void DebuggerPluginPrivate::cleanupViews()
-{
- m_actions.reverseDirectionAction->setChecked(false);
- m_actions.reverseDirectionAction->setEnabled(false);
- hideDebuggerToolTip();
+ m_snapshotDock = m_uiSwitcher->createDockWidget(CppLanguage, m_snapshotWindow);
+ m_snapshotDock->setObjectName(QString(DOCKWIDGET_SNAPSHOTS));
- if (!boolSetting(CloseBuffersOnExit))
- return;
+ m_stackDock = m_uiSwitcher->createDockWidget(CppLanguage, m_stackWindow);
+ m_stackDock->setObjectName(QString(DOCKWIDGET_STACK));
- EditorManager *editorManager = EditorManager::instance();
- QTC_ASSERT(editorManager, return);
- QList<IEditor *> toClose;
- foreach (IEditor *editor, editorManager->openedEditors()) {
- if (editor->property(Constants::OPENED_BY_DEBUGGER).toBool()) {
- // Close disassembly views. Close other opened files
- // if they are not modified and not current editor.
- if (editor->property(Constants::OPENED_WITH_DISASSEMBLY).toBool()
- || (!editor->file()->isModified()
- && editor != editorManager->currentEditor())) {
- toClose.append(editor);
- } else {
- editor->setProperty(Constants::OPENED_BY_DEBUGGER, false);
- }
- }
- }
- editorManager->closeEditors(toClose);
-}
+ m_sourceFilesDock = m_uiSwitcher->createDockWidget(CppLanguage,
+ m_sourceFilesWindow, Qt::TopDockWidgetArea);
+ m_sourceFilesDock->setObjectName(QString(DOCKWIDGET_SOURCE_FILES));
+ connect(m_sourceFilesDock->toggleViewAction(), SIGNAL(toggled(bool)),
+ SLOT(sourceFilesDockToggled(bool)), Qt::QueuedConnection);
-void DebuggerPluginPrivate::setBusyCursor(bool busy)
-{
- //STATE_DEBUG("BUSY FROM: " << m_busy << " TO: " << busy);
- if (busy == m_busy)
- return;
- m_busy = busy;
- QCursor cursor(busy ? Qt::BusyCursor : Qt::ArrowCursor);
- m_breakWindow->setCursor(cursor);
- //m_consoleWindow->setCursor(cursor);
- m_localsWindow->setCursor(cursor);
- m_modulesWindow->setCursor(cursor);
- m_logWindow->setCursor(cursor);
- m_registerWindow->setCursor(cursor);
- m_returnWindow->setCursor(cursor);
- m_sourceFilesWindow->setCursor(cursor);
- m_stackWindow->setCursor(cursor);
- m_threadsWindow->setCursor(cursor);
- m_watchersWindow->setCursor(cursor);
- m_snapshotWindow->setCursor(cursor);
- m_scriptConsoleWindow->setCursor(cursor);
-}
+ m_threadsDock = m_uiSwitcher->createDockWidget(CppLanguage, m_threadsWindow);
+ m_threadsDock->setObjectName(QString(DOCKWIDGET_THREADS));
-void DebuggerPluginPrivate::setSimpleDockWidgetArrangement
- (Debugger::DebuggerLanguages activeLanguages)
-{
- DebuggerMainWindow *mw = debuggerMainWindow();
- QTC_ASSERT(mw, return);
- mw->setTrackingEnabled(false);
+ QSplitter *localsAndWatchers = new Core::MiniSplitter(Qt::Vertical);
+ localsAndWatchers->setObjectName(QLatin1String("CppDebugLocalsAndWatchers"));
+ localsAndWatchers->setWindowTitle(m_localsWindow->windowTitle());
+ localsAndWatchers->addWidget(m_localsWindow);
+ localsAndWatchers->addWidget(m_returnWindow);
+ localsAndWatchers->addWidget(m_watchersWindow);
+ localsAndWatchers->setStretchFactor(0, 3);
+ localsAndWatchers->setStretchFactor(1, 1);
+ localsAndWatchers->setStretchFactor(2, 1);
- QList<QDockWidget *> dockWidgets = mw->dockWidgets();
- foreach (QDockWidget *dockWidget, dockWidgets) {
- dockWidget->setFloating(false);
- mw->removeDockWidget(dockWidget);
- }
+ m_watchDock = m_uiSwitcher->createDockWidget(CppLanguage, localsAndWatchers);
+ m_watchDock->setObjectName(QString(DOCKWIDGET_WATCHERS));
- foreach (QDockWidget *dockWidget, dockWidgets) {
- if (dockWidget == m_outputDock /*|| dockWidget == m_consoleDock*/) {
- mw->addDockWidget(Qt::TopDockWidgetArea, dockWidget);
- } else {
- mw->addDockWidget(Qt::BottomDockWidgetArea, dockWidget);
- }
- dockWidget->hide();
- }
+ m_scriptConsoleDock =
+ m_uiSwitcher->createDockWidget(QmlLanguage, m_scriptConsoleWindow);
+ m_scriptConsoleDock->setObjectName(QString(DOCKWIDGET_QML_SCRIPTCONSOLE));
- if ((activeLanguages.testFlag(CppLanguage)
- && !activeLanguages.testFlag(QmlLanguage))
- || activeLanguages == AnyLanguage) {
- m_stackDock->show();
- m_breakDock->show();
- m_watchDock->show();
- m_threadsDock->show();
- m_snapshotDock->show();
- } else {
- m_stackDock->show();
- m_breakDock->show();
- m_watchDock->show();
- m_scriptConsoleDock->show();
- if (m_uiSwitcher->qmlInspectorWindow())
- m_uiSwitcher->qmlInspectorWindow()->show();
- }
- mw->splitDockWidget(mw->toolBarDockWidget(), m_stackDock, Qt::Vertical);
- mw->splitDockWidget(m_stackDock, m_watchDock, Qt::Horizontal);
- mw->tabifyDockWidget(m_watchDock, m_breakDock);
- mw->tabifyDockWidget(m_watchDock, m_modulesDock);
- mw->tabifyDockWidget(m_watchDock, m_registerDock);
- mw->tabifyDockWidget(m_watchDock, m_threadsDock);
- mw->tabifyDockWidget(m_watchDock, m_sourceFilesDock);
- mw->tabifyDockWidget(m_watchDock, m_snapshotDock);
- mw->tabifyDockWidget(m_watchDock, m_scriptConsoleDock);
- if (m_uiSwitcher->qmlInspectorWindow())
- mw->tabifyDockWidget(m_watchDock, m_uiSwitcher->qmlInspectorWindow());
+ // Register factory of DebuggerRunControl.
+ m_debuggerRunControlFactory = new DebuggerRunControlFactory
+ (m_plugin, DebuggerEngineType(m_cmdLineEnabledEngines));
+ m_plugin->addAutoReleasedObject(m_debuggerRunControlFactory);
- mw->setTrackingEnabled(true);
-}
+ m_debugMode->setContext(
+ Context(CC::C_EDITORMANAGER, C_DEBUGMODE, CC::C_NAVIGATION_PANE));
-void DebuggerPluginPrivate::setInitialState()
-{
- m_watchersWindow->setVisible(false);
- m_returnWindow->setVisible(false);
- setBusyCursor(false);
- m_actions.reverseDirectionAction->setChecked(false);
- m_actions.reverseDirectionAction->setEnabled(false);
- hideDebuggerToolTip();
+ m_reverseToolButton = 0;
+
+ // debug action
+ act = m_debugAction = new QAction(this);
+ QIcon debuggerIcon(":/projectexplorer/images/debugger_start_small.png");
+ debuggerIcon.addFile(":/projectexplorer/images/debugger_start.png");
+ act->setIcon(debuggerIcon);
+ act->setText(tr("Start Debugging"));
+ connect(act, SIGNAL(triggered()), this, SLOT(debugProject()));
- m_startExternalAction->setEnabled(true);
- m_attachExternalAction->setEnabled(true);
-#ifdef Q_OS_WIN
- m_attachCoreAction->setEnabled(false);
-#else
- m_attachCoreAction->setEnabled(true);
-#endif
- m_startRemoteAction->setEnabled(true);
- m_detachAction->setEnabled(false);
+ // Handling of external applications.
+ act = m_startExternalAction = new QAction(this);
+ act->setText(tr("Start and Debug External Application..."));
+ connect(act, SIGNAL(triggered()), SLOT(startExternalApplication()));
- m_actions.watchAction1->setEnabled(true);
- m_actions.watchAction2->setEnabled(true);
- m_actions.breakAction->setEnabled(true);
- //m_actions.snapshotAction->setEnabled(false);
- action(OperateByInstruction)->setEnabled(false);
+ act = m_startRemoteLldbAction = new QAction(this);
+ act->setText(tr("Start and Debug External Application with External Engine..."));
+ connect(act, SIGNAL(triggered()), SLOT(startRemoteEngine()));
- m_actions.exitAction->setEnabled(false);
- m_actions.resetAction->setEnabled(false);
+ act = m_attachExternalAction = new QAction(this);
+ act->setText(tr("Attach to Running External Application..."));
+ connect(act, SIGNAL(triggered()), SLOT(attachExternalApplication()));
- m_actions.stepAction->setEnabled(false);
- m_actions.stepOutAction->setEnabled(false);
- m_actions.runToLineAction->setEnabled(false);
- m_actions.runToFunctionAction->setEnabled(false);
- m_actions.returnFromFunctionAction->setEnabled(false);
- m_actions.jumpToLineAction->setEnabled(false);
- m_actions.nextAction->setEnabled(false);
+ act = m_attachCoreAction = new QAction(this);
+ act->setText(tr("Attach to Core..."));
+ connect(act, SIGNAL(triggered()), SLOT(attachCore()));
- action(AutoDerefPointers)->setEnabled(true);
- action(ExpandStack)->setEnabled(false);
- action(ExecuteCommand)->setEnabled(m_state == InferiorStopOk);
+ act = m_attachTcfAction = new QAction(this);
+ act->setText(tr("Attach to Running Tcf Agent..."));
+ act->setToolTip(tr("This attaches to a running "
+ "'Target Communication Framework' agent."));
+ connect(act, SIGNAL(triggered()), SLOT(attachRemoteTcf()));
- m_scriptConsoleWindow->setEnabled(false);
+ act = m_startRemoteAction = new QAction(this);
+ act->setText(tr("Start and Attach to Remote Application..."));
+ connect(act, SIGNAL(triggered()), SLOT(startRemoteApplication()));
- //emit m_plugin->stateChanged(m_state);
-}
+#ifdef Q_OS_WIN
+ m_startRemoteCdbAction = new QAction(tr("Attach to Remote CDB Session..."), this);
+ connect(m_startRemoteCdbAction, SIGNAL(triggered()), SLOT(startRemoteCdbSession()));
+#endif
-void DebuggerPluginPrivate::updateWatchersWindow()
-{
- m_watchersWindow->setVisible(
- m_watchersWindow->model()->rowCount(QModelIndex()) > 0);
- m_returnWindow->setVisible(
- m_returnWindow->model()->rowCount(QModelIndex()) > 0);
-}
+ act = m_detachAction = new QAction(this);
+ act->setText(tr("Detach Debugger"));
+ connect(act, SIGNAL(triggered()), SLOT(handleExecDetach()));
-void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
-{
- QTC_ASSERT(engine, return);
- QTC_ASSERT(m_watchersWindow->model(), return);
- QTC_ASSERT(m_returnWindow->model(), return);
- QTC_ASSERT(!engine->isSlaveEngine(), return);
+ Core::Command *cmd = 0;
- m_threadBox->setCurrentIndex(engine->threadsHandler()->currentThread());
+ Core::ActionContainer *mstart =
+ am->actionContainer(PE::M_DEBUG_STARTDEBUGGING);
- updateWatchersWindow();
+ cmd = am->registerAction(m_debugAction, Constants::DEBUG, globalcontext);
+ cmd->setAttribute(Core::Command::CA_UpdateText);
+ cmd->setAttribute(Core::Command::CA_UpdateIcon);
+ cmd->setDefaultText(tr("Start Debugging"));
+ cmd->setDefaultKeySequence(QKeySequence(Constants::DEBUG_KEY));
+ mstart->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
+ Core::ICore::instance()->modeManager()->addAction(cmd, Constants::P_ACTION_DEBUG);
- //m_plugin->showMessage(QString("PLUGIN SET STATE: ")
- // + DebuggerEngine::stateName(engine->state()), LogStatus);
- //qDebug() << "PLUGIN SET STATE: " << engine->state();
+ cmd = am->registerAction(m_actions.continueAction,
+ Constants::DEBUG, m_continuableContext);
+ mstart->addAction(cmd, CC::G_DEFAULT_ONE);
- if (m_state == engine->state())
- return;
+ cmd = am->registerAction(m_startExternalAction,
+ Constants::STARTEXTERNAL, globalcontext);
+ cmd->setAttribute(Command::CA_Hide);
+ mstart->addAction(cmd, CC::G_DEFAULT_ONE);
- m_state = engine->state();
- bool actionsEnabled = DebuggerEngine::debuggerActionsEnabled(m_state);
+ cmd = am->registerAction(m_startRemoteLldbAction,
+ Constants::STARTREMOTELLDB, globalcontext);
+ cmd->setAttribute(Command::CA_Hide);
+ mstart->addAction(cmd, CC::G_DEFAULT_ONE);
- ICore *core = ICore::instance();
- ActionManager *am = core->actionManager();
- if (m_state == DebuggerNotReady) {
- QTC_ASSERT(false, /* We use the Core m_debugAction here */);
- // F5 starts debugging. It is "startable".
- m_actions.interruptAction->setEnabled(false);
- m_actions.continueAction->setEnabled(false);
- m_actions.exitAction->setEnabled(false);
- am->command(Constants::STOP)->setKeySequence(QKeySequence());
- am->command(Constants::DEBUG)->setKeySequence(QKeySequence(DEBUG_KEY));
- core->updateAdditionalContexts(m_anyContext, Context());
- } else if (m_state == InferiorStopOk) {
- // F5 continues, Shift-F5 kills. It is "continuable".
- m_actions.interruptAction->setEnabled(false);
- m_actions.continueAction->setEnabled(true);
- m_actions.exitAction->setEnabled(true);
- am->command(Constants::STOP)->setKeySequence(QKeySequence(STOP_KEY));
- am->command(Constants::DEBUG)->setKeySequence(QKeySequence(DEBUG_KEY));
- core->updateAdditionalContexts(m_anyContext, m_continuableContext);
- } else if (m_state == InferiorRunOk) {
- // Shift-F5 interrupts. It is also "interruptible".
- m_actions.interruptAction->setEnabled(true);
- m_actions.continueAction->setEnabled(false);
- m_actions.exitAction->setEnabled(false);
- am->command(Constants::STOP)->setKeySequence(QKeySequence());
- am->command(Constants::DEBUG)->setKeySequence(QKeySequence(STOP_KEY));
- core->updateAdditionalContexts(m_anyContext, m_interruptibleContext);
- } else if (m_state == DebuggerFinished) {
- // We don't want to do anything anymore.
- m_actions.interruptAction->setEnabled(false);
- m_actions.continueAction->setEnabled(false);
- m_actions.exitAction->setEnabled(false);
- am->command(Constants::STOP)->setKeySequence(QKeySequence());
- am->command(Constants::DEBUG)->setKeySequence(QKeySequence(DEBUG_KEY));
- //core->updateAdditionalContexts(m_anyContext, m_finishedContext);
- m_codeModelSnapshot = CPlusPlus::Snapshot();
- core->updateAdditionalContexts(m_anyContext, Context());
- setBusyCursor(false);
- cleanupViews();
- } else if (m_state == InferiorUnrunnable) {
- // We don't want to do anything anymore.
- m_actions.interruptAction->setEnabled(false);
- m_actions.continueAction->setEnabled(false);
- m_actions.exitAction->setEnabled(true);
- am->command(Constants::STOP)->setKeySequence(QKeySequence(STOP_KEY));
- am->command(Constants::DEBUG)->setKeySequence(QKeySequence(STOP_KEY));
- core->updateAdditionalContexts(m_anyContext, m_finishedContext);
- } else {
- // Everything else is "undisturbable".
- m_actions.interruptAction->setEnabled(false);
- m_actions.continueAction->setEnabled(false);
- m_actions.exitAction->setEnabled(false);
- am->command(Constants::STOP)->setKeySequence(QKeySequence());
- am->command(Constants::DEBUG)->setKeySequence(QKeySequence());
- core->updateAdditionalContexts(m_anyContext, m_undisturbableContext);
- }
+ cmd = am->registerAction(m_attachExternalAction,
+ Constants::ATTACHEXTERNAL, globalcontext);
+ cmd->setAttribute(Command::CA_Hide);
+ mstart->addAction(cmd, CC::G_DEFAULT_ONE);
- m_startExternalAction->setEnabled(true);
- m_attachExternalAction->setEnabled(true);
-#ifdef Q_OS_WIN
- m_attachCoreAction->setEnabled(false);
-#else
- m_attachCoreAction->setEnabled(true);
-#endif
- m_startRemoteAction->setEnabled(true);
+ cmd = am->registerAction(m_attachCoreAction,
+ Constants::ATTACHCORE, globalcontext);
- const bool isCore = engine->startParameters().startMode == AttachCore;
- const bool stopped = m_state == InferiorStopOk;
- const bool detachable = stopped && !isCore;
- m_detachAction->setEnabled(detachable);
+ cmd->setAttribute(Command::CA_Hide);
+ mstart->addAction(cmd, CC::G_DEFAULT_ONE);
- if (stopped)
- QApplication::alert(mainWindow(), 3000);
+ cmd = am->registerAction(m_attachTcfAction,
+ Constants::ATTACHTCF, globalcontext);
+ mstart->addAction(cmd, CC::G_DEFAULT_ONE);
- const uint caps = engine->debuggerCapabilities();
- const bool canReverse = (caps & ReverseSteppingCapability)
- && boolSetting(EnableReverseDebugging);
- m_actions.reverseDirectionAction->setEnabled(canReverse);
+ cmd = am->registerAction(m_startRemoteAction,
+ Constants::ATTACHREMOTE, globalcontext);
+ cmd->setAttribute(Command::CA_Hide);
+ mstart->addAction(cmd, CC::G_DEFAULT_ONE);
- m_actions.watchAction1->setEnabled(true);
- m_actions.watchAction2->setEnabled(true);
- m_actions.breakAction->setEnabled(true);
- //m_actions.snapshotAction->setEnabled(stopped && (caps & SnapshotCapability));
+ if (m_startRemoteCdbAction) {
+ cmd = am->registerAction(m_startRemoteCdbAction,
+ Constants::ATTACHREMOTECDB, globalcontext);
+ cmd->setAttribute(Command::CA_Hide);
+ mstart->addAction(cmd, CC::G_DEFAULT_ONE);
+ }
- action(OperateByInstruction)->setEnabled(stopped || isCore);
+ cmd = am->registerAction(m_detachAction,
+ Constants::DETACH, globalcontext);
+ cmd->setAttribute(Command::CA_Hide);
+ m_uiSwitcher->addMenuAction(cmd, AnyLanguage, CC::G_DEFAULT_ONE);
- m_actions.resetAction->setEnabled(m_state != DebuggerNotReady
- && m_state != DebuggerFinished);
+ cmd = am->registerAction(m_actions.exitAction,
+ Constants::STOP, globalcontext);
+ //cmd->setDefaultKeySequence(QKeySequence(Constants::STOP_KEY));
+ cmd->setDefaultText(tr("Stop Debugger"));
+ m_uiSwitcher->addMenuAction(cmd, AnyLanguage, CC::G_DEFAULT_ONE);
- m_actions.stepAction->setEnabled(stopped);
- m_actions.stepOutAction->setEnabled(stopped);
- m_actions.runToLineAction->setEnabled(stopped);
- m_actions.runToFunctionAction->setEnabled(stopped);
- m_actions.returnFromFunctionAction->
- setEnabled(stopped && (caps & ReturnFromFunctionCapability));
+ cmd = am->registerAction(m_actions.interruptAction,
+ Constants::DEBUG, m_interruptibleContext);
+ cmd->setDefaultText(tr("Interrupt Debugger"));
- const bool canJump = stopped && (caps & JumpToLineCapability);
- m_actions.jumpToLineAction->setEnabled(canJump);
+ cmd = am->registerAction(m_actions.undisturbableAction,
+ Constants::DEBUG, m_undisturbableContext);
+ cmd->setDefaultText(tr("Debugger is Busy"));
- m_actions.nextAction->setEnabled(stopped);
+ cmd = am->registerAction(m_actions.resetAction,
+ Constants::RESET, globalcontext);
+ //cmd->setDefaultKeySequence(QKeySequence(Constants::RESET_KEY));
+ cmd->setDefaultText(tr("Reset Debugger"));
+ m_uiSwitcher->addMenuAction(cmd, AnyLanguage, CC::G_DEFAULT_ONE);
- const bool canDeref = actionsEnabled && (caps & AutoDerefPointersCapability);
- action(AutoDerefPointers)->setEnabled(canDeref);
- action(AutoDerefPointers)->setEnabled(true);
- action(ExpandStack)->setEnabled(actionsEnabled);
- action(ExecuteCommand)->setEnabled(m_state == InferiorStopOk);
+ QAction *sep = new QAction(this);
+ sep->setSeparator(true);
+ cmd = am->registerAction(sep, _("Debugger.Sep.Step"), globalcontext);
+ m_uiSwitcher->addMenuAction(cmd, CppLanguage);
- const bool notbusy = m_state == InferiorStopOk
- || m_state == DebuggerNotReady
- || m_state == DebuggerFinished
- || m_state == InferiorUnrunnable;
- setBusyCursor(!notbusy);
+ cmd = am->registerAction(m_actions.nextAction,
+ Constants::NEXT, cppDebuggercontext);
+ cmd->setDefaultKeySequence(QKeySequence(Constants::NEXT_KEY));
+ cmd->setAttribute(Command::CA_Hide);
+ m_uiSwitcher->addMenuAction(cmd, CppLanguage);
- m_scriptConsoleWindow->setEnabled(stopped);
-}
+ cmd = am->registerAction(m_actions.stepAction,
+ Constants::STEP, cppDebuggercontext);
+ cmd->setDefaultKeySequence(QKeySequence(Constants::STEP_KEY));
+ cmd->setAttribute(Command::CA_Hide);
+ m_uiSwitcher->addMenuAction(cmd, CppLanguage);
-void DebuggerPluginPrivate::updateDebugActions()
-{
- ProjectExplorerPlugin *pe = ProjectExplorerPlugin::instance();
- Project *project = pe->startupProject();
- m_debugAction->setEnabled(pe->canRun(project, Constants::DEBUGMODE));
-}
-void DebuggerPluginPrivate::gotoLocation(const QString &file, int line, bool setMarker)
-{
- // CDB might hit on breakpoints while shutting down.
- if (m_shuttingDown)
- return;
+ cmd = am->registerAction(m_actions.stepOutAction,
+ Constants::STEPOUT, cppDebuggercontext);
+ cmd->setDefaultKeySequence(QKeySequence(Constants::STEPOUT_KEY));
+ cmd->setAttribute(Command::CA_Hide);
+ m_uiSwitcher->addMenuAction(cmd, CppLanguage);
- doRemoveLocationMark();
- bool newEditor = false;
- ITextEditor *editor =
- BaseTextEditor::openEditorAt(file, line, 0, QString(),
- EditorManager::IgnoreNavigationHistory, &newEditor);
- if (!editor)
- return;
- if (newEditor)
- editor->setProperty(Debugger::Constants::OPENED_BY_DEBUGGER, true);
- if (setMarker)
- m_locationMark.reset(new LocationMark(file, line));
-}
+ cmd = am->registerAction(m_actions.runToLineAction,
+ Constants::RUN_TO_LINE1, cppDebuggercontext);
+ cmd->setDefaultKeySequence(QKeySequence(Constants::RUN_TO_LINE_KEY));
+ cmd->setAttribute(Command::CA_Hide);
+ m_uiSwitcher->addMenuAction(cmd, CppLanguage);
-void DebuggerPluginPrivate::onModeChanged(IMode *mode)
-{
- // FIXME: This one gets always called, even if switching between modes
- // different then the debugger mode. E.g. Welcome and Help mode and
- // also on shutdown.
- m_uiSwitcher->onModeChanged(mode);
+ cmd = am->registerAction(m_actions.runToFunctionAction,
+ Constants::RUN_TO_FUNCTION, cppDebuggercontext);
+ cmd->setDefaultKeySequence(QKeySequence(Constants::RUN_TO_FUNCTION_KEY));
+ cmd->setAttribute(Command::CA_Hide);
+ m_uiSwitcher->addMenuAction(cmd, CppLanguage);
- if (mode != m_debugMode)
- return;
- EditorManager *editorManager = EditorManager::instance();
- if (editorManager->currentEditor())
- editorManager->currentEditor()->widget()->setFocus();
-}
+ cmd = am->registerAction(m_actions.jumpToLineAction,
+ Constants::JUMP_TO_LINE1, cppDebuggercontext);
+ cmd->setAttribute(Command::CA_Hide);
+ m_uiSwitcher->addMenuAction(cmd, CppLanguage);
-void DebuggerPluginPrivate::showSettingsDialog()
-{
- ICore::instance()->showOptionsDialog(
- _(DEBUGGER_SETTINGS_CATEGORY),
- _(DEBUGGER_COMMON_SETTINGS_ID));
-}
-void DebuggerPluginPrivate::dumpLog()
-{
- QString fileName = QFileDialog::getSaveFileName(mainWindow(),
- tr("Save Debugger Log"), QDir::tempPath());
- if (fileName.isEmpty())
- return;
- QFile file(fileName);
- if (!file.open(QIODevice::WriteOnly))
- return;
- QTextStream ts(&file);
- ts << m_logWindow->inputContents();
- ts << "\n\n=======================================\n\n";
- ts << m_logWindow->combinedContents();
-}
+ cmd = am->registerAction(m_actions.returnFromFunctionAction,
+ Constants::RETURN_FROM_FUNCTION, cppDebuggercontext);
+ cmd->setAttribute(Command::CA_Hide);
+ m_uiSwitcher->addMenuAction(cmd, CppLanguage);
-void DebuggerPluginPrivate::clearStatusMessage()
-{
- m_statusLabel->setText(m_lastPermanentStatusMessage);
-}
-/*! Activates the previous mode when the current mode is the debug mode. */
-void DebuggerPluginPrivate::activatePreviousMode()
-{
- ModeManager *modeManager = ICore::instance()->modeManager();
+ cmd = am->registerAction(m_actions.reverseDirectionAction,
+ Constants::REVERSE, cppDebuggercontext);
+ cmd->setDefaultKeySequence(QKeySequence(Constants::REVERSE_KEY));
+ cmd->setAttribute(Command::CA_Hide);
+ m_uiSwitcher->addMenuAction(cmd, CppLanguage);
- if (modeManager->currentMode() == modeManager->mode(MODE_DEBUG)
- && !m_previousMode.isEmpty()) {
- modeManager->activateMode(m_previousMode);
- m_previousMode.clear();
- }
-}
-void DebuggerPluginPrivate::activateDebugMode()
-{
- m_actions.reverseDirectionAction->setChecked(false);
- m_actions.reverseDirectionAction->setEnabled(false);
- ModeManager *modeManager = ModeManager::instance();
- m_previousMode = modeManager->currentMode()->id();
- modeManager->activateMode(_(MODE_DEBUG));
-}
+ sep = new QAction(this);
+ sep->setSeparator(true);
+ cmd = am->registerAction(sep, _("Debugger.Sep.Break"), globalcontext);
+ m_uiSwitcher->addMenuAction(cmd, CppLanguage);
-void DebuggerPluginPrivate::sessionLoaded()
-{
- m_breakHandler->loadSessionData();
- dummyEngine()->watchHandler()->loadSessionData();
-}
-void DebuggerPluginPrivate::aboutToUnloadSession()
-{
- m_breakHandler->removeSessionData();
- // Stop debugging the active project when switching sessions.
- // Note that at startup, session switches may occur, which interfere
- // with command-line debugging startup.
- // FIXME ABC: Still wanted? Iterate?
- //if (d->m_engine && state() != DebuggerNotReady
- // && runControl()->sp().startMode == StartInternal)
- // d->m_engine->shutdown();
-}
+ //cmd = am->registerAction(m_actions.snapshotAction,
+ // Constants::SNAPSHOT, cppDebuggercontext);
+ //cmd->setDefaultKeySequence(QKeySequence(Constants::SNAPSHOT_KEY));
+ //cmd->setAttribute(Command::CA_Hide);
+ //m_uiSwitcher->addMenuAction(cmd, CppLanguage);
-void DebuggerPluginPrivate::aboutToSaveSession()
-{
- dummyEngine()->watchHandler()->loadSessionData();
- m_breakHandler->saveSessionData();
-}
+ cmd = am->registerAction(m_actions.frameDownAction,
+ Constants::FRAME_DOWN, cppDebuggercontext);
+ cmd = am->registerAction(m_actions.frameUpAction,
+ Constants::FRAME_UP, cppDebuggercontext);
-void DebuggerPluginPrivate::executeDebuggerCommand()
-{
- if (QAction *action = qobject_cast<QAction *>(sender()))
- currentEngine()->executeDebuggerCommand(action->data().toString());
-}
-void DebuggerPluginPrivate::showStatusMessage(const QString &msg0, int timeout)
-{
- showMessage(msg0, LogStatus);
- QString msg = msg0;
- msg.replace(QLatin1Char('\n'), QString());
- m_statusLabel->setText(msg);
- if (timeout > 0) {
- m_statusTimer.setSingleShot(true);
- m_statusTimer.start(timeout);
- } else {
- m_lastPermanentStatusMessage = msg;
- m_statusTimer.stop();
- }
-}
+ cmd = am->registerAction(action(OperateByInstruction),
+ Constants::OPERATE_BY_INSTRUCTION, cppDebuggercontext);
+ cmd->setAttribute(Command::CA_Hide);
+ m_uiSwitcher->addMenuAction(cmd, CppLanguage);
-void DebuggerPluginPrivate::scriptExpressionEntered(const QString &expression)
-{
- currentEngine()->executeDebuggerCommand(expression);
-}
-void DebuggerPluginPrivate::openMemoryEditor()
-{
- AddressDialog dialog;
- if (dialog.exec() == QDialog::Accepted)
- (void) new MemoryViewAgent(currentEngine(), dialog.address());
-}
+ cmd = am->registerAction(m_actions.breakAction,
+ Constants::TOGGLE_BREAK, globalcontext);
+ cmd->setDefaultKeySequence(QKeySequence(Constants::TOGGLE_BREAK_KEY));
+ m_uiSwitcher->addMenuAction(cmd, CppLanguage);
+ connect(m_actions.breakAction, SIGNAL(triggered()),
+ SLOT(toggleBreakpoint()));
-void DebuggerPluginPrivate::coreShutdown()
-{
- m_shuttingDown = true;
-}
+ //mcppcontext->addAction(cmd);
-void DebuggerPluginPrivate::writeSettings() const
-{
- m_debuggerSettings->writeSettings();
- m_uiSwitcher->writeSettings();
- if (GdbOptionsPage::gdbBinariesChanged)
- GdbOptionsPage::writeGdbBinarySettings();
-}
+ sep = new QAction(this);
+ sep->setSeparator(true);
+ cmd = am->registerAction(sep, _("Debugger.Sep.Watch"), globalcontext);
+ m_uiSwitcher->addMenuAction(cmd, CppLanguage);
-void DebuggerPluginPrivate::readSettings()
-{
- //qDebug() << "PLUGIN READ SETTINGS";
- m_debuggerSettings->readSettings();
- m_uiSwitcher->readSettings();
- GdbOptionsPage::readGdbBinarySettings();
-}
-const CPlusPlus::Snapshot &DebuggerPluginPrivate::cppCodeModelSnapshot() const
-{
- using namespace CppTools;
- if (m_codeModelSnapshot.isEmpty() && action(UseCodeModel)->isChecked())
- m_codeModelSnapshot = CppModelManagerInterface::instance()->snapshot();
- return m_codeModelSnapshot;
-}
+ cmd = am->registerAction(m_actions.watchAction1,
+ Constants::ADD_TO_WATCH1, cppeditorcontext);
+ cmd->action()->setEnabled(true);
+ //cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+D,Ctrl+W")));
+ m_uiSwitcher->addMenuAction(cmd, CppLanguage);
-void DebuggerPluginPrivate::resetLocation()
-{
- currentEngine()->resetLocation();
-}
-void DebuggerPluginPrivate::removeLocationMark()
-{
- m_locationTimer.setSingleShot(true);
- m_locationTimer.start(80);
-}
+ // Editor context menu
+ ActionContainer *editorContextMenu =
+ am->actionContainer(CppEditor::Constants::M_CONTEXT);
+ cmd = am->registerAction(sep, _("Debugger.Sep.Views"),
+ cppDebuggercontext);
+ editorContextMenu->addAction(cmd);
+ cmd->setAttribute(Command::CA_Hide);
-void DebuggerPluginPrivate::doRemoveLocationMark()
-{
- m_locationTimer.stop();
- m_locationMark.reset();
-}
+ cmd = am->registerAction(m_actions.watchAction2,
+ Constants::ADD_TO_WATCH2, cppDebuggercontext);
+ cmd->action()->setEnabled(true);
+ editorContextMenu->addAction(cmd);
+ cmd->setAttribute(Command::CA_Hide);
-void DebuggerPluginPrivate::setSessionValue(const QString &name, const QVariant &value)
-{
- QTC_ASSERT(sessionManager(), return);
- sessionManager()->setValue(name, value);
- //qDebug() << "SET SESSION VALUE: " << name;
-}
+ m_plugin->addAutoReleasedObject(new CommonOptionsPage);
+ QList<Core::IOptionsPage *> engineOptionPages;
+ if (m_cmdLineEnabledEngines & GdbEngineType)
+ addGdbOptionPages(&engineOptionPages);
+#ifdef CDB_ENABLED
+ if (m_cmdLineEnabledEngines & CdbEngineType)
+ addCdbOptionPages(&engineOptionPages);
+#endif
+#ifdef Q_OS_WIN
+ Debugger::Cdb::addCdb2OptionPages(&engineOptionPages);
+#endif
+#ifdef WITH_LLDB
+ if (m_cmdLineEnabledEngines & LldbEngineType)
+ addLldbOptionPages(&engineOptionPages);
+#endif
-QVariant DebuggerPluginPrivate::sessionValue(const QString &name)
-{
- QTC_ASSERT(sessionManager(), return QVariant());
- //qDebug() << "GET SESSION VALUE: " << name;
- return sessionManager()->value(name);
-}
+ //if (m_cmdLineEnabledEngines & ScriptEngineType)
+ // addScriptOptionPages(&engineOptionPages);
+ //if (m_cmdLineEnabledEngines & TcfEngineType)
+ // addTcfOptionPages(&engineOptionPages);
+ foreach (Core::IOptionsPage *op, engineOptionPages)
+ m_plugin->addAutoReleasedObject(op);
+ m_plugin->addAutoReleasedObject(new DebuggingHelperOptionPage);
-void DebuggerPluginPrivate::openTextEditor(const QString &titlePattern0,
- const QString &contents)
-{
- if (m_shuttingDown)
- return;
- QString titlePattern = titlePattern0;
- EditorManager *editorManager = EditorManager::instance();
- QTC_ASSERT(editorManager, return);
- IEditor *editor = editorManager->openEditorWithContents(
- CC::K_DEFAULT_TEXT_EDITOR_ID, &titlePattern, contents);
- QTC_ASSERT(editor, return);
- editorManager->activateEditor(editor, EditorManager::IgnoreNavigationHistory);
-}
+ //setSimpleDockWidgetArrangement(Lang_Cpp);
+ connect(ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode*)),
+ SLOT(onModeChanged(Core::IMode*)));
+ m_debugMode->widget()->setFocusProxy(EditorManager::instance());
+ m_plugin->addObject(m_debugMode);
-void DebuggerPluginPrivate::clearCppCodeModelSnapshot()
-{
- m_codeModelSnapshot = CPlusPlus::Snapshot();
-}
-void DebuggerPluginPrivate::showMessage(const QString &msg, int channel, int timeout)
-{
- //qDebug() << "PLUGIN OUTPUT: " << channel << msg;
- //ConsoleWindow *cw = m_consoleWindow;
- QTC_ASSERT(m_logWindow, return);
- switch (channel) {
- case StatusBar:
- // This will append to m_logWindow's output pane, too.
- showStatusMessage(msg, timeout);
- break;
- case LogMiscInput:
- m_logWindow->showInput(LogMisc, msg);
- m_logWindow->showOutput(LogMisc, msg);
- break;
- case LogInput:
- m_logWindow->showInput(LogInput, msg);
- m_logWindow->showOutput(LogInput, msg);
- break;
- case ScriptConsoleOutput:
- m_scriptConsoleWindow->appendResult(msg);
- break;
- case LogError:
- m_logWindow->showOutput(channel, msg);
- ensureLogVisible();
- break;
- default:
- m_logWindow->showOutput(channel, msg);
- break;
- }
-}
+ //
+ // Connections
+ //
-DebuggerMainWindow *DebuggerPluginPrivate::debuggerMainWindow() const
-{
- return qobject_cast<DebuggerMainWindow*>(mainWindow());
-}
+ // TextEditor
+ connect(TextEditorSettings::instance(),
+ SIGNAL(fontSettingsChanged(TextEditor::FontSettings)),
+ SLOT(fontSettingsChanged(TextEditor::FontSettings)));
-void DebuggerPluginPrivate::showQtDumperLibraryWarning(const QString &details)
-{
- QMessageBox dialog(mainWindow());
- QPushButton *qtPref = dialog.addButton(tr("Open Qt4 Options"),
- QMessageBox::ActionRole);
- QPushButton *helperOff = dialog.addButton(tr("Turn off Helper Usage"),
- QMessageBox::ActionRole);
- QPushButton *justContinue = dialog.addButton(tr("Continue Anyway"),
- QMessageBox::AcceptRole);
- dialog.setDefaultButton(justContinue);
- dialog.setWindowTitle(tr("Debugging Helper Missing"));
- dialog.setText(tr("The debugger could not load the debugging helper library."));
- dialog.setInformativeText(tr(
- "The debugging helper is used to nicely format the values of some Qt "
- "and Standard Library data types. "
- "It must be compiled for each used Qt version separately. "
- "On the Qt4 options page, select a Qt installation "
- "and click Rebuild."));
- if (!details.isEmpty())
- dialog.setDetailedText(details);
- dialog.exec();
- if (dialog.clickedButton() == qtPref) {
- ICore::instance()->showOptionsDialog(
- _(Qt4ProjectManager::Constants::QT_SETTINGS_CATEGORY),
- _(Qt4ProjectManager::Constants::QTVERSION_SETTINGS_PAGE_ID));
- } else if (dialog.clickedButton() == helperOff) {
- action(UseDebuggingHelpers)->setValue(qVariantFromValue(false), false);
- }
-}
+ // ProjectExplorer
+ connect(sessionManager(), SIGNAL(sessionLoaded()),
+ SLOT(sessionLoaded()));
+ connect(sessionManager(), SIGNAL(aboutToSaveSession()),
+ SLOT(aboutToSaveSession()));
+ connect(sessionManager(), SIGNAL(aboutToUnloadSession()),
+ SLOT(aboutToUnloadSession()));
+ connect(ProjectExplorerPlugin::instance(), SIGNAL(updateRunActions()),
+ SLOT(updateDebugActions()));
-bool DebuggerPluginPrivate::isRegisterViewVisible() const
-{
- return m_registerDock->toggleViewAction()->isChecked();
-}
+ // EditorManager
+ QObject *editorManager = core->editorManager();
+ connect(editorManager, SIGNAL(editorAboutToClose(Core::IEditor*)),
+ SLOT(editorAboutToClose(Core::IEditor*)));
+ connect(editorManager, SIGNAL(editorOpened(Core::IEditor*)),
+ SLOT(editorOpened(Core::IEditor*)));
-void DebuggerPluginPrivate::createNewDock(QWidget *widget)
-{
- QDockWidget *dockWidget =
- m_uiSwitcher->createDockWidget(CppLanguage, widget);
- dockWidget->setWindowTitle(widget->windowTitle());
- dockWidget->setObjectName(widget->windowTitle());
- dockWidget->setFeatures(QDockWidget::DockWidgetClosable);
- //dockWidget->setWidget(widget);
- //mainWindow()->addDockWidget(Qt::TopDockWidgetArea, dockWidget);
- dockWidget->show();
-}
+ // Application interaction
+ connect(action(SettingsDialog), SIGNAL(triggered()),
+ SLOT(showSettingsDialog()));
-void DebuggerPluginPrivate::runControlStarted(DebuggerRunControl *runControl)
-{
- activateDebugMode();
- if (!hasSnapshots())
- m_uiSwitcher->updateActiveLanguages();
+ // Toolbar
+ QWidget *toolbarContainer = new QWidget;
- const QString message = runControl->idString();
- showMessage(message, StatusBar);
- showMessage(m_debuggerSettings->dump(), LogDebug);
- m_snapshotHandler->appendSnapshot(runControl);
- connectEngine(runControl->engine());
-}
+ QHBoxLayout *hbox = new QHBoxLayout(toolbarContainer);
+ hbox->setMargin(0);
+ hbox->setSpacing(0);
+ hbox->addWidget(toolButton(am->command(Constants::DEBUG)->action()));
+ hbox->addWidget(toolButton(am->command(STOP)->action()));
+ hbox->addWidget(toolButton(am->command(NEXT)->action()));
+ hbox->addWidget(toolButton(am->command(STEP)->action()));
+ hbox->addWidget(toolButton(am->command(STEPOUT)->action()));
+ hbox->addWidget(toolButton(am->command(OPERATE_BY_INSTRUCTION)->action()));
-void DebuggerPluginPrivate::runControlFinished(DebuggerRunControl *runControl)
-{
- m_snapshotHandler->removeSnapshot(runControl);
- if (m_snapshotHandler->size() == 0) {
- // Last engine quits.
- disconnectEngine();
- if (boolSetting(SwitchModeOnExit))
- activatePreviousMode();
- } else {
- // Connect to some existing engine.
- m_snapshotHandler->activateSnapshot(0);
- }
-}
+ //hbox->addWidget(new Utils::StyledSeparator);
+ m_reverseToolButton = toolButton(am->command(REVERSE)->action());
+ hbox->addWidget(m_reverseToolButton);
+ //m_reverseToolButton->hide();
-void DebuggerPluginPrivate::remoteCommand(const QStringList &options,
- const QStringList &)
-{
- if (options.isEmpty())
- return;
+ hbox->addWidget(new Utils::StyledSeparator);
+ hbox->addWidget(new QLabel(tr("Threads:")));
- unsigned enabledEngines = 0;
- QString errorMessage;
+ m_threadBox = new QComboBox;
+ connect(m_threadBox, SIGNAL(activated(int)), SLOT(selectThread(int)));
- if (!parseArguments(options,
- &m_attachRemoteParameters, &enabledEngines, &errorMessage)) {
- qWarning("%s", qPrintable(errorMessage));
- return;
- }
+ hbox->addWidget(m_threadBox);
+ hbox->addSpacerItem(new QSpacerItem(4, 0));
+ hbox->addWidget(m_statusLabel, 10);
- if (!attachCmdLine())
- qWarning("%s", qPrintable(
- _("Incomplete remote attach command received: %1").
- arg(options.join(QString(QLatin1Char(' '))))));
-}
+ m_uiSwitcher->setToolbar(CppLanguage, toolbarContainer);
+ connect(m_uiSwitcher,
+ SIGNAL(dockResetRequested(Debugger::DebuggerLanguages)),
+ SLOT(setSimpleDockWidgetArrangement(Debugger::DebuggerLanguages)));
-QString DebuggerPluginPrivate::gdbBinaryForToolChain(int toolChain) const
-{
- return GdbOptionsPage::gdbBinaryToolChainMap.key(toolChain);
-}
+ connect(action(EnableReverseDebugging),
+ SIGNAL(valueChanged(QVariant)),
+ SLOT(enableReverseDebuggingTriggered(QVariant)));
-DebuggerLanguages DebuggerPluginPrivate::activeLanguages() const
-{
- return m_uiSwitcher->activeDebugLanguages();
-}
+ // UI Switcher
+ connect(m_uiSwitcher,
+ SIGNAL(activeLanguagesChanged(Debugger::DebuggerLanguages)),
+ SLOT(languagesChanged(Debugger::DebuggerLanguages)));
-bool DebuggerPluginPrivate::isReverseDebugging() const
-{
- return m_actions.reverseDirectionAction->isChecked();
-}
+ setInitialState();
+ connectEngine(0);
-QMessageBox *showMessageBox(int icon, const QString &title,
- const QString &text, int buttons)
-{
- QMessageBox *mb = new QMessageBox(QMessageBox::Icon(icon),
- title, text, QMessageBox::StandardButtons(buttons),
- debuggerCore()->mainWindow());
- mb->setAttribute(Qt::WA_DeleteOnClose);
- mb->show();
- return mb;
-}
+ connect(sessionManager(),
+ SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
+ SLOT(onCurrentProjectChanged(ProjectExplorer::Project*)));
-void DebuggerPluginPrivate::ensureLogVisible()
-{
- QAction *action = m_outputDock->toggleViewAction();
- if (!action->isChecked())
- action->trigger();
-}
+ connect(&m_locationTimer,
+ SIGNAL(timeout()),
+ SLOT(doRemoveLocationMark()));
-void DebuggerPluginPrivate::extensionsInitialized()
-{
QTC_ASSERT(m_coreSettings, /**/);
m_watchersWindow->setVisible(false);
m_returnWindow->setVisible(false);