OSDN Git Service

Debugger: Expose which languages (QML, C++, Any) an engine supports
[qt-creator-jp/qt-creator-jp.git] / src / plugins / debugger / debuggerplugin.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
8 **
9 **
10 ** GNU Lesser General Public License Usage
11 **
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 **
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 **
23 ** Other Usage
24 **
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at info@qt.nokia.com.
30 **
31 **************************************************************************/
32
33 #include "debuggerplugin.h"
34
35 #include "debuggerstartparameters.h"
36 #include "debuggeractions.h"
37 #include "debuggerconstants.h"
38 #include "debuggerinternalconstants.h"
39 #include "debuggercore.h"
40 #include "debuggerdialogs.h"
41 #include "debuggerengine.h"
42 #include "debuggermainwindow.h"
43 #include "debuggerrunner.h"
44 #include "debuggerruncontrolfactory.h"
45 #include "debuggerstringutils.h"
46 #include "memoryagent.h"
47 #include "breakpoint.h"
48 #include "breakhandler.h"
49 #include "breakwindow.h"
50 #include "consolewindow.h"
51 #include "disassemblerlines.h"
52 #include "logwindow.h"
53 #include "moduleswindow.h"
54 #include "moduleshandler.h"
55 #include "registerwindow.h"
56 #include "snapshotwindow.h"
57 #include "stackhandler.h"
58 #include "stackwindow.h"
59 #include "sourcefileswindow.h"
60 #include "threadswindow.h"
61 #include "watchhandler.h"
62 #include "watchwindow.h"
63 #include "watchutils.h"
64 #include "debuggertooltipmanager.h"
65 #include "qml/qmlengine.h"
66 #include "qml/qmlcppengine.h"
67
68 #include "snapshothandler.h"
69 #include "threadshandler.h"
70 #include "commonoptionspage.h"
71
72 #include <coreplugin/actionmanager/actionmanager.h>
73 #include <coreplugin/actionmanager/actioncontainer.h>
74 #include <coreplugin/actionmanager/command.h>
75 #include <coreplugin/id.h>
76 #include <coreplugin/imode.h>
77 #include <coreplugin/coreconstants.h>
78 #include <coreplugin/dialogs/ioptionspage.h>
79 #include <coreplugin/editormanager/editormanager.h>
80 #include <coreplugin/findplaceholder.h>
81 #include <coreplugin/icontext.h>
82 #include <coreplugin/icore.h>
83 #include <coreplugin/imode.h>
84 #include <coreplugin/icorelistener.h>
85 #include <coreplugin/minisplitter.h>
86 #include <coreplugin/modemanager.h>
87
88 #include <cppeditor/cppeditorconstants.h>
89 #include <cplusplus/ModelManagerInterface.h>
90
91 #include <extensionsystem/pluginmanager.h>
92
93 #include <projectexplorer/project.h>
94 #include <projectexplorer/projectexplorer.h>
95 #include <projectexplorer/projectexplorerconstants.h>
96 #include <projectexplorer/toolchainmanager.h>
97 #include <projectexplorer/toolchain.h>
98 #include <projectexplorer/session.h>
99 #include <projectexplorer/target.h>
100 #include <projectexplorer/abi.h>
101
102 #include <qtsupport/qtsupportconstants.h>
103
104 #include <texteditor/basetexteditor.h>
105 #include <texteditor/fontsettings.h>
106 #include <texteditor/texteditorsettings.h>
107
108 #include <utils/qtcassert.h>
109 #include <utils/savedaction.h>
110 #include <utils/styledbar.h>
111 #include <utils/proxyaction.h>
112 #include <utils/statuslabel.h>
113 #include <utils/fileutils.h>
114
115 #include <qml/scriptconsole.h>
116
117 #include <QtCore/QTimer>
118 #include <QtCore/QtPlugin>
119 #include <QtGui/QComboBox>
120 #include <QtGui/QDockWidget>
121 #include <QtGui/QFileDialog>
122 #include <QtGui/QMenu>
123 #include <QtGui/QMessageBox>
124 #include <QtGui/QPushButton>
125 #include <QtGui/QTextBlock>
126 #include <QtGui/QTextCursor>
127 #include <QtGui/QToolButton>
128 #include <QtGui/QTreeWidget>
129 #include <QtGui/QInputDialog>
130
131 #include <climits>
132
133 #define DEBUG_STATE 1
134 #ifdef DEBUG_STATE
135 //#   define STATE_DEBUG(s)
136 //    do { QString msg; QTextStream ts(&msg); ts << s;
137 //      showMessage(msg, LogDebug); } while (0)
138 #   define STATE_DEBUG(s) do { qDebug() << s; } while(0)
139 #else
140 #   define STATE_DEBUG(s)
141 #endif
142
143 /*!
144     \namespace Debugger
145     Debugger plugin namespace
146 */
147
148 /*!
149     \namespace Debugger::Internal
150     Internal namespace of the Debugger plugin
151     \internal
152 */
153
154 /*!
155     \class Debugger::DebuggerEngine
156
157     \brief Base class of a debugger engine.
158
159     Note: the Debugger process itself and any helper processes like
160     gdbserver, the CODA client etc are referred to as 'Engine',
161     whereas the debugged process is referred to as 'Inferior'.
162
163     Transitions marked by '---' are done in the individual engines.
164     Transitions marked by '+-+' are done in the base DebuggerEngine.
165     Transitions marked by '*' are done asynchronously.
166
167     The GdbEngine->setupEngine() function is described in more detail below.
168
169     The engines are responsible for local roll-back to the last
170     acknowledged state before calling notify*Failed. I.e. before calling
171     notifyEngineSetupFailed() any process started during setupEngine()
172     so far must be terminated.
173     \code
174
175                         DebuggerNotReady
176                          progressmanager/progressmanager.cpp      +
177                       EngineSetupRequested
178                                +
179                   (calls *Engine->setupEngine())
180                             |      |
181                             |      |
182                        {notify-  {notify-
183                         Engine-   Engine-
184                         SetupOk}  SetupFailed}
185                             +      +
186                             +      `+-+-+> EngineSetupFailed
187                             +                   +
188                             +    [calls RunControl->startFailed]
189                             +                   +
190                             +             DebuggerFinished
191                             v
192                       EngineSetupOk
193                             +
194              [calls RunControl->StartSuccessful]
195                             +
196                   InferiorSetupRequested
197                             +
198              (calls *Engine->setupInferior())
199                          |       |
200                          |       |
201                     {notify-   {notify-
202                      Inferior- Inferior-
203                      SetupOk}  SetupFailed}
204                          +       +
205                          +       ` +-+-> InferiorSetupFailed +-+-+-+-+-+->.
206                          +                                                +
207                   InferiorSetupOk                                         +
208                          +                                                +
209                   EngineRunRequested                                      +
210                          +                                                +
211                  (calls *Engine->runEngine())                             +
212                /       |            |        \                            +
213              /         |            |          \                          +
214             | (core)   | (attach)   |           |                         +
215             |          |            |           |                         +
216       {notify-    {notifyER&- {notifyER&-  {notify-                       +
217       Inferior-     Inferior-   Inferior-  EngineRun-                     +
218      Unrunnable}     StopOk}     RunOk}     Failed}                       +
219            +           +            +           +                         +
220    InferiorUnrunnable  +     InferiorRunOk      +                         +
221                        +                        +                         +
222                 InferiorStopOk            EngineRunFailed                 +
223                                                 +                         v
224                                                  `-+-+-+-+-+-+-+-+-+-+-+>-+
225                                                                           +
226                                                                           +
227                        #Interrupt@InferiorRunOk#                          +
228                                   +                                       +
229                           InferiorStopRequested                           +
230   #SpontaneousStop                +                                       +
231    @InferiorRunOk#         (calls *Engine->                               +
232           +               interruptInferior())                            +
233       {notify-               |          |                                 +
234      Spontaneous-       {notify-    {notify-                              +
235       Inferior-          Inferior-   Inferior-                            +
236        StopOk}           StopOk}    StopFailed}                           +
237            +              +             +                                 +
238             +            +              +                                 +
239             InferiorStopOk              +                                 +
240                   +                     +                                 +
241                   +                    +                                  +
242                   +                   +                                   +
243         #Stop@InferiorUnrunnable#    +                                    +
244           #Creator Close Event#     +                                     +
245                        +           +                                      +
246                 InferiorShutdownRequested                                 +
247                             +                                             +
248            (calls *Engine->shutdownInferior())                            +
249                          |        |                                       +
250                     {notify-   {notify-                                   +
251                      Inferior- Inferior-                                  +
252                   ShutdownOk}  ShutdownFailed}                            +
253                          +        +                                       +
254                          +        +                                       +
255   #Inferior exited#      +        +                                       +
256          |               +        +                                       +
257    {notifyInferior-      +        +                                       +
258       Exited}            +        +                                       +
259            +             +        +                                       +
260      InferiorExitOk      +        +                                       +
261              +           +        +                                       +
262             InferiorShutdownOk InferiorShutdownFailed                     +
263                       *          *                                        +
264                   EngineShutdownRequested                                 +
265                             +                                             +
266            (calls *Engine->shutdownEngine())  <+-+-+-+-+-+-+-+-+-+-+-+-+-+'
267                          |        |
268                          |        |
269                     {notify-   {notify-
270                      Engine-    Engine-
271                   ShutdownOk}  ShutdownFailed}
272                          +       +
273             EngineShutdownOk  EngineShutdownFailed
274                          *       *
275                      DebuggerFinished
276
277 \endcode */
278
279 /* Here is a matching graph as a GraphViz graph. View it using
280  * \code
281 grep "^sg1:" debuggerplugin.cpp | cut -c5- | dot -osg1.ps -Tps && gv sg1.ps
282
283 sg1: digraph DebuggerStates {
284 sg1:   DebuggerNotReady -> EngineSetupRequested
285 sg1:   EngineSetupRequested -> EngineSetupOk [ label="notifyEngineSetupOk", style="dashed" ];
286 sg1:   EngineSetupRequested -> EngineSetupFailed [ label= "notifyEngineSetupFailed", style="dashed"];
287 sg1:   EngineSetupFailed -> DebuggerFinished [ label= "RunControl::StartFailed" ];
288 sg1:   EngineSetupOk -> InferiorSetupRequested [ label= "RunControl::StartSuccessful" ];
289 sg1:   InferiorSetupRequested -> InferiorSetupOk [ label="notifyInferiorSetupOk", style="dashed" ];
290 sg1:   InferiorSetupRequested -> InferiorSetupFailed [ label="notifyInferiorFailed", style="dashed" ];
291 sg1:   InferiorSetupOk -> EngineRunRequested
292 sg1:   InferiorSetupFailed -> EngineShutdownRequested
293 sg1:   EngineRunRequested -> InferiorUnrunnable [ label="notifyInferiorUnrunnable", style="dashed" ];
294 sg1:   EngineRunRequested -> InferiorStopOk [ label="notifyEngineRunAndInferiorStopOk", style="dashed" ];
295 sg1:   EngineRunRequested -> InferiorRunOk [ label="notifyEngineRunAndInferiorRunOk", style="dashed" ];
296 sg1:   EngineRunRequested -> EngineRunFailed [ label="notifyEngineRunFailed", style="dashed" ];
297 sg1:   EngineRunFailed -> EngineShutdownRequested
298 sg1:   InferiorRunOk -> InferiorStopOk [ label="SpontaneousStop\nnotifyInferiorSpontaneousStop", style="dashed" ];
299 sg1:   InferiorRunOk -> InferiorStopRequested [ label="User stop\nEngine::interruptInferior", style="dashed"];
300 sg1:   InferiorStopRequested -> InferiorStopOk [ label="notifyInferiorStopOk", style="dashed" ];
301 sg1:   InferiorStopRequested -> InferiorShutdownRequested  [ label="notifyInferiorStopFailed", style="dashed" ];
302 sg1:   InferiorStopOk -> InferiorRunRequested [ label="User\nEngine::continueInferior" ];
303 sg1:   InferiorRunRequested -> InferiorRunOk [ label="notifyInferiorRunOk", style="dashed"];
304 sg1:   InferiorRunRequested -> InferiorRunFailed [ label="notifyInferiorRunFailed", style="dashed"];
305 sg1:   InferiorRunFailed -> InferiorStopOk
306 sg1:   InferiorStopOk -> InferiorShutdownRequested [ label="Close event" ];
307 sg1:   InferiorUnrunnable -> InferiorShutdownRequested [ label="Close event" ];
308 sg1:   InferiorShutdownRequested -> InferiorShutdownOk [ label= "Engine::shutdownInferior\nnotifyInferiorShutdownOk", style="dashed" ];
309 sg1:   InferiorShutdownRequested -> InferiorShutdownFailed [ label="Engine::shutdownInferior\nnotifyInferiorShutdownFailed", style="dashed" ];
310 sg1:   InferiorExited -> InferiorExitOk [ label="notifyInferiorExited", style="dashed"];
311 sg1:   InferiorExitOk -> InferiorShutdownOk
312 sg1:   InferiorShutdownOk -> EngineShutdownRequested
313 sg1:   InferiorShutdownFailed -> EngineShutdownRequested
314 sg1:   EngineShutdownRequested -> EngineShutdownOk [ label="Engine::shutdownEngine\nnotifyEngineShutdownOk", style="dashed" ];
315 sg1:   EngineShutdownRequested -> EngineShutdownFailed  [ label="Engine::shutdownEngine\nnotifyEngineShutdownFailed", style="dashed" ];
316 sg1:   EngineShutdownOk -> DebuggerFinished  [ style = "dotted" ];
317 sg1:   EngineShutdownFailed  -> DebuggerFinished [ style = "dotted" ];
318 sg1: }
319 * \endcode */
320 // Additional signalling:    {notifyInferiorIll}   {notifyEngineIll}
321
322
323 /*!
324     \class Debugger::Internal::GdbEngine
325     \brief Implementation of Debugger::Engine driving a gdb executable.
326
327     GdbEngine specific startup. All happens in EngineSetupRequested state:
328
329     Transitions marked by '---' are done in the individual adapters.
330
331     Transitions marked by '+-+' are done in the GdbEngine.
332
333     \code
334                   GdbEngine::setupEngine()
335                           +
336             (calls *Adapter->startAdapter())
337                           |      |
338                           |      `---> handleAdapterStartFailed()
339                           |                   +
340                           |             {notifyEngineSetupFailed}
341                           |
342                  handleAdapterStarted()
343                           +
344                  {notifyEngineSetupOk}
345
346
347
348                 GdbEngine::setupInferior()
349                           +
350             (calls *Adapter->prepareInferior())
351                           |      |
352                           |      `---> handlePrepareInferiorFailed()
353                           |                   +
354                           |             {notifyInferiorSetupFailed}
355                           |
356                 handleInferiorPrepared()
357                           +
358                 {notifyInferiorSetupOk}
359
360 \endcode */
361
362 using namespace Core;
363 using namespace Debugger::Constants;
364 using namespace ProjectExplorer;
365 using namespace TextEditor;
366
367 namespace CC = Core::Constants;
368 namespace PE = ProjectExplorer::Constants;
369
370
371 namespace Debugger {
372 namespace Constants {
373
374 #ifdef Q_WS_MAC
375 const char STOP_KEY[]                     = "Shift+Ctrl+Y";
376 const char RESET_KEY[]                    = "Ctrl+Shift+F5";
377 const char STEP_KEY[]                     = "Ctrl+Shift+I";
378 const char STEPOUT_KEY[]                  = "Ctrl+Shift+T";
379 const char NEXT_KEY[]                     = "Ctrl+Shift+O";
380 const char REVERSE_KEY[]                  = "";
381 const char RUN_TO_LINE_KEY[]              = "Shift+F8";
382 const char RUN_TO_SELECTED_FUNCTION_KEY[] = "Ctrl+F6";
383 const char JUMP_TO_LINE_KEY[]             = "Ctrl+D,Ctrl+L";
384 const char TOGGLE_BREAK_KEY[]             = "F8";
385 const char BREAK_BY_FUNCTION_KEY[]        = "Ctrl+D,Ctrl+F";
386 const char BREAK_AT_MAIN_KEY[]            = "Ctrl+D,Ctrl+M";
387 const char ADD_TO_WATCH_KEY[]             = "Ctrl+D,Ctrl+W";
388 const char SNAPSHOT_KEY[]                 = "Ctrl+D,Ctrl+S";
389 #else
390 const char STOP_KEY[]                     = "Shift+F5";
391 const char RESET_KEY[]                    = "Ctrl+Shift+F5";
392 const char STEP_KEY[]                     = "F11";
393 const char STEPOUT_KEY[]                  = "Shift+F11";
394 const char NEXT_KEY[]                     = "F10";
395 const char REVERSE_KEY[]                  = "F12";
396 const char RUN_TO_LINE_KEY[]              = "";
397 const char RUN_TO_SELECTED_FUNCTION_KEY[] = "Ctrl+F6";
398 const char JUMP_TO_LINE_KEY[]             = "";
399 const char TOGGLE_BREAK_KEY[]             = "F9";
400 const char BREAK_BY_FUNCTION_KEY[]        = "";
401 const char BREAK_AT_MAIN_KEY[]            = "";
402 const char ADD_TO_WATCH_KEY[]             = "Ctrl+Alt+Q";
403 const char SNAPSHOT_KEY[]                 = "Ctrl+D,Ctrl+S";
404 #endif
405
406 } // namespace Constants
407
408
409 namespace Internal {
410
411 // To be passed through margin menu action's data
412 struct BreakpointMenuContextData : public ContextData
413 {
414     enum Mode
415     {
416         Breakpoint,
417         MessageTracePoint
418     };
419
420     BreakpointMenuContextData() : mode(Breakpoint) {}
421     Mode mode;
422 };
423
424 } // namespace Internal
425 } // namespace Debugger
426
427 Q_DECLARE_METATYPE(Debugger::Internal::BreakpointMenuContextData)
428
429 namespace Debugger {
430 namespace Internal {
431
432 // FIXME: Outdated?
433 // The createCdbEngine function takes a list of options pages it can add to.
434 // This allows for having a "enabled" toggle on the page independently
435 // of the engine. That's good for not enabling the related ActiveX control
436 // unnecessarily.
437
438 void addCdbOptionPages(QList<IOptionsPage*> *opts);
439 void addGdbOptionPages(QList<IOptionsPage*> *opts);
440 void addScriptOptionPages(QList<IOptionsPage*> *opts);
441 void addTcfOptionPages(QList<IOptionsPage*> *opts);
442
443 #ifdef WITH_LLDB
444 void addLldbOptionPages(QList<IOptionsPage*> *opts);
445 #endif
446
447 static SessionManager *sessionManager()
448 {
449     return ProjectExplorerPlugin::instance()->session();
450 }
451
452 static QToolButton *toolButton(QAction *action)
453 {
454     QToolButton *button = new QToolButton;
455     button->setDefaultAction(action);
456     return button;
457 }
458
459 static Abi anyAbiOfBinary(const QString &fileName)
460 {
461     QList<Abi> abis = Abi::abisOfBinary(fileName);
462     if (abis.isEmpty())
463         return Abi();
464     return abis.at(0);
465 }
466
467 ///////////////////////////////////////////////////////////////////////
468 //
469 // DummyEngine
470 //
471 ///////////////////////////////////////////////////////////////////////
472
473 class DummyEngine : public DebuggerEngine
474 {
475     Q_OBJECT
476
477 public:
478     DummyEngine() : DebuggerEngine(DebuggerStartParameters(), AnyLanguage) {}
479     ~DummyEngine() {}
480
481     void setupEngine() {}
482     void setupInferior() {}
483     void runEngine() {}
484     void shutdownEngine() {}
485     void shutdownInferior() {}
486     unsigned debuggerCapabilities() const { return AddWatcherCapability; }
487     bool acceptsBreakpoint(BreakpointModelId) const { return false; }
488     bool acceptsDebuggerCommands() const { return false; }
489 };
490
491 ///////////////////////////////////////////////////////////////////////
492 //
493 // DebugMode
494 //
495 ///////////////////////////////////////////////////////////////////////
496
497 class DebugMode : public IMode
498 {
499 public:
500     DebugMode()
501     {
502         setObjectName(QLatin1String("DebugMode"));
503         setContext(Context(CC::C_EDITORMANAGER, C_DEBUGMODE, CC::C_NAVIGATION_PANE));
504         setDisplayName(DebuggerPlugin::tr("Debug"));
505         setIcon(QIcon(QLatin1String(":/fancyactionbar/images/mode_Debug.png")));
506         setPriority(85);
507         setId(MODE_DEBUG);
508         setType(CC::MODE_EDIT_TYPE);
509     }
510
511     ~DebugMode()
512     {
513         // Make sure the editor manager does not get deleted.
514         //EditorManager::instance()->setParent(0);
515         delete m_widget;
516     }
517 };
518
519
520 ///////////////////////////////////////////////////////////////////////
521 //
522 // Misc
523 //
524 ///////////////////////////////////////////////////////////////////////
525
526 static TextEditor::ITextEditor *currentTextEditor()
527 {
528     if (const Core::EditorManager *editorManager = Core::EditorManager::instance())
529             if (Core::IEditor *editor = editorManager->currentEditor())
530                 return qobject_cast<TextEditor::ITextEditor*>(editor);
531     return 0;
532 }
533
534 static bool currentTextEditorPosition(ContextData *data)
535 {
536     if (TextEditor::ITextEditor *textEditor = currentTextEditor()) {
537         if (const Core::IFile *file = textEditor->file()) {
538             data->fileName = file->fileName();
539             data->lineNumber = textEditor->currentLine();
540             return true;
541         }
542     }
543     return false;
544 }
545
546 ///////////////////////////////////////////////////////////////////////
547 //
548 // DebuggerPluginPrivate
549 //
550 ///////////////////////////////////////////////////////////////////////
551
552 static DebuggerPluginPrivate *theDebuggerCore = 0;
553
554 /*!
555     \class Debugger::Internal::DebuggerCore
556
557     This is the "internal" interface of the debugger plugin that's
558     used by debugger views and debugger engines. The interface is
559     implemented in DebuggerPluginPrivate.
560 */
561
562 /*!
563     \class Debugger::Internal::DebuggerPluginPrivate
564
565     Implementation of DebuggerCore.
566 */
567
568 class DebuggerPluginPrivate : public DebuggerCore
569 {
570     Q_OBJECT
571
572 public:
573     explicit DebuggerPluginPrivate(DebuggerPlugin *plugin);
574     ~DebuggerPluginPrivate();
575
576     bool initialize(const QStringList &arguments, QString *errorMessage);
577     void extensionsInitialized();
578     void aboutToShutdown();
579
580     void connectEngine(DebuggerEngine *engine);
581     void disconnectEngine() { connectEngine(0); }
582     DebuggerEngine *currentEngine() const { return m_currentEngine; }
583     DebuggerEngine *dummyEngine();
584
585     void setThreads(const QStringList &list, int index)
586     {
587         const bool state = m_threadBox->blockSignals(true);
588         m_threadBox->clear();
589         foreach (const QString &item, list)
590             m_threadBox->addItem(item);
591         m_threadBox->setCurrentIndex(index);
592         m_threadBox->blockSignals(state);
593     }
594
595 public slots:
596     void writeSettings()
597     {
598         m_debuggerSettings->writeSettings();
599         m_mainWindow->writeSettings();
600     }
601
602     void selectThread(int index)
603     {
604         currentEngine()->selectThread(index);
605     }
606
607     void breakpointSetMarginActionTriggered()
608     {
609         const QAction *action = qobject_cast<const QAction *>(sender());
610         QTC_ASSERT(action, return);
611         const BreakpointMenuContextData data =
612             action->data().value<BreakpointMenuContextData>();
613         QString message;
614         if (data.mode == BreakpointMenuContextData::MessageTracePoint) {
615             if (data.address) {
616                 //: Message tracepoint: Address hit.
617                 message = tr("0x%1 hit").arg(data.address, 0, 16);
618             } else {
619                 //: Message tracepoint: %1 file, %2 line %3 function hit.
620                 message = tr("%1:%2 %3() hit").arg(QFileInfo(data.fileName).fileName()).
621                         arg(data.lineNumber).
622                         arg(cppFunctionAt(data.fileName, data.lineNumber));
623             }
624             QInputDialog dialog; // Create wide input dialog.
625             dialog.setWindowFlags(dialog.windowFlags()
626               & ~(Qt::WindowContextHelpButtonHint|Qt::MSWindowsFixedSizeDialogHint));
627             dialog.resize(600, dialog.height());
628             dialog.setWindowTitle(tr("Add Message Tracepoint"));
629             dialog.setLabelText (tr("Message:"));
630             dialog.setTextValue(message);
631             if (dialog.exec() != QDialog::Accepted || dialog.textValue().isEmpty())
632                 return;
633             message = dialog.textValue();
634         }
635         if (data.address)
636             toggleBreakpointByAddress(data.address, message);
637         else
638             toggleBreakpointByFileAndLine(data.fileName, data.lineNumber, message);
639     }
640
641     void breakpointRemoveMarginActionTriggered()
642     {
643         const QAction *act = qobject_cast<QAction *>(sender());
644         QTC_ASSERT(act, return);
645         BreakpointModelId id = act->data().value<BreakpointModelId>();
646         m_breakHandler->removeBreakpoint(id);
647      }
648
649     void breakpointEnableMarginActionTriggered()
650     {
651         const QAction *act = qobject_cast<QAction *>(sender());
652         QTC_ASSERT(act, return);
653         BreakpointModelId id = act->data().value<BreakpointModelId>();
654         breakHandler()->setEnabled(id, true);
655     }
656
657     void breakpointDisableMarginActionTriggered()
658     {
659         const QAction *act = qobject_cast<QAction *>(sender());
660         QTC_ASSERT(act, return);
661         BreakpointModelId id = act->data().value<BreakpointModelId>();;
662         breakHandler()->setEnabled(id, false);
663     }
664
665     void updateWatchersHeader(int section, int, int newSize)
666     {
667         m_watchersWindow->header()->resizeSection(section, newSize);
668     }
669
670     void sourceFilesDockToggled(bool on)
671     {
672         if (on && m_currentEngine->state() == InferiorStopOk)
673             m_currentEngine->reloadSourceFiles();
674     }
675
676     void modulesDockToggled(bool on)
677     {
678         if (on && m_currentEngine->state() == InferiorStopOk)
679             m_currentEngine->reloadModules();
680     }
681
682     void registerDockToggled(bool on)
683     {
684         if (on && m_currentEngine->state() == InferiorStopOk)
685             m_currentEngine->reloadRegisters();
686     }
687
688     void synchronizeBreakpoints()
689     {
690         showMessage("ATTEMPT SYNC", LogDebug);
691         for (int i = 0, n = m_snapshotHandler->size(); i != n; ++i) {
692             if (DebuggerEngine *engine = m_snapshotHandler->at(i))
693                 engine->attemptBreakpointSynchronization();
694         }
695     }
696
697     void synchronizeWatchers()
698     {
699         for (int i = 0, n = m_snapshotHandler->size(); i != n; ++i) {
700             if (DebuggerEngine *engine = m_snapshotHandler->at(i))
701                 engine->watchHandler()->updateWatchers();
702         }
703     }
704
705     void editorOpened(Core::IEditor *editor);
706     void updateBreakMenuItem(Core::IEditor *editor);
707     void setBusyCursor(bool busy);
708     void requestMark(TextEditor::ITextEditor *editor, int lineNumber);
709     void requestContextMenu(TextEditor::ITextEditor *editor,
710         int lineNumber, QMenu *menu);
711
712     void activatePreviousMode();
713     void activateDebugMode();
714     void toggleBreakpoint();
715     void toggleBreakpointByFileAndLine(const QString &fileName, int lineNumber,
716                                        const QString &tracePointMessage = QString());
717     void toggleBreakpointByAddress(quint64 address,
718                                    const QString &tracePointMessage = QString());
719     void onModeChanged(Core::IMode *mode);
720     void onCoreAboutToOpen();
721     void showSettingsDialog();
722
723     void debugProject();
724     void debugProjectBreakMain();
725     void startExternalApplication();
726     void startRemoteCdbSession();
727     void startRemoteApplication();
728     bool queryRemoteParameters(DebuggerStartParameters &sp, bool useScript);
729     void attachRemoteApplication();
730     void attachToQmlPort();
731     void startRemoteEngine();
732     void attachExternalApplication();
733     Q_SLOT void attachExternalApplication(ProjectExplorer::RunControl *rc);
734     void runScheduled();
735     void attachCore();
736     void attachRemote(const QString &spec);
737
738     void enableReverseDebuggingTriggered(const QVariant &value);
739     void languagesChanged();
740     void showStatusMessage(const QString &msg, int timeout = -1);
741     void openMemoryEditor();
742
743     const CPlusPlus::Snapshot &cppCodeModelSnapshot() const;
744
745     void showQtDumperLibraryWarning(const QString &details);
746     DebuggerMainWindow *mainWindow() const { return m_mainWindow; }
747     bool isDockVisible(const QString &objectName) const
748         { return mainWindow()->isDockVisible(objectName); }
749
750     bool hasSnapshots() const { return m_snapshotHandler->size(); }
751     void createNewDock(QWidget *widget);
752
753     void runControlStarted(DebuggerEngine *engine);
754     void runControlFinished(DebuggerEngine *engine);
755     DebuggerLanguages activeLanguages() const;
756     unsigned enabledEngines() const { return m_cmdLineEnabledEngines; }
757     QString debuggerForAbi(const Abi &abi, DebuggerEngineType et = NoEngineType) const;
758     void remoteCommand(const QStringList &options, const QStringList &);
759
760     bool isReverseDebugging() const;
761
762     BreakHandler *breakHandler() const { return m_breakHandler; }
763     SnapshotHandler *snapshotHandler() const { return m_snapshotHandler; }
764
765     void setConfigValue(const QString &name, const QVariant &value);
766     QVariant configValue(const QString &name) const;
767
768     DebuggerRunControl *createDebugger(const DebuggerStartParameters &sp,
769         RunConfiguration *rc = 0);
770     void startDebugger(RunControl *runControl);
771     void displayDebugger(DebuggerEngine *engine, bool updateEngine = true);
772
773     void dumpLog();
774     void cleanupViews();
775     void setInitialState();
776
777     void fontSettingsChanged(const TextEditor::FontSettings &settings);
778
779     void updateState(DebuggerEngine *engine);
780     void updateWatchersWindow();
781     void onCurrentProjectChanged(ProjectExplorer::Project *project);
782
783     void sessionLoaded();
784     void aboutToUnloadSession();
785     void aboutToSaveSession();
786
787     void executeDebuggerCommand(const QString &command);
788     void scriptExpressionEntered(const QString &expression);
789     void coreShutdown();
790
791 public slots:
792     void updateDebugActions();
793
794     void handleExecDetach()
795     {
796         currentEngine()->resetLocation();
797         currentEngine()->detachDebugger();
798     }
799
800     void handleExecContinue()
801     {
802         currentEngine()->resetLocation();
803         currentEngine()->continueInferior();
804     }
805
806     void handleExecInterrupt()
807     {
808         currentEngine()->resetLocation();
809         currentEngine()->requestInterruptInferior();
810     }
811
812     void handleExecReset()
813     {
814         currentEngine()->resetLocation();
815         currentEngine()->notifyEngineIll(); // FIXME: Check.
816     }
817
818     void handleExecStep()
819     {
820         if (currentEngine()->state() == DebuggerNotReady) {
821             debugProjectBreakMain();
822         } else {
823             currentEngine()->resetLocation();
824             if (boolSetting(OperateByInstruction))
825                 currentEngine()->executeStepI();
826             else
827                 currentEngine()->executeStep();
828         }
829     }
830
831     void handleExecNext()
832     {
833         if (currentEngine()->state() == DebuggerNotReady) {
834             debugProjectBreakMain();
835         } else {
836             currentEngine()->resetLocation();
837             if (boolSetting(OperateByInstruction))
838                 currentEngine()->executeNextI();
839             else
840                 currentEngine()->executeNext();
841         }
842     }
843
844     void handleExecStepOut()
845     {
846         currentEngine()->resetLocation();
847         currentEngine()->executeStepOut();
848     }
849
850     void handleExecReturn()
851     {
852         currentEngine()->resetLocation();
853         currentEngine()->executeReturn();
854     }
855
856     void handleExecJumpToLine()
857     {
858         //removeTooltip();
859         currentEngine()->resetLocation();
860         ContextData data;
861         if (currentTextEditorPosition(&data))
862             currentEngine()->executeJumpToLine(data);
863     }
864
865     void handleExecRunToLine()
866     {
867         //removeTooltip();
868         currentEngine()->resetLocation();
869         ContextData data;
870         if (currentTextEditorPosition(&data))
871             currentEngine()->executeRunToLine(data);
872     }
873
874     void handleExecRunToSelectedFunction()
875     {
876         ITextEditor *textEditor = currentTextEditor();
877         QTC_ASSERT(textEditor, return);
878         QPlainTextEdit *ed = qobject_cast<QPlainTextEdit*>(textEditor->widget());
879         if (!ed)
880             return;
881         QTextCursor cursor = ed->textCursor();
882         QString functionName = cursor.selectedText();
883         if (functionName.isEmpty()) {
884             const QTextBlock block = cursor.block();
885             const QString line = block.text();
886             foreach (const QString &str, line.trimmed().split('(')) {
887                 QString a;
888                 for (int i = str.size(); --i >= 0; ) {
889                     if (!str.at(i).isLetterOrNumber())
890                         break;
891                     a = str.at(i) + a;
892                 }
893                 if (!a.isEmpty()) {
894                     functionName = a;
895                     break;
896                 }
897             }
898         }
899
900         if (functionName.isEmpty()) {
901             showStatusMessage(tr("No function selected."));
902         } else {
903             showStatusMessage(tr("Running to function \"%1\".")
904                 .arg(functionName));
905             currentEngine()->resetLocation();
906             currentEngine()->executeRunToFunction(functionName);
907         }
908     }
909
910     void slotEditBreakpoint()
911     {
912         const QAction *act = qobject_cast<QAction *>(sender());
913         QTC_ASSERT(act, return);
914         const BreakpointModelId id = act->data().value<BreakpointModelId>();
915         QTC_ASSERT(id > 0, return);
916         BreakWindow::editBreakpoint(id, mainWindow());
917     }
918
919     void slotRunToLine()
920     {
921         const QAction *action = qobject_cast<const QAction *>(sender());
922         QTC_ASSERT(action, return);
923         const BreakpointMenuContextData data = action->data().value<BreakpointMenuContextData>();
924         currentEngine()->executeRunToLine(data);
925     }
926
927     void slotJumpToLine()
928     {
929         const QAction *action = qobject_cast<const QAction *>(sender());
930         QTC_ASSERT(action, return);
931         const BreakpointMenuContextData data = action->data().value<BreakpointMenuContextData>();
932         currentEngine()->executeJumpToLine(data);
933     }
934
935     void handleAddToWatchWindow()
936     {
937         // Requires a selection, but that's the only case we want anyway.
938         EditorManager *editorManager = EditorManager::instance();
939         if (!editorManager)
940             return;
941         IEditor *editor = editorManager->currentEditor();
942         if (!editor)
943             return;
944         ITextEditor *textEditor = qobject_cast<ITextEditor*>(editor);
945         if (!textEditor)
946             return;
947         QTextCursor tc;
948         QPlainTextEdit *ptEdit = qobject_cast<QPlainTextEdit*>(editor->widget());
949         if (ptEdit)
950             tc = ptEdit->textCursor();
951         QString exp;
952         if (tc.hasSelection()) {
953             exp = tc.selectedText();
954         } else {
955             int line, column;
956             exp = cppExpressionAt(textEditor, tc.position(), &line, &column);
957         }
958         if (exp.isEmpty())
959             return;
960         currentEngine()->watchHandler()->watchExpression(exp);
961     }
962
963     void handleExecExit()
964     {
965         currentEngine()->exitDebugger();
966     }
967
968     void handleFrameDown()
969     {
970         currentEngine()->frameDown();
971     }
972
973     void handleFrameUp()
974     {
975         currentEngine()->frameUp();
976     }
977
978     void handleOperateByInstructionTriggered(bool operateByInstructionTriggered)
979     {
980         // Go to source only if we have the file.
981         if (currentEngine()->stackHandler()->currentIndex() >= 0) {
982             const StackFrame frame = currentEngine()->stackHandler()->currentFrame();
983             if (operateByInstructionTriggered || frame.isUsable()) {
984                 currentEngine()->gotoLocation(Location(frame, true));
985             }
986         }
987     }
988
989     bool isActiveDebugLanguage(int lang) const
990     {
991         return m_mainWindow->activeDebugLanguages() & lang;
992     }
993
994     QVariant sessionValue(const QString &name);
995     void setSessionValue(const QString &name, const QVariant &value);
996     QIcon locationMarkIcon() const { return m_locationMarkIcon; }
997
998     void openTextEditor(const QString &titlePattern0, const QString &contents);
999     void clearCppCodeModelSnapshot();
1000     void showMessage(const QString &msg, int channel, int timeout = -1);
1001
1002     Utils::SavedAction *action(int code) const;
1003     bool boolSetting(int code) const;
1004     QString stringSetting(int code) const;
1005
1006     void showModuleSymbols(const QString &moduleName, const Symbols &symbols);
1007
1008     bool parseArgument(QStringList::const_iterator &it,
1009         const QStringList::const_iterator &cend,
1010         unsigned *enabledEngines, QString *errorMessage);
1011     bool parseArguments(const QStringList &args,
1012         unsigned *enabledEngines, QString *errorMessage);
1013
1014     DebuggerToolTipManager *toolTipManager() const { return m_toolTipManager; }
1015     virtual QSharedPointer<GlobalDebuggerOptions> globalDebuggerOptions() const { return m_globalDebuggerOptions; }
1016
1017     // FIXME: Remove.
1018     void maybeEnrichParameters(DebuggerStartParameters *sp);
1019
1020 public:
1021     DebuggerMainWindow *m_mainWindow;
1022     DebuggerRunControlFactory *m_debuggerRunControlFactory;
1023
1024     QString m_previousMode;
1025     QList<DebuggerStartParameters> m_scheduledStarts;
1026
1027     Utils::ProxyAction *m_visibleStartAction;
1028     Utils::ProxyAction *m_hiddenStopAction;
1029     QAction *m_startAction;
1030     QAction *m_startExternalAction;
1031     QAction *m_startRemoteAction;
1032     QAction *m_attachToQmlPortAction;
1033     QAction *m_attachRemoteAction;
1034     QAction *m_startRemoteCdbAction;
1035     QAction *m_startRemoteLldbAction;
1036     QAction *m_attachExternalAction;
1037     QAction *m_attachCoreAction;
1038     QAction *m_detachAction;
1039     QAction *m_continueAction;
1040     QAction *m_exitAction; // On application output button if "Stop" is possible
1041     QAction *m_interruptAction; // On the fat debug button if "Pause" is possible
1042     QAction *m_undisturbableAction; // On the fat debug button if nothing can be done
1043     QAction *m_resetAction;
1044     QAction *m_stepAction;
1045     QAction *m_stepOutAction;
1046     QAction *m_runToLineAction; // In the debug menu
1047     QAction *m_runToSelectedFunctionAction;
1048     QAction *m_jumpToLineAction; // In the Debug menu.
1049     QAction *m_returnFromFunctionAction;
1050     QAction *m_nextAction;
1051     QAction *m_watchAction1; // In the Debug menu.
1052     QAction *m_watchAction2; // In the text editor context menu.
1053     QAction *m_breakAction;
1054     QAction *m_reverseDirectionAction;
1055     QAction *m_frameUpAction;
1056     QAction *m_frameDownAction;
1057
1058     QToolButton *m_reverseToolButton;
1059
1060     QIcon m_startIcon;
1061     QIcon m_exitIcon;
1062     QIcon m_continueIcon;
1063     QIcon m_interruptIcon;
1064     QIcon m_locationMarkIcon;
1065
1066     Utils::StatusLabel *m_statusLabel;
1067     QComboBox *m_threadBox;
1068
1069     BreakWindow *m_breakWindow;
1070     BreakHandler *m_breakHandler;
1071     //ConsoleWindow *m_consoleWindow;
1072     QTreeView *m_returnWindow;
1073     QTreeView *m_localsWindow;
1074     QTreeView *m_watchersWindow;
1075     QAbstractItemView *m_registerWindow;
1076     QAbstractItemView *m_modulesWindow;
1077     QAbstractItemView *m_snapshotWindow;
1078     SourceFilesWindow *m_sourceFilesWindow;
1079     QAbstractItemView *m_stackWindow;
1080     QAbstractItemView *m_threadsWindow;
1081     LogWindow *m_logWindow;
1082     ScriptConsole *m_scriptConsoleWindow;
1083
1084     bool m_busy;
1085     QString m_lastPermanentStatusMessage;
1086
1087     mutable CPlusPlus::Snapshot m_codeModelSnapshot;
1088     DebuggerPlugin *m_plugin;
1089
1090     SnapshotHandler *m_snapshotHandler;
1091     bool m_shuttingDown;
1092     DebuggerEngine *m_currentEngine;
1093     DebuggerSettings *m_debuggerSettings;
1094     QSettings *m_coreSettings;
1095     bool m_gdbBinariesChanged;
1096     uint m_cmdLineEnabledEngines;
1097     QStringList m_arguments;
1098     DebuggerToolTipManager *m_toolTipManager;
1099     CommonOptionsPage *m_commonOptionsPage;
1100     DummyEngine *m_dummyEngine;
1101     const QSharedPointer<GlobalDebuggerOptions> m_globalDebuggerOptions;
1102 };
1103
1104 DebuggerPluginPrivate::DebuggerPluginPrivate(DebuggerPlugin *plugin) :
1105     m_toolTipManager(new DebuggerToolTipManager(this)),
1106     m_dummyEngine(0),
1107     m_globalDebuggerOptions(new GlobalDebuggerOptions)
1108 {
1109     setObjectName("DebuggerCore");
1110     qRegisterMetaType<WatchData>("WatchData");
1111     qRegisterMetaType<ContextData>("ContextData");
1112     qRegisterMetaType<DebuggerStartParameters>("DebuggerStartParameters");
1113
1114     QTC_CHECK(!theDebuggerCore);
1115     theDebuggerCore = this;
1116
1117     m_plugin = plugin;
1118
1119     m_startRemoteCdbAction = 0;
1120     m_shuttingDown = false;
1121     m_statusLabel = 0;
1122     m_threadBox = 0;
1123
1124     m_breakWindow = 0;
1125     m_breakHandler = 0;
1126     m_returnWindow = 0;
1127     m_localsWindow = 0;
1128     m_watchersWindow = 0;
1129     m_registerWindow = 0;
1130     m_modulesWindow = 0;
1131     m_snapshotWindow = 0;
1132     m_sourceFilesWindow = 0;
1133     m_stackWindow = 0;
1134     m_threadsWindow = 0;
1135     m_logWindow = 0;
1136     m_scriptConsoleWindow = 0;
1137
1138     m_mainWindow = 0;
1139     m_snapshotHandler = 0;
1140     m_currentEngine = 0;
1141     m_debuggerSettings = 0;
1142
1143     m_gdbBinariesChanged = true;
1144     m_cmdLineEnabledEngines = AllEngineTypes;
1145
1146     m_reverseToolButton = 0;
1147     m_startAction = 0;
1148     m_startExternalAction = 0;
1149     m_startRemoteAction = 0;
1150     m_attachRemoteAction = 0;
1151     m_attachToQmlPortAction = 0;
1152     m_startRemoteCdbAction = 0;
1153     m_startRemoteLldbAction = 0;
1154     m_attachExternalAction = 0;
1155     m_attachCoreAction = 0;
1156     m_detachAction = 0;
1157
1158     m_commonOptionsPage = 0;
1159 }
1160
1161 DebuggerPluginPrivate::~DebuggerPluginPrivate()
1162 {
1163     delete m_debuggerSettings;
1164     m_debuggerSettings = 0;
1165
1166     // Mainwindow will be deleted by debug mode.
1167
1168     delete m_snapshotHandler;
1169     m_snapshotHandler = 0;
1170
1171     delete m_breakHandler;
1172     m_breakHandler = 0;
1173 }
1174
1175 DebuggerEngine *DebuggerPluginPrivate::dummyEngine()
1176 {
1177     if (!m_dummyEngine) {
1178         m_dummyEngine = new DummyEngine;
1179         m_dummyEngine->setParent(this);
1180         m_dummyEngine->setObjectName(_("DummyEngine"));
1181     }
1182     return m_dummyEngine;
1183 }
1184
1185 DebuggerCore *debuggerCore()
1186 {
1187     return theDebuggerCore;
1188 }
1189
1190 static QString msgParameterMissing(const QString &a)
1191 {
1192     return DebuggerPlugin::tr("Option '%1' is missing the parameter.").arg(a);
1193 }
1194
1195 void DebuggerPluginPrivate::maybeEnrichParameters(DebuggerStartParameters *sp)
1196 {
1197     if (!boolSetting(AutoEnrichParameters))
1198         return;
1199     if (sp->sysroot.isEmpty() && (sp->startMode == AttachToRemoteServer
1200             || sp->startMode == StartRemote)) {
1201         // FIXME: Get from BaseQtVersion.
1202         sp->sysroot = QString::fromLocal8Bit(qgetenv("QTC_DEBUGGER_SYSROOT"));
1203         showMessage(QString::fromLatin1("USING QTC_DEBUGGER_SYSROOT %1")
1204             .arg(sp->sysroot), LogWarning);
1205     }
1206     if (sp->debugInfoLocation.isEmpty())
1207         sp->debugInfoLocation = sp->sysroot + "/usr/lib/debug";
1208     if (sp->debugSourceLocation.isEmpty()) {
1209         QString base = sp->sysroot + "/usr/src/debug/";
1210         sp->debugSourceLocation.append(base + "qt5base/src/corelib");
1211         sp->debugSourceLocation.append(base + "qt5base/src/gui");
1212         sp->debugSourceLocation.append(base + "qt5base/src/network");
1213         sp->debugSourceLocation.append(base + "qt5base/src/v8");
1214         sp->debugSourceLocation.append(base + "qtdeclarative/src/declarative/qml");
1215     }
1216 }
1217
1218 bool DebuggerPluginPrivate::parseArgument(QStringList::const_iterator &it,
1219     const QStringList::const_iterator &cend,
1220     unsigned *enabledEngines, QString *errorMessage)
1221 {
1222     const QString &option = *it;
1223     // '-debug <pid>'
1224     // '-debug <corefile>'
1225     // '-debug <server:port>@<exe>@<arch>'
1226     if (*it == _("-debug")) {
1227         ++it;
1228         if (it == cend) {
1229             *errorMessage = msgParameterMissing(*it);
1230             return false;
1231         }
1232         DebuggerStartParameters sp;
1233         qulonglong pid = it->toULongLong();
1234         QString remoteChannel = it->contains('@') ? it->section('@', 0, 0) : *it;
1235         uint port = 0;
1236         int pos = remoteChannel.indexOf(QLatin1Char(':'));
1237         if (pos != -1)
1238             port = remoteChannel.mid(pos + 1).toUInt();
1239         if (pid) {
1240             sp.startMode = AttachExternal;
1241             sp.attachPID = pid;
1242             sp.displayName = tr("Process %1").arg(sp.attachPID);
1243             sp.startMessage = tr("Attaching to local process %1.").arg(sp.attachPID);
1244             sp.toolChainAbi = Abi::hostAbi();
1245         } else if (port) {
1246             sp.startMode = AttachToRemoteServer;
1247             sp.remoteChannel = remoteChannel;
1248             sp.executable = it->section('@', 1, 1);
1249             if (sp.remoteChannel.isEmpty()) {
1250                 *errorMessage = DebuggerPlugin::tr("The parameter '%1' of option "
1251                     "'%2' does not match the pattern <server:port>@<executable>@<architecture>.")
1252                         .arg(*it, option);
1253                 return false;
1254             }
1255             sp.remoteArchitecture = it->section('@', 2, 2);
1256             sp.displayName = tr("Remote: \"%1\"").arg(sp.remoteChannel);
1257             sp.startMessage = tr("Attaching to remote server %1.")
1258                 .arg(sp.remoteChannel);
1259             sp.toolChainAbi = anyAbiOfBinary(sp.executable);
1260         } else {
1261             // Fixme: Distinguish between core-file and executable by argument syntax?
1262             // (default up to 2.2 was core-file (".dmp on Windows)).
1263             const bool isExecutable = Abi::hostAbi().os() == Abi::WindowsOS ?
1264                 !it->endsWith(QLatin1String(".dmp"), Qt::CaseInsensitive) :
1265                 QFileInfo(*it).isExecutable();
1266             if (isExecutable) {
1267                 sp.startMode = StartExternal;
1268                 sp.executable = *it;
1269                 sp.displayName = tr("Executable file \"%1\"").arg(sp.executable);
1270                 sp.startMessage = tr("Debugging file %1.").arg(sp.executable);
1271             } else {
1272                 sp.startMode = AttachCore;
1273                 sp.coreFile = *it;
1274                 sp.displayName = tr("Core file \"%1\"").arg(sp.coreFile);
1275                 sp.startMessage = tr("Attaching to core file %1.").arg(sp.coreFile);
1276             }
1277             sp.toolChainAbi = anyAbiOfBinary(*it);
1278         }
1279         m_scheduledStarts.append(sp);
1280         return true;
1281     }
1282     // -wincrashevent <event-handle>:<pid>. A handle used for
1283     // a handshake when attaching to a crashed Windows process.
1284     // This is created by $QTC/src/tools/qtcdebugger/main.cpp:
1285     // args << QLatin1String("-wincrashevent")
1286     //   << QString("%1:%2").arg(argWinCrashEvent).arg(argProcessId);
1287     if (*it == _("-wincrashevent")) {
1288         ++it;
1289         if (it == cend) {
1290             *errorMessage = msgParameterMissing(*it);
1291             return false;
1292         }
1293         DebuggerStartParameters sp;
1294         sp.startMode = AttachCrashedExternal;
1295         sp.crashParameter = it->section(':', 0, 0);
1296         sp.attachPID = it->section(':', 1, 1).toULongLong();
1297         sp.displayName = tr("Crashed process %1").arg(sp.attachPID);
1298         sp.startMessage = tr("Attaching to crashed process %1").arg(sp.attachPID);
1299         sp.toolChainAbi = Abi::hostAbi();
1300         if (!sp.attachPID) {
1301             *errorMessage = DebuggerPlugin::tr("The parameter '%1' of option '%2' "
1302                 "does not match the pattern <handle>:<pid>.").arg(*it, option);
1303             return false;
1304         }
1305         m_scheduledStarts.append(sp);
1306         return true;
1307     }
1308     // Engine disabling.
1309     if (option == _("-disable-cdb")) {
1310         *enabledEngines &= ~CdbEngineType;
1311         return true;
1312     }
1313     if (option == _("-disable-gdb")) {
1314         *enabledEngines &= ~GdbEngineType;
1315         return true;
1316     }
1317     if (option == _("-disable-qmldb")) {
1318         *enabledEngines &= ~QmlEngineType;
1319         return true;
1320     }
1321     if (option == _("-disable-sdb")) {
1322         *enabledEngines &= ~ScriptEngineType;
1323         return true;
1324     }
1325     if (option == _("-disable-lldb")) {
1326         *enabledEngines &= ~LldbEngineType;
1327         return true;
1328     }
1329
1330     *errorMessage = DebuggerPlugin::tr("Invalid debugger option: %1").arg(option);
1331     return false;
1332 }
1333
1334 bool DebuggerPluginPrivate::parseArguments(const QStringList &args,
1335    unsigned *enabledEngines, QString *errorMessage)
1336 {
1337     const QStringList::const_iterator cend = args.constEnd();
1338     for (QStringList::const_iterator it = args.constBegin(); it != cend; ++it)
1339         if (!parseArgument(it, cend, enabledEngines, errorMessage))
1340             return false;
1341     if (Constants::Internal::debug)
1342         qDebug().nospace() << args << "engines=0x"
1343             << QString::number(*enabledEngines, 16) << '\n';
1344     return true;
1345 }
1346
1347 bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
1348     QString *errorMessage)
1349 {
1350     Q_UNUSED(errorMessage);
1351     m_arguments = arguments;
1352     // Cpp/Qml ui setup
1353     m_mainWindow = new DebuggerMainWindow;
1354
1355     return true;
1356 }
1357
1358 void DebuggerPluginPrivate::setConfigValue(const QString &name, const QVariant &value)
1359 {
1360     m_coreSettings->setValue(_("DebugMode/") + name, value);
1361 }
1362
1363 QVariant DebuggerPluginPrivate::configValue(const QString &name) const
1364 {
1365     const QVariant value = m_coreSettings->value(_("DebugMode/") + name);
1366     if (value.isValid())
1367         return value;
1368     // Legacy (pre-2.1): Check old un-namespaced-settings.
1369     return m_coreSettings->value(name);
1370 }
1371
1372 void DebuggerPluginPrivate::onCurrentProjectChanged(Project *project)
1373 {
1374     RunConfiguration *activeRc = 0;
1375     if (project) {
1376         Target *target = project->activeTarget();
1377         QTC_ASSERT(target, return);
1378         activeRc = target->activeRunConfiguration();
1379         QTC_CHECK(activeRc);
1380     }
1381     for (int i = 0, n = m_snapshotHandler->size(); i != n; ++i) {
1382         // Run controls might be deleted during exit.
1383         if (DebuggerEngine *engine = m_snapshotHandler->at(i)) {
1384             DebuggerRunControl *runControl = engine->runControl();
1385             RunConfiguration *rc = runControl->runConfiguration();
1386             if (rc == activeRc) {
1387                 m_snapshotHandler->setCurrentIndex(i);
1388                 updateState(engine);
1389                 return;
1390             }
1391         }
1392     }
1393     // No corresponding debugger found. So we are ready to start one.
1394     m_interruptAction->setEnabled(false);
1395     m_continueAction->setEnabled(false);
1396     m_exitAction->setEnabled(false);
1397     m_startAction->setEnabled(true);
1398     m_visibleStartAction->setAction(m_startAction);
1399 }
1400
1401 void DebuggerPluginPrivate::languagesChanged()
1402 {
1403 }
1404
1405 void DebuggerPluginPrivate::debugProject()
1406 {
1407     ProjectExplorerPlugin *pe = ProjectExplorerPlugin::instance();
1408     if (Project *pro = pe->startupProject())
1409         pe->runProject(pro, Constants::DEBUGMODE);
1410 }
1411
1412 void DebuggerPluginPrivate::debugProjectBreakMain()
1413 {
1414     ProjectExplorerPlugin *pe = ProjectExplorerPlugin::instance();
1415     if (Project *pro = pe->startupProject())
1416         pe->runProject(pro, Constants::DEBUGMODE2);
1417 }
1418
1419 void DebuggerPluginPrivate::startExternalApplication()
1420 {
1421     DebuggerStartParameters sp;
1422     StartExternalDialog dlg(mainWindow());
1423     dlg.setExecutableFile(
1424             configValue(_("LastExternalExecutableFile")).toString());
1425     dlg.setExecutableArguments(
1426             configValue(_("LastExternalExecutableArguments")).toString());
1427     dlg.setRunInTerminal(
1428             configValue(_("LastExternalRunInTerminal")).toBool());
1429     dlg.setWorkingDirectory(
1430             configValue(_("LastExternalWorkingDirectory")).toString());
1431     dlg.setAbiIndex(configValue(_("LastExternalAbiIndex")).toInt());
1432
1433     if (dlg.exec() != QDialog::Accepted)
1434         return;
1435
1436     setConfigValue(_("LastExternalExecutableFile"),
1437                    dlg.executableFile());
1438     setConfigValue(_("LastExternalExecutableArguments"),
1439                    dlg.executableArguments());
1440     setConfigValue(_("LastExternalWorkingDirectory"),
1441                    dlg.workingDirectory());
1442     setConfigValue(_("LastExternalRunInTerminal"),
1443                    dlg.runInTerminal());
1444     setConfigValue(_("LastExternalAbiIndex"), QVariant(dlg.abiIndex()));
1445
1446     sp.executable = dlg.executableFile();
1447     sp.startMode = StartExternal;
1448     sp.toolChainAbi = dlg.abi();
1449     sp.debuggerCommand = dlg.debuggerCommand();
1450     sp.workingDirectory = dlg.workingDirectory();
1451     sp.displayName = sp.executable;
1452     sp.useTerminal = dlg.runInTerminal();
1453     if (!dlg.executableArguments().isEmpty())
1454         sp.processArgs = dlg.executableArguments();
1455     // Fixme: 1 of 3 testing hacks.
1456     if (sp.processArgs.startsWith(__("@tcf@ ")) || sp.processArgs.startsWith(__("@sym@ ")))
1457         // Set up an ARM Symbian Abi
1458         sp.toolChainAbi = Abi(Abi::ArmArchitecture, Abi::SymbianOS, Abi::SymbianDeviceFlavor, Abi::ElfFormat, false);
1459
1460     sp.breakOnMain = dlg.breakAtMain();
1461     if (RunControl *rc = m_debuggerRunControlFactory->create(sp))
1462         startDebugger(rc);
1463 }
1464
1465 void DebuggerPluginPrivate::attachExternalApplication()
1466 {
1467     AttachExternalDialog dlg(mainWindow());
1468     dlg.setAbiIndex(configValue(_("LastAttachExternalAbiIndex")).toInt());
1469
1470     if (dlg.exec() != QDialog::Accepted)
1471         return;
1472
1473     if (dlg.attachPID() == 0) {
1474         QMessageBox::warning(mainWindow(), tr("Warning"),
1475             tr("Cannot attach to process with PID 0"));
1476         return;
1477     }
1478
1479     setConfigValue(_("LastAttachExternalAbiIndex"), QVariant(dlg.abiIndex()));
1480
1481     DebuggerStartParameters sp;
1482     sp.attachPID = dlg.attachPID();
1483     sp.displayName = tr("Process %1").arg(dlg.attachPID());
1484     sp.executable = dlg.executable();
1485     sp.startMode = AttachExternal;
1486     sp.toolChainAbi = dlg.abi();
1487     sp.debuggerCommand = dlg.debuggerCommand();
1488     if (DebuggerRunControl *rc = createDebugger(sp))
1489         startDebugger(rc);
1490 }
1491
1492 void DebuggerPluginPrivate::attachExternalApplication(ProjectExplorer::RunControl *rc)
1493 {
1494     DebuggerStartParameters sp;
1495     sp.attachPID = rc->applicationProcessHandle().pid();
1496     sp.displayName = tr("Debugger attached to %1").arg(rc->displayName());
1497     sp.startMode = AttachExternal;
1498     sp.toolChainAbi = rc->abi();
1499     if (DebuggerRunControl *rc = createDebugger(sp))
1500         startDebugger(rc);
1501 }
1502
1503 void DebuggerPluginPrivate::attachCore()
1504 {
1505     AttachCoreDialog dlg(mainWindow());
1506     dlg.setExecutableFile(configValue(_("LastExternalExecutableFile")).toString());
1507     dlg.setCoreFile(configValue(_("LastExternalCoreFile")).toString());
1508     dlg.setAbiIndex(configValue(_("LastExternalCoreAbiIndex")).toInt());
1509     dlg.setSysroot(configValue(_("LastSysroot")).toString());
1510     dlg.setOverrideStartScript(configValue(_("LastExternalStartScript")).toString());
1511
1512     if (dlg.exec() != QDialog::Accepted)
1513         return;
1514
1515     setConfigValue(_("LastExternalExecutableFile"), dlg.executableFile());
1516     setConfigValue(_("LastExternalCoreFile"), dlg.coreFile());
1517     setConfigValue(_("LastExternalCoreAbiIndex"), QVariant(dlg.abiIndex()));
1518     setConfigValue(_("LastSysroot"), dlg.sysroot());
1519     setConfigValue(_("LastExternalStartScript"), dlg.overrideStartScript());
1520
1521     DebuggerStartParameters sp;
1522     sp.executable = dlg.executableFile();
1523     sp.coreFile = dlg.coreFile();
1524     sp.displayName = tr("Core file \"%1\"").arg(dlg.coreFile());
1525     sp.startMode = AttachCore;
1526     sp.debuggerCommand = dlg.debuggerCommand();
1527     sp.toolChainAbi = dlg.abi();
1528     sp.sysroot = dlg.sysroot();
1529     sp.overrideStartScript = dlg.overrideStartScript();
1530     if (DebuggerRunControl *rc = createDebugger(sp))
1531         startDebugger(rc);
1532 }
1533
1534 void DebuggerPluginPrivate::attachRemote(const QString &spec)
1535 {
1536     // spec is: server:port@executable@architecture
1537     DebuggerStartParameters sp;
1538     sp.remoteChannel = spec.section('@', 0, 0);
1539     sp.executable = spec.section('@', 1, 1);
1540     sp.remoteArchitecture = spec.section('@', 2, 2);
1541     sp.displayName = tr("Remote: \"%1\"").arg(sp.remoteChannel);
1542     sp.startMode = AttachToRemoteServer;
1543     sp.toolChainAbi = anyAbiOfBinary(sp.executable);
1544     if (DebuggerRunControl *rc = createDebugger(sp))
1545         startDebugger(rc);
1546 }
1547
1548 void DebuggerPluginPrivate::startRemoteCdbSession()
1549 {
1550     const QString connectionKey = _("CdbRemoteConnection");
1551     DebuggerStartParameters sp;
1552     Abi hostAbi = Abi::hostAbi();
1553     sp.toolChainAbi = ProjectExplorer::Abi(hostAbi.architecture(),
1554                                            ProjectExplorer::Abi::WindowsOS,
1555                                            ProjectExplorer::Abi::WindowsMsvc2010Flavor,
1556                                            ProjectExplorer::Abi::PEFormat,
1557                                            hostAbi.wordWidth());
1558     sp.startMode = AttachToRemoteServer;
1559     StartRemoteCdbDialog dlg(mainWindow());
1560     QString previousConnection = configValue(connectionKey).toString();
1561     if (previousConnection.isEmpty())
1562         previousConnection = QLatin1String("localhost:1234");
1563     dlg.setConnection(previousConnection);
1564     if (dlg.exec() != QDialog::Accepted)
1565         return;
1566     sp.remoteChannel = dlg.connection();
1567     setConfigValue(connectionKey, sp.remoteChannel);
1568     if (RunControl *rc = createDebugger(sp))
1569         startDebugger(rc);
1570 }
1571
1572 bool DebuggerPluginPrivate::queryRemoteParameters(DebuggerStartParameters &sp, bool useScript)
1573 {
1574     StartRemoteDialog dlg(mainWindow(), useScript);
1575     QStringList arches;
1576     arches.append(_("i386:x86-64:intel"));
1577     arches.append(_("i386"));
1578     arches.append(_("arm"));
1579     QString lastUsed = configValue(_("LastRemoteArchitecture")).toString();
1580     if (!arches.contains(lastUsed))
1581         arches.prepend(lastUsed);
1582     dlg.setRemoteArchitectures(arches);
1583     QStringList gnuTargets;
1584     gnuTargets.append(_("auto"));
1585     gnuTargets.append(_("i686-linux-gnu"));
1586     gnuTargets.append(_("x86_64-linux-gnu"));
1587     gnuTargets.append(_("arm-none-linux-gnueabi"));
1588     const QString lastUsedGnuTarget
1589         = configValue(_("LastGnuTarget")).toString();
1590     if (!gnuTargets.contains(lastUsedGnuTarget))
1591         gnuTargets.prepend(lastUsedGnuTarget);
1592     dlg.setGnuTargets(gnuTargets);
1593     dlg.setRemoteChannel(
1594             configValue(_("LastRemoteChannel")).toString());
1595     dlg.setLocalExecutable(
1596             configValue(_("LastLocalExecutable")).toString());
1597     dlg.setDebugger(configValue(_("LastDebugger")).toString());
1598     dlg.setRemoteArchitecture(lastUsed);
1599     dlg.setGnuTarget(lastUsedGnuTarget);
1600     dlg.setOverrideStartScript(configValue(_("LastRemoteStartScript")).toString());
1601     dlg.setServerStartScript(
1602             configValue(_("LastServerStartScript")).toString());
1603     dlg.setUseServerStartScript(
1604             configValue(_("LastUseServerStartScript")).toBool());
1605     dlg.setSysroot(configValue(_("LastSysroot")).toString());
1606     dlg.setDebugInfoLocation(configValue(_("LastDebugInfoLocation")).toString());
1607     if (dlg.exec() != QDialog::Accepted)
1608         return false;
1609     setConfigValue(_("LastRemoteChannel"), dlg.remoteChannel());
1610     setConfigValue(_("LastLocalExecutable"), dlg.localExecutable());
1611     setConfigValue(_("LastDebugger"), dlg.debugger());
1612     setConfigValue(_("LastRemoteArchitecture"), dlg.remoteArchitecture());
1613     setConfigValue(_("LastGnuTarget"), dlg.gnuTarget());
1614     setConfigValue(_("LastRemoteStartScript"), dlg.overrideStartScript());
1615     setConfigValue(_("LastServerStartScript"), dlg.serverStartScript());
1616     setConfigValue(_("LastUseServerStartScript"), dlg.useServerStartScript());
1617     setConfigValue(_("LastSysroot"), dlg.sysroot());
1618     setConfigValue(_("LastDebugInfoLocation"), dlg.debugInfoLocation());
1619     sp.remoteChannel = dlg.remoteChannel();
1620     sp.remoteArchitecture = dlg.remoteArchitecture();
1621     sp.gnuTarget = dlg.gnuTarget();
1622     sp.executable = dlg.localExecutable();
1623     sp.displayName = tr("Remote: \"%1\"").arg(sp.remoteChannel);
1624     sp.debuggerCommand = dlg.debugger(); // Override toolchain-detection.
1625     if (!sp.debuggerCommand.isEmpty())
1626         sp.toolChainAbi = ProjectExplorer::Abi();
1627     sp.overrideStartScript = dlg.overrideStartScript();
1628     sp.useServerStartScript = dlg.useServerStartScript();
1629     sp.serverStartScript = dlg.serverStartScript();
1630     sp.sysroot = dlg.sysroot();
1631     sp.debugInfoLocation = dlg.debugInfoLocation();
1632     return true;
1633 }
1634
1635 void DebuggerPluginPrivate::startRemoteApplication()
1636 {
1637     DebuggerStartParameters sp;
1638     sp.startMode = StartRemote;
1639     if (!queryRemoteParameters(sp, true))
1640         return;
1641     if (RunControl *rc = createDebugger(sp))
1642         startDebugger(rc);
1643 }
1644
1645 void DebuggerPluginPrivate::attachRemoteApplication()
1646 {
1647     DebuggerStartParameters sp;
1648     if (!queryRemoteParameters(sp, false))
1649         return;
1650     sp.startMode = AttachToRemoteServer;
1651     sp.useServerStartScript = false;
1652     sp.serverStartScript.clear();
1653     if (RunControl *rc = createDebugger(sp))
1654         startDebugger(rc);
1655 }
1656
1657 void DebuggerPluginPrivate::attachToQmlPort()
1658 {
1659     DebuggerStartParameters sp;
1660     AttachToQmlPortDialog dlg(mainWindow());
1661
1662     const QVariant qmlServerAddress = configValue(_("LastQmlServerAddress"));
1663     if (qmlServerAddress.isValid()) {
1664         dlg.setHost(qmlServerAddress.toString());
1665     } else {
1666         dlg.setHost(sp.qmlServerAddress);
1667     }
1668
1669     const QVariant qmlServerPort = configValue(_("LastQmlServerPort"));
1670     if (qmlServerPort.isValid()) {
1671         dlg.setPort(qmlServerPort.toInt());
1672     } else {
1673         dlg.setPort(sp.qmlServerPort);
1674     }
1675
1676     if (dlg.exec() != QDialog::Accepted)
1677         return;
1678
1679     setConfigValue(_("LastQmlServerAddress"), dlg.host());
1680     setConfigValue(_("LastQmlServerPort"), dlg.port());
1681
1682     sp.qmlServerAddress = dlg.host();
1683     sp.qmlServerPort = dlg.port();
1684
1685     sp.startMode = AttachToQmlPort;
1686     if (RunControl *rc = createDebugger(sp))
1687         startDebugger(rc);
1688 }
1689
1690 void DebuggerPluginPrivate::startRemoteEngine()
1691 {
1692     DebuggerStartParameters sp;
1693     StartRemoteEngineDialog dlg(mainWindow());
1694     if (dlg.exec() != QDialog::Accepted)
1695         return;
1696
1697     sp.connParams.host = dlg.host();
1698     sp.connParams.userName = dlg.username();
1699     sp.connParams.password = dlg.password();
1700
1701     sp.connParams.timeout = 5;
1702     sp.connParams.authenticationType = Utils::SshConnectionParameters::AuthenticationByPassword;
1703     sp.connParams.port = 22;
1704     sp.connParams.proxyType = Utils::SshConnectionParameters::NoProxy;
1705
1706     sp.executable = dlg.inferiorPath();
1707     sp.serverStartScript = dlg.enginePath();
1708     sp.startMode = StartRemoteEngine;
1709     if (RunControl *rc = createDebugger(sp))
1710         startDebugger(rc);
1711 }
1712
1713 void DebuggerPluginPrivate::enableReverseDebuggingTriggered(const QVariant &value)
1714 {
1715     QTC_ASSERT(m_reverseToolButton, return);
1716     m_reverseToolButton->setVisible(value.toBool());
1717     m_reverseDirectionAction->setChecked(false);
1718     m_reverseDirectionAction->setEnabled(value.toBool());
1719 }
1720
1721 void DebuggerPluginPrivate::runScheduled()
1722 {
1723     foreach (const DebuggerStartParameters &sp, m_scheduledStarts) {
1724         RunControl *rc = createDebugger(sp);
1725         QTC_ASSERT(rc, qDebug() << "CANNOT CREATE RUN CONTROL"; continue);
1726         showStatusMessage(sp.startMessage);
1727         startDebugger(rc);
1728     }
1729 }
1730
1731 void DebuggerPluginPrivate::editorOpened(IEditor *editor)
1732 {
1733     if (!isEditorDebuggable(editor))
1734         return;
1735     ITextEditor *textEditor = qobject_cast<ITextEditor *>(editor);
1736     if (!textEditor)
1737         return;
1738     connect(textEditor,
1739         SIGNAL(markRequested(TextEditor::ITextEditor*,int)),
1740         SLOT(requestMark(TextEditor::ITextEditor*,int)));
1741     connect(textEditor,
1742         SIGNAL(markContextMenuRequested(TextEditor::ITextEditor*,int,QMenu*)),
1743         SLOT(requestContextMenu(TextEditor::ITextEditor*,int,QMenu*)));
1744 }
1745
1746 void DebuggerPluginPrivate::updateBreakMenuItem(Core::IEditor *editor)
1747 {
1748     ITextEditor *textEditor = qobject_cast<ITextEditor *>(editor);
1749     m_breakAction->setEnabled(textEditor != 0);
1750 }
1751
1752 void DebuggerPluginPrivate::requestContextMenu(ITextEditor *editor,
1753     int lineNumber, QMenu *menu)
1754 {
1755     if (!isEditorDebuggable(editor))
1756         return;
1757
1758     BreakpointMenuContextData args;
1759     args.lineNumber = lineNumber;
1760     bool contextUsable = true;
1761
1762     BreakpointModelId id = BreakpointModelId();
1763     if (editor->property("DisassemblerView").toBool()) {
1764         args.fileName = editor->file()->fileName();
1765         QString line = editor->contents()
1766             .section('\n', lineNumber - 1, lineNumber - 1);
1767         BreakpointResponse needle;
1768         needle.type = BreakpointByAddress;
1769         needle.address = DisassemblerLine::addressFromDisassemblyLine(line);
1770         args.address = needle.address;
1771         needle.lineNumber = -1;
1772         id = breakHandler()->findSimilarBreakpoint(needle);
1773         contextUsable = args.address != 0;
1774     } else {
1775         args.fileName = editor->file()->fileName();
1776         id = breakHandler()
1777             ->findBreakpointByFileAndLine(args.fileName, lineNumber);
1778     }
1779
1780     if (id) {
1781         // Remove existing breakpoint.
1782         QAction *act = new QAction(menu);
1783         act->setData(QVariant::fromValue(id));
1784         act->setText(tr("Remove Breakpoint %1").arg(id.toString()));
1785         connect(act, SIGNAL(triggered()),
1786             SLOT(breakpointRemoveMarginActionTriggered()));
1787         menu->addAction(act);
1788
1789         // Enable/disable existing breakpoint.
1790         act = new QAction(menu);
1791         act->setData(QVariant::fromValue(id));
1792         if (breakHandler()->isEnabled(id)) {
1793             act->setText(tr("Disable Breakpoint %1").arg(id.toString()));
1794             connect(act, SIGNAL(triggered()),
1795                 SLOT(breakpointDisableMarginActionTriggered()));
1796         } else {
1797             act->setText(tr("Enable Breakpoint %1").arg(id.toString()));
1798             connect(act, SIGNAL(triggered()),
1799                 SLOT(breakpointEnableMarginActionTriggered()));
1800         }
1801         menu->addAction(act);
1802
1803         // Edit existing breakpoint.
1804         act = new QAction(menu);
1805         act->setText(tr("Edit Breakpoint %1...").arg(id.toString()));
1806         connect(act, SIGNAL(triggered()), SLOT(slotEditBreakpoint()));
1807         act->setData(QVariant::fromValue(id));
1808         menu->addAction(act);
1809     } else {
1810         // Handle non-existing breakpoint.
1811         const QString text = args.address
1812             ? tr("Set Breakpoint at 0x%1").arg(args.address, 0, 16)
1813             : tr("Set Breakpoint at line %1").arg(lineNumber);
1814         QAction *act = new QAction(text, menu);
1815         act->setData(QVariant::fromValue(args));
1816         act->setEnabled(contextUsable);
1817         connect(act, SIGNAL(triggered()),
1818             SLOT(breakpointSetMarginActionTriggered()));
1819         menu->addAction(act);
1820         // Message trace point
1821         args.mode = BreakpointMenuContextData::MessageTracePoint;
1822         const QString tracePointText = args.address
1823             ? tr("Set Message Tracepoint at 0x%1...").arg(args.address, 0, 16)
1824             : tr("Set Message Tracepoint at line %1...").arg(lineNumber);
1825         act = new QAction(tracePointText, menu);
1826         act->setData(QVariant::fromValue(args));
1827         act->setEnabled(contextUsable);
1828         connect(act, SIGNAL(triggered()),
1829             SLOT(breakpointSetMarginActionTriggered()));
1830         menu->addAction(act);
1831     }
1832     // Run to, jump to line below in stopped state.
1833     if (currentEngine()->state() == InferiorStopOk && contextUsable) {
1834         menu->addSeparator();
1835         if (currentEngine()->debuggerCapabilities() & RunToLineCapability) {
1836             const QString runText = args.address
1837                 ? DebuggerEngine::tr("Run to Address 0x%1").arg(args.address, 0, 16)
1838                 : DebuggerEngine::tr("Run to Line %1").arg(args.lineNumber);
1839             QAction *runToLineAction  = new QAction(runText, menu);
1840             runToLineAction->setData(QVariant::fromValue(args));
1841             connect(runToLineAction, SIGNAL(triggered()), SLOT(slotRunToLine()));
1842             menu->addAction(runToLineAction);
1843         }
1844         if (currentEngine()->debuggerCapabilities() & JumpToLineCapability) {
1845             const QString jumpText = args.address
1846                 ? DebuggerEngine::tr("Jump to Address 0x%1").arg(args.address, 0, 16)
1847                 : DebuggerEngine::tr("Jump to Line %1").arg(args.lineNumber);
1848             QAction *jumpToLineAction  = new QAction(jumpText, menu);
1849             jumpToLineAction->setData(QVariant::fromValue(args));
1850             connect(jumpToLineAction, SIGNAL(triggered()), SLOT(slotJumpToLine()));
1851             menu->addAction(jumpToLineAction);
1852         }
1853     }
1854 }
1855
1856 void DebuggerPluginPrivate::toggleBreakpoint()
1857 {
1858     ITextEditor *textEditor = currentTextEditor();
1859     QTC_ASSERT(textEditor, return);
1860     const int lineNumber = textEditor->currentLine();
1861     if (textEditor->property("DisassemblerView").toBool()) {
1862         QString line = textEditor->contents()
1863             .section('\n', lineNumber - 1, lineNumber - 1);
1864         quint64 address = DisassemblerLine::addressFromDisassemblyLine(line);
1865         toggleBreakpointByAddress(address);
1866     } else if (lineNumber >= 0) {
1867         toggleBreakpointByFileAndLine(textEditor->file()->fileName(), lineNumber);
1868     }
1869 }
1870
1871 void DebuggerPluginPrivate::toggleBreakpointByFileAndLine(const QString &fileName,
1872     int lineNumber, const QString &tracePointMessage)
1873 {
1874     BreakHandler *handler = m_breakHandler;
1875     BreakpointModelId id =
1876         handler->findBreakpointByFileAndLine(fileName, lineNumber, true);
1877     if (!id)
1878         id = handler->findBreakpointByFileAndLine(fileName, lineNumber, false);
1879
1880     if (id) {
1881         handler->removeBreakpoint(id);
1882     } else {
1883         BreakpointParameters data(BreakpointByFileAndLine);
1884         data.tracepoint = !tracePointMessage.isEmpty();
1885         data.message = tracePointMessage;
1886         data.fileName = fileName;
1887         data.lineNumber = lineNumber;
1888         handler->appendBreakpoint(data);
1889     }
1890 }
1891
1892 void DebuggerPluginPrivate::toggleBreakpointByAddress(quint64 address,
1893                                                       const QString &tracePointMessage)
1894 {
1895     BreakHandler *handler = m_breakHandler;
1896     BreakpointModelId id = handler->findBreakpointByAddress(address);
1897
1898     if (id) {
1899         handler->removeBreakpoint(id);
1900     } else {
1901         BreakpointParameters data(BreakpointByAddress);
1902         data.tracepoint = !tracePointMessage.isEmpty();
1903         data.message = tracePointMessage;
1904         data.address = address;
1905         handler->appendBreakpoint(data);
1906     }
1907 }
1908
1909 void DebuggerPluginPrivate::requestMark(ITextEditor *editor, int lineNumber)
1910 {
1911     if (editor->property("DisassemblerView").toBool()) {
1912         QString line = editor->contents()
1913             .section('\n', lineNumber - 1, lineNumber - 1);
1914         quint64 address = DisassemblerLine::addressFromDisassemblyLine(line);
1915         toggleBreakpointByAddress(address);
1916     } else if (editor->file()) {
1917         toggleBreakpointByFileAndLine(editor->file()->fileName(), lineNumber);
1918     }
1919 }
1920
1921 DebuggerRunControl *DebuggerPluginPrivate::createDebugger
1922     (const DebuggerStartParameters &sp0, RunConfiguration *rc)
1923 {
1924     DebuggerStartParameters sp = sp0;
1925     maybeEnrichParameters(&sp);
1926     return m_debuggerRunControlFactory->create(sp, rc);
1927 }
1928
1929 // If updateEngine is set, the engine will update its threads/modules and so forth.
1930 void DebuggerPluginPrivate::displayDebugger(DebuggerEngine *engine, bool updateEngine)
1931 {
1932     QTC_ASSERT(engine, return);
1933     disconnectEngine();
1934     connectEngine(engine);
1935     if (updateEngine)
1936         engine->updateAll();
1937     engine->updateViews();
1938 }
1939
1940 void DebuggerPluginPrivate::startDebugger(RunControl *rc)
1941 {
1942     QTC_ASSERT(rc, return);
1943     ProjectExplorerPlugin::instance()->startRunControl(rc, Constants::DEBUGMODE);
1944 }
1945
1946
1947 void DebuggerPluginPrivate::connectEngine(DebuggerEngine *engine)
1948 {
1949     if (!engine)
1950         engine = dummyEngine();
1951
1952     if (m_currentEngine == engine)
1953         return;
1954
1955     if (m_currentEngine)
1956         m_currentEngine->resetLocation();
1957     m_currentEngine = engine;
1958
1959     m_localsWindow->setModel(engine->localsModel());
1960     m_modulesWindow->setModel(engine->modulesModel());
1961     m_registerWindow->setModel(engine->registerModel());
1962     m_returnWindow->setModel(engine->returnModel());
1963     m_sourceFilesWindow->setModel(engine->sourceFilesModel());
1964     m_stackWindow->setModel(engine->stackModel());
1965     m_threadsWindow->setModel(engine->threadsModel());
1966     //m_threadBox->setModel(engine->threadsModel());
1967     //m_threadBox->setModelColumn(ThreadData::ComboNameColumn);
1968     m_watchersWindow->setModel(engine->watchersModel());
1969     engine->watchHandler()->rebuildModel();
1970 }
1971
1972 static void changeFontSize(QWidget *widget, qreal size)
1973 {
1974     QFont font = widget->font();
1975     font.setPointSizeF(size);
1976     widget->setFont(font);
1977 }
1978
1979 void DebuggerPluginPrivate::fontSettingsChanged
1980     (const TextEditor::FontSettings &settings)
1981 {
1982     if (!boolSetting(FontSizeFollowsEditor))
1983         return;
1984     qreal size = settings.fontZoom() * settings.fontSize() / 100.;
1985     changeFontSize(m_breakWindow, size);
1986     changeFontSize(m_logWindow, size);
1987     changeFontSize(m_localsWindow, size);
1988     changeFontSize(m_modulesWindow, size);
1989     //changeFontSize(m_consoleWindow, size);
1990     changeFontSize(m_registerWindow, size);
1991     changeFontSize(m_returnWindow, size);
1992     changeFontSize(m_sourceFilesWindow, size);
1993     changeFontSize(m_stackWindow, size);
1994     changeFontSize(m_threadsWindow, size);
1995     changeFontSize(m_watchersWindow, size);
1996 }
1997
1998 void DebuggerPluginPrivate::cleanupViews()
1999 {
2000     m_reverseDirectionAction->setChecked(false);
2001     m_reverseDirectionAction->setEnabled(false);
2002
2003     if (!boolSetting(CloseBuffersOnExit))
2004         return;
2005
2006     EditorManager *editorManager = EditorManager::instance();
2007     QTC_ASSERT(editorManager, return);
2008     QList<IEditor *> toClose;
2009     foreach (IEditor *editor, editorManager->openedEditors()) {
2010         if (editor->property(Constants::OPENED_BY_DEBUGGER).toBool()) {
2011             // Close disassembly views. Close other opened files
2012             // if they are not modified and not current editor.
2013             if (editor->property(Constants::OPENED_WITH_DISASSEMBLY).toBool()
2014                     || (!editor->file()->isModified()
2015                         && editor != editorManager->currentEditor())) {
2016                 toClose.append(editor);
2017             } else {
2018                 editor->setProperty(Constants::OPENED_BY_DEBUGGER, false);
2019             }
2020         }
2021     }
2022     editorManager->closeEditors(toClose);
2023 }
2024
2025 void DebuggerPluginPrivate::setBusyCursor(bool busy)
2026 {
2027     //STATE_DEBUG("BUSY FROM: " << m_busy << " TO: " << busy);
2028     if (busy == m_busy)
2029         return;
2030     m_busy = busy;
2031     QCursor cursor(busy ? Qt::BusyCursor : Qt::ArrowCursor);
2032     m_breakWindow->setCursor(cursor);
2033     //m_consoleWindow->setCursor(cursor);
2034     m_localsWindow->setCursor(cursor);
2035     m_modulesWindow->setCursor(cursor);
2036     m_logWindow->setCursor(cursor);
2037     m_registerWindow->setCursor(cursor);
2038     m_returnWindow->setCursor(cursor);
2039     m_sourceFilesWindow->setCursor(cursor);
2040     m_stackWindow->setCursor(cursor);
2041     m_threadsWindow->setCursor(cursor);
2042     m_watchersWindow->setCursor(cursor);
2043     m_snapshotWindow->setCursor(cursor);
2044     m_scriptConsoleWindow->setCursor(cursor);
2045 }
2046
2047 void DebuggerPluginPrivate::setInitialState()
2048 {
2049     m_watchersWindow->setVisible(false);
2050     m_returnWindow->setVisible(false);
2051     setBusyCursor(false);
2052     m_reverseDirectionAction->setChecked(false);
2053     m_reverseDirectionAction->setEnabled(false);
2054     m_toolTipManager->closeAllToolTips();
2055
2056     m_startExternalAction->setEnabled(true);
2057     m_attachExternalAction->setEnabled(true);
2058     m_attachToQmlPortAction->setEnabled(true);
2059     m_attachCoreAction->setEnabled(true);
2060     m_startRemoteAction->setEnabled(true);
2061     m_attachRemoteAction->setEnabled(true);
2062     m_detachAction->setEnabled(false);
2063
2064     m_watchAction1->setEnabled(true);
2065     m_watchAction2->setEnabled(true);
2066     m_breakAction->setEnabled(false);
2067     //m_snapshotAction->setEnabled(false);
2068     action(OperateByInstruction)->setEnabled(false);
2069
2070     m_exitAction->setEnabled(false);
2071     m_resetAction->setEnabled(false);
2072
2073     m_interruptAction->setEnabled(false);
2074     m_continueAction->setEnabled(false);
2075
2076     m_stepAction->setEnabled(true);
2077     m_stepOutAction->setEnabled(false);
2078     m_runToLineAction->setEnabled(false);
2079     m_runToSelectedFunctionAction->setEnabled(true);
2080     m_returnFromFunctionAction->setEnabled(false);
2081     m_jumpToLineAction->setEnabled(false);
2082     m_nextAction->setEnabled(true);
2083
2084     action(AutoDerefPointers)->setEnabled(true);
2085     action(ExpandStack)->setEnabled(false);
2086
2087     m_scriptConsoleWindow->setEnabled(false);
2088 }
2089
2090 void DebuggerPluginPrivate::updateWatchersWindow()
2091 {
2092     m_watchersWindow->setVisible(
2093         m_watchersWindow->model()->rowCount(QModelIndex()) > 0);
2094     m_returnWindow->setVisible(
2095         m_returnWindow->model()->rowCount(QModelIndex()) > 0);
2096 }
2097
2098 void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
2099 {
2100     QTC_ASSERT(engine, return);
2101     QTC_ASSERT(m_watchersWindow->model(), return);
2102     QTC_ASSERT(m_returnWindow->model(), return);
2103     QTC_ASSERT(!engine->isSlaveEngine(), return);
2104
2105     m_threadBox->setCurrentIndex(engine->threadsHandler()->currentThread());
2106
2107     updateWatchersWindow();
2108
2109     const DebuggerState state = engine->state();
2110     //showMessage(QString("PLUGIN SET STATE: ")
2111     //    + DebuggerEngine::stateName(state), LogStatus);
2112     //qDebug() << "PLUGIN SET STATE: " << state;
2113
2114     static DebuggerState previousState = DebuggerNotReady;
2115     if (state == previousState)
2116         return;
2117
2118     bool actionsEnabled = DebuggerEngine::debuggerActionsEnabled(state);
2119
2120     if (state == DebuggerNotReady) {
2121         QTC_ASSERT(false, /* We use the Core's m_debugAction here */);
2122         // F5 starts debugging. It is "startable".
2123         m_interruptAction->setEnabled(false);
2124         m_continueAction->setEnabled(false);
2125         m_exitAction->setEnabled(false);
2126         m_startAction->setEnabled(true);
2127         m_visibleStartAction->setAction(m_startAction);
2128         m_hiddenStopAction->setAction(m_undisturbableAction);
2129     } else if (state == InferiorStopOk) {
2130         // F5 continues, Shift-F5 kills. It is "continuable".
2131         m_interruptAction->setEnabled(false);
2132         m_continueAction->setEnabled(true);
2133         m_exitAction->setEnabled(true);
2134         m_startAction->setEnabled(false);
2135         m_visibleStartAction->setAction(m_continueAction);
2136         m_hiddenStopAction->setAction(m_exitAction);
2137     } else if (state == InferiorRunOk) {
2138         // Shift-F5 interrupts. It is also "interruptible".
2139         m_interruptAction->setEnabled(true);
2140         m_continueAction->setEnabled(false);
2141         m_exitAction->setEnabled(true);
2142         m_startAction->setEnabled(false);
2143         m_visibleStartAction->setAction(m_interruptAction);
2144         m_hiddenStopAction->setAction(m_interruptAction);
2145     } else if (state == DebuggerFinished) {
2146         // We don't want to do anything anymore.
2147         m_interruptAction->setEnabled(false);
2148         m_continueAction->setEnabled(false);
2149         m_exitAction->setEnabled(false);
2150         m_startAction->setEnabled(true);
2151         m_visibleStartAction->setAction(m_startAction);
2152         m_hiddenStopAction->setAction(m_undisturbableAction);
2153         m_codeModelSnapshot = CPlusPlus::Snapshot();
2154         setBusyCursor(false);
2155         cleanupViews();
2156     } else if (state == InferiorUnrunnable) {
2157         // We don't want to do anything anymore.
2158         m_interruptAction->setEnabled(false);
2159         m_continueAction->setEnabled(false);
2160         m_exitAction->setEnabled(true);
2161         m_startAction->setEnabled(false);
2162         m_visibleStartAction->setAction(m_startAction);
2163         m_hiddenStopAction->setAction(m_undisturbableAction);
2164     } else {
2165         // Everything else is "undisturbable".
2166         m_interruptAction->setEnabled(false);
2167         m_continueAction->setEnabled(false);
2168         m_exitAction->setEnabled(false);
2169         m_startAction->setEnabled(false);
2170         m_visibleStartAction->setAction(m_undisturbableAction);
2171         m_hiddenStopAction->setAction(m_undisturbableAction);
2172     }
2173
2174     m_startExternalAction->setEnabled(true);
2175     m_attachToQmlPortAction->setEnabled(true);
2176     m_attachExternalAction->setEnabled(true);
2177     m_attachCoreAction->setEnabled(true);
2178     m_startRemoteAction->setEnabled(true);
2179     m_attachRemoteAction->setEnabled(true);
2180
2181     const bool isCore = engine->startParameters().startMode == AttachCore;
2182     const bool stopped = state == InferiorStopOk;
2183     const bool detachable = stopped && !isCore;
2184     m_detachAction->setEnabled(detachable);
2185
2186     if (stopped)
2187         QApplication::alert(mainWindow(), 3000);
2188
2189     const uint caps = engine->debuggerCapabilities();
2190     const bool canReverse = (caps & ReverseSteppingCapability)
2191                 && boolSetting(EnableReverseDebugging);
2192     m_reverseDirectionAction->setEnabled(canReverse);
2193
2194     m_watchAction1->setEnabled(true);
2195     m_watchAction2->setEnabled(true);
2196     m_breakAction->setEnabled(true);
2197
2198     const bool canOperateByInstruction = (caps & OperateByInstructionCapability)
2199             && (stopped || isCore);
2200     action(OperateByInstruction)->setEnabled(canOperateByInstruction);
2201
2202     m_resetAction->setEnabled(state != DebuggerNotReady
2203                                       && state != DebuggerFinished);
2204
2205     m_stepAction->setEnabled(stopped || state == DebuggerNotReady);
2206     m_nextAction->setEnabled(stopped || state == DebuggerNotReady);
2207     m_stepAction->setToolTip(QString());
2208     m_nextAction->setToolTip(QString());
2209
2210     m_stepOutAction->setEnabled(stopped);
2211     m_runToLineAction->setEnabled(stopped && (caps & RunToLineCapability));
2212     m_runToSelectedFunctionAction->setEnabled(stopped);
2213     m_returnFromFunctionAction->
2214         setEnabled(stopped && (caps & ReturnFromFunctionCapability));
2215
2216     const bool canJump = stopped && (caps & JumpToLineCapability);
2217     m_jumpToLineAction->setEnabled(canJump);
2218
2219     const bool canDeref = actionsEnabled && (caps & AutoDerefPointersCapability);
2220     action(AutoDerefPointers)->setEnabled(canDeref);
2221     action(AutoDerefPointers)->setEnabled(true);
2222     action(ExpandStack)->setEnabled(actionsEnabled);
2223
2224     const bool notbusy = state == InferiorStopOk
2225         || state == DebuggerNotReady
2226         || state == DebuggerFinished
2227         || state == InferiorUnrunnable;
2228     setBusyCursor(!notbusy);
2229
2230     //Console should be enabled only for QML
2231     QmlEngine *qmlEngine = qobject_cast<QmlEngine *>(engine);
2232     QmlCppEngine *qmlCppEngine = qobject_cast<QmlCppEngine *>(engine);
2233     if (qmlCppEngine)
2234         qmlEngine = qobject_cast<QmlEngine *>(qmlCppEngine->qmlEngine());
2235
2236     if (qmlEngine) {
2237         m_scriptConsoleWindow->setEnabled(stopped);
2238     }
2239
2240 }
2241
2242 void DebuggerPluginPrivate::updateDebugActions()
2243 {
2244     ProjectExplorerPlugin *pe = ProjectExplorerPlugin::instance();
2245     Project *project = pe->startupProject();
2246     const QString debugMode = _(Constants::DEBUGMODE);
2247     const bool canRun = pe->canRun(project, debugMode);
2248     m_startAction->setEnabled(canRun);
2249     m_startAction->setToolTip(canRun ? QString() : pe->cannotRunReason(project, debugMode));
2250
2251     // Step into/next: Start and break at 'main' unless a debugger is running.
2252     if (m_snapshotHandler->currentIndex() < 0) {
2253         const QString debugMode2 = _(Constants::DEBUGMODE2);
2254         const bool canRunAndBreakMain = pe->canRun(project, debugMode2);
2255         m_stepAction->setEnabled(canRunAndBreakMain);
2256         m_nextAction->setEnabled(canRunAndBreakMain);
2257         QString toolTip;
2258         if (canRunAndBreakMain) {
2259             QTC_ASSERT(project, return ; );
2260             toolTip = tr("Start '%1' and break at function 'main()'")
2261                       .arg(project->displayName());
2262         } else {
2263             // Do not display long tooltip saying 'debugMode2 is not supported
2264             // for project' for projects to which 'break at main' is not applicable.
2265             if (!canRun)
2266                 toolTip = pe->cannotRunReason(project, debugMode2);
2267         }
2268         m_stepAction->setToolTip(toolTip);
2269         m_nextAction->setToolTip(toolTip);
2270     }
2271 }
2272
2273 void DebuggerPluginPrivate::onCoreAboutToOpen()
2274 {
2275     m_mainWindow->onModeChanged(ModeManager::instance()->currentMode());
2276 }
2277
2278 void DebuggerPluginPrivate::onModeChanged(IMode *mode)
2279 {
2280      // FIXME: This one gets always called, even if switching between modes
2281      //        different then the debugger mode. E.g. Welcome and Help mode and
2282      //        also on shutdown.
2283
2284     m_mainWindow->onModeChanged(mode);
2285
2286     if (mode->id() != Constants::MODE_DEBUG) {
2287         m_toolTipManager->leavingDebugMode();
2288         return;
2289     }
2290
2291     EditorManager *editorManager = EditorManager::instance();
2292     if (editorManager->currentEditor())
2293         editorManager->currentEditor()->widget()->setFocus();
2294     m_toolTipManager->debugModeEntered();
2295 }
2296
2297 void DebuggerPluginPrivate::showSettingsDialog()
2298 {
2299     ICore::instance()->showOptionsDialog(
2300         _(DEBUGGER_SETTINGS_CATEGORY),
2301         _(DEBUGGER_COMMON_SETTINGS_ID));
2302 }
2303
2304 void DebuggerPluginPrivate::dumpLog()
2305 {
2306     QString fileName = QFileDialog::getSaveFileName(mainWindow(),
2307         tr("Save Debugger Log"), QDir::tempPath());
2308     if (fileName.isEmpty())
2309         return;
2310     Utils::FileSaver saver(fileName);
2311     if (!saver.hasError()) {
2312         QTextStream ts(saver.file());
2313         ts << m_logWindow->inputContents();
2314         ts << "\n\n=======================================\n\n";
2315         ts << m_logWindow->combinedContents();
2316         saver.setResult(&ts);
2317     }
2318     saver.finalize(mainWindow());
2319 }
2320
2321 /*! Activates the previous mode when the current mode is the debug mode. */
2322 void DebuggerPluginPrivate::activatePreviousMode()
2323 {
2324     ModeManager *modeManager = ModeManager::instance();
2325     if (modeManager->currentMode() == modeManager->mode(MODE_DEBUG)
2326             && !m_previousMode.isEmpty()) {
2327         modeManager->activateMode(m_previousMode);
2328         m_previousMode.clear();
2329     }
2330 }
2331
2332 void DebuggerPluginPrivate::activateDebugMode()
2333 {
2334     m_reverseDirectionAction->setChecked(false);
2335     m_reverseDirectionAction->setEnabled(false);
2336     ModeManager *modeManager = ModeManager::instance();
2337     m_previousMode = modeManager->currentMode()->id();
2338     modeManager->activateMode(_(MODE_DEBUG));
2339 }
2340
2341 void DebuggerPluginPrivate::sessionLoaded()
2342 {
2343     m_breakHandler->loadSessionData();
2344     dummyEngine()->watchHandler()->loadSessionData();
2345     m_toolTipManager->loadSessionData();
2346 }
2347
2348 void DebuggerPluginPrivate::aboutToUnloadSession()
2349 {
2350     m_breakHandler->removeSessionData();
2351     m_toolTipManager->sessionAboutToChange();
2352     // Stop debugging the active project when switching sessions.
2353     // Note that at startup, session switches may occur, which interfere
2354     // with command-line debugging startup.
2355     // FIXME ABC: Still wanted? Iterate?
2356     //if (d->m_engine && state() != DebuggerNotReady
2357     //    && engine()->sp().startMode == StartInternal)
2358     //        d->m_engine->shutdown();
2359 }
2360
2361 void DebuggerPluginPrivate::aboutToSaveSession()
2362 {
2363     dummyEngine()->watchHandler()->saveSessionData();
2364     m_toolTipManager->saveSessionData();
2365     m_breakHandler->saveSessionData();
2366 }
2367
2368 void DebuggerPluginPrivate::executeDebuggerCommand(const QString &command)
2369 {
2370     if (currentEngine()->acceptsDebuggerCommands())
2371         currentEngine()->executeDebuggerCommand(command);
2372     else
2373         showStatusMessage(tr("User commands are not accepted in the current state."));
2374 }
2375
2376 void DebuggerPluginPrivate::showStatusMessage(const QString &msg0, int timeout)
2377 {
2378     showMessage(msg0, LogStatus);
2379     QString msg = msg0;
2380     msg.remove(QLatin1Char('\n'));
2381     m_statusLabel->showStatusMessage(msg, timeout);
2382 }
2383
2384 void DebuggerPluginPrivate::scriptExpressionEntered(const QString &expression)
2385 {
2386     currentEngine()->executeDebuggerCommand(expression);
2387 }
2388
2389 void DebuggerPluginPrivate::openMemoryEditor()
2390 {
2391     AddressDialog dialog;
2392     if (dialog.exec() == QDialog::Accepted)
2393         currentEngine()->openMemoryView(dialog.address(), 0, QList<MemoryMarkup>(), QPoint());
2394 }
2395
2396 void DebuggerPluginPrivate::coreShutdown()
2397 {
2398     m_shuttingDown = true;
2399 }
2400
2401 const CPlusPlus::Snapshot &DebuggerPluginPrivate::cppCodeModelSnapshot() const
2402 {
2403     if (m_codeModelSnapshot.isEmpty() && action(UseCodeModel)->isChecked())
2404         m_codeModelSnapshot = CPlusPlus::CppModelManagerInterface::instance()->snapshot();
2405     return m_codeModelSnapshot;
2406 }
2407
2408 void DebuggerPluginPrivate::setSessionValue(const QString &name, const QVariant &value)
2409 {
2410     QTC_ASSERT(sessionManager(), return);
2411     sessionManager()->setValue(name, value);
2412     //qDebug() << "SET SESSION VALUE: " << name;
2413 }
2414
2415 QVariant DebuggerPluginPrivate::sessionValue(const QString &name)
2416 {
2417     QTC_ASSERT(sessionManager(), return QVariant());
2418     //qDebug() << "GET SESSION VALUE: " << name;
2419     return sessionManager()->value(name);
2420 }
2421
2422 void DebuggerPluginPrivate::openTextEditor(const QString &titlePattern0,
2423     const QString &contents)
2424 {
2425     if (m_shuttingDown)
2426         return;
2427     QString titlePattern = titlePattern0;
2428     EditorManager *editorManager = EditorManager::instance();
2429     QTC_ASSERT(editorManager, return);
2430     IEditor *editor = editorManager->openEditorWithContents(
2431         CC::K_DEFAULT_TEXT_EDITOR_ID, &titlePattern, contents);
2432     QTC_ASSERT(editor, return);
2433     editorManager->activateEditor(editor, EditorManager::IgnoreNavigationHistory);
2434 }
2435
2436
2437 void DebuggerPluginPrivate::clearCppCodeModelSnapshot()
2438 {
2439     m_codeModelSnapshot = CPlusPlus::Snapshot();
2440 }
2441
2442 void DebuggerPluginPrivate::showMessage(const QString &msg, int channel, int timeout)
2443 {
2444     //qDebug() << "PLUGIN OUTPUT: " << channel << msg;
2445     //ConsoleWindow *cw = m_consoleWindow;
2446     QTC_ASSERT(m_logWindow, return);
2447     switch (channel) {
2448         case StatusBar:
2449             // This will append to m_logWindow's output pane, too.
2450             showStatusMessage(msg, timeout);
2451             break;
2452         case LogMiscInput:
2453             m_logWindow->showInput(LogMisc, msg);
2454             m_logWindow->showOutput(LogMisc, msg);
2455             break;
2456         case LogInput:
2457             m_logWindow->showInput(LogInput, msg);
2458             m_logWindow->showOutput(LogInput, msg);
2459             break;
2460         case ScriptConsoleOutput:
2461             m_scriptConsoleWindow->appendResult(msg);
2462             break;
2463         case LogError: {
2464             m_logWindow->showOutput(channel, msg);
2465             QAction *action = m_mainWindow->dockWidget(_(DOCKWIDGET_OUTPUT))
2466                 ->toggleViewAction();
2467             if (!action->isChecked())
2468                 action->trigger();
2469             break;
2470         }
2471         default:
2472             m_logWindow->showOutput(channel, msg);
2473             break;
2474     }
2475 }
2476
2477 void DebuggerPluginPrivate::showQtDumperLibraryWarning(const QString &details)
2478 {
2479     QMessageBox dialog(mainWindow());
2480     QPushButton *qtPref = dialog.addButton(tr("Open Qt4 Options"),
2481         QMessageBox::ActionRole);
2482     QPushButton *helperOff = dialog.addButton(tr("Turn off Helper Usage"),
2483         QMessageBox::ActionRole);
2484     QPushButton *justContinue = dialog.addButton(tr("Continue Anyway"),
2485         QMessageBox::AcceptRole);
2486     dialog.setDefaultButton(justContinue);
2487     dialog.setWindowTitle(tr("Debugging Helper Missing"));
2488     dialog.setText(tr("The debugger could not load the debugging helper library."));
2489     dialog.setInformativeText(tr(
2490         "The debugging helper is used to nicely format the values of some Qt "
2491         "and Standard Library data types. "
2492         "It must be compiled for each used Qt version separately. "
2493         "On the Qt4 options page, select a Qt installation "
2494         "and click Rebuild."));
2495     if (!details.isEmpty())
2496         dialog.setDetailedText(details);
2497     dialog.exec();
2498     if (dialog.clickedButton() == qtPref) {
2499         ICore::instance()->showOptionsDialog(
2500             _(ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_CATEGORY),
2501             _(QtSupport::Constants::QTVERSION_SETTINGS_PAGE_ID));
2502     } else if (dialog.clickedButton() == helperOff) {
2503         action(UseDebuggingHelpers)->setValue(qVariantFromValue(false), false);
2504     }
2505 }
2506
2507 void DebuggerPluginPrivate::createNewDock(QWidget *widget)
2508 {
2509     QDockWidget *dockWidget =
2510         m_mainWindow->createDockWidget(CppLanguage, widget);
2511     dockWidget->setWindowTitle(widget->windowTitle());
2512     dockWidget->setFeatures(QDockWidget::DockWidgetClosable);
2513     dockWidget->show();
2514 }
2515
2516 static QString formatStartParameters(DebuggerStartParameters &sp)
2517 {
2518     QString rc;
2519     QTextStream str(&rc);
2520     str << "Start parameters: '" << sp.displayName << "' mode: " << sp.startMode
2521         << "\nABI: " << sp.toolChainAbi.toString() << '\n';
2522     if (!sp.executable.isEmpty()) {
2523         str << "Executable: " << QDir::toNativeSeparators(sp.executable)
2524             << ' ' << sp.processArgs;
2525         if (sp.useTerminal)
2526             str << " [terminal]";
2527         str << '\n';
2528         if (!sp.workingDirectory.isEmpty())
2529             str << "Directory: " << QDir::toNativeSeparators(sp.workingDirectory)
2530                 << '\n';
2531         if (sp.executableUid) {
2532             str << "UID: 0x";
2533             str.setIntegerBase(16);
2534             str << sp.executableUid << '\n';
2535             str.setIntegerBase(10);
2536         }
2537     }
2538     if (!sp.debuggerCommand.isEmpty())
2539         str << "Debugger: " << QDir::toNativeSeparators(sp.debuggerCommand) << '\n';
2540     if (!sp.coreFile.isEmpty())
2541         str << "Core: " << QDir::toNativeSeparators(sp.coreFile) << '\n';
2542     if (sp.attachPID > 0)
2543         str << "PID: " << sp.attachPID << ' ' << sp.crashParameter << '\n';
2544     if (!sp.projectSourceDirectory.isEmpty()) {
2545         str << "Project: " << QDir::toNativeSeparators(sp.projectSourceDirectory);
2546         if (!sp.projectBuildDirectory.isEmpty())
2547             str << " (built: " << QDir::toNativeSeparators(sp.projectBuildDirectory)
2548                 << ')';
2549         str << '\n';
2550     }
2551     if (!sp.qtInstallPath.isEmpty())
2552         str << "Qt: " << QDir::toNativeSeparators(sp.qtInstallPath) << '\n';
2553     if (!sp.qmlServerAddress.isEmpty())
2554         str << "QML server: " << sp.qmlServerAddress << ':'
2555             << sp.qmlServerPort << '\n';
2556     if (!sp.remoteChannel.isEmpty()) {
2557         str << "Remote: " << sp.remoteChannel << ", "
2558             << sp.remoteArchitecture << '\n';
2559         if (!sp.remoteDumperLib.isEmpty())
2560             str << "Remote dumpers: " << sp.remoteDumperLib << '\n';
2561         if (!sp.remoteSourcesDir.isEmpty())
2562             str << "Remote sources: " << sp.remoteSourcesDir << '\n';
2563         if (!sp.remoteMountPoint.isEmpty())
2564             str << "Remote mount point: " << sp.remoteMountPoint
2565                 << " Local: " << sp.localMountDir << '\n';
2566     }
2567     if (!sp.gnuTarget.isEmpty())
2568         str << "Gnu target: " << sp.gnuTarget << '\n';
2569     str << "Sysroot: " << sp.sysroot << '\n';
2570     str << "Debug Source Loaction: " << sp.debugSourceLocation.join(":") << '\n';
2571     str << "Symbol file: " << sp.symbolFileName << '\n';
2572     if (sp.useServerStartScript)
2573         str << "Using server start script: " << sp.serverStartScript;
2574     str << "Dumper libraries: " << QDir::toNativeSeparators(sp.dumperLibrary);
2575     foreach (const QString &dl, sp.dumperLibraryLocations)
2576         str << ' ' << QDir::toNativeSeparators(dl);
2577     str << '\n';
2578     return rc;
2579 }
2580
2581 void DebuggerPluginPrivate::runControlStarted(DebuggerEngine *engine)
2582 {
2583     activateDebugMode();
2584     const QString message = tr("Starting debugger '%1' for ABI '%2'...")
2585             .arg(engine->objectName())
2586             .arg(engine->startParameters().toolChainAbi.toString());
2587     showMessage(message, StatusBar);
2588     showMessage(formatStartParameters(engine->startParameters()), LogDebug);
2589     showMessage(m_debuggerSettings->dump(), LogDebug);
2590     m_snapshotHandler->appendSnapshot(engine);
2591     connectEngine(engine);
2592 }
2593
2594 void DebuggerPluginPrivate::runControlFinished(DebuggerEngine *engine)
2595 {
2596     showStatusMessage(tr("Debugger finished."));
2597     m_snapshotHandler->removeSnapshot(engine);
2598     if (m_snapshotHandler->size() == 0) {
2599         // Last engine quits.
2600         disconnectEngine();
2601         if (boolSetting(SwitchModeOnExit))
2602             activatePreviousMode();
2603     } else {
2604         // Connect to some existing engine.
2605         m_snapshotHandler->activateSnapshot(0);
2606     }
2607     action(OperateByInstruction)->setValue(QVariant(false));
2608 }
2609
2610 void DebuggerPluginPrivate::remoteCommand(const QStringList &options,
2611     const QStringList &)
2612 {
2613     if (options.isEmpty())
2614         return;
2615
2616     unsigned enabledEngines = 0;
2617     QString errorMessage;
2618
2619     if (!parseArguments(options, &enabledEngines, &errorMessage)) {
2620         qWarning("%s", qPrintable(errorMessage));
2621         return;
2622     }
2623     runScheduled();
2624 }
2625
2626 QString DebuggerPluginPrivate::debuggerForAbi(const Abi &abi, DebuggerEngineType et) const
2627 {
2628     enum { debug = 0 };
2629     QList<Abi> searchAbis;
2630     searchAbis.push_back(abi);
2631     // Pick the right tool chain in case cdb/gdb were started with other tool chains.
2632     // Also, lldb should be preferred over gdb.
2633     if (abi.os() == ProjectExplorer::Abi::WindowsOS) {
2634         switch (et) {
2635         case CdbEngineType:
2636             searchAbis.clear();
2637             searchAbis.push_back(Abi(abi.architecture(), abi.os(),
2638                 Abi::WindowsMsvc2010Flavor, abi.binaryFormat(), abi.wordWidth()));
2639             searchAbis.push_back(Abi(abi.architecture(), abi.os(),
2640                 Abi::WindowsMsvc2008Flavor, abi.binaryFormat(), abi.wordWidth()));
2641             searchAbis.push_back(Abi(abi.architecture(), abi.os(),
2642                 Abi::WindowsMsvc2005Flavor, abi.binaryFormat(), abi.wordWidth()));
2643             break;
2644         case GdbEngineType:
2645             searchAbis.clear();
2646             searchAbis.push_back(Abi(abi.architecture(), abi.os(),
2647                 Abi::WindowsMSysFlavor, abi.binaryFormat(), abi.wordWidth()));
2648             break;
2649         default:
2650             break;
2651         }
2652     }
2653     if (debug)
2654         qDebug() << "debuggerForAbi" << abi.toString() << searchAbis.size()
2655                  << searchAbis.front().toString() << et;
2656
2657     foreach (const Abi &searchAbi, searchAbis) {
2658         const QList<ToolChain *> toolchains =
2659             ToolChainManager::instance()->findToolChains(searchAbi);
2660         // Find manually configured ones first
2661         for (int i = toolchains.size() - 1; i >= 0; i--) {
2662             const QString debugger = toolchains.at(i)->debuggerCommand();
2663             if (debug)
2664                 qDebug() << i << toolchains.at(i)->displayName() << debugger;
2665             if (!debugger.isEmpty())
2666                 return debugger;
2667         }
2668     }
2669     return QString();
2670 }
2671
2672 DebuggerLanguages DebuggerPluginPrivate::activeLanguages() const
2673 {
2674     QTC_ASSERT(m_mainWindow, return AnyLanguage);
2675     return m_mainWindow->activeDebugLanguages();
2676 }
2677
2678 bool DebuggerPluginPrivate::isReverseDebugging() const
2679 {
2680     return m_reverseDirectionAction->isChecked();
2681 }
2682
2683 QMessageBox *showMessageBox(int icon, const QString &title,
2684     const QString &text, int buttons)
2685 {
2686     QMessageBox *mb = new QMessageBox(QMessageBox::Icon(icon),
2687         title, text, QMessageBox::StandardButtons(buttons),
2688         debuggerCore()->mainWindow());
2689     mb->setAttribute(Qt::WA_DeleteOnClose);
2690     mb->show();
2691     return mb;
2692 }
2693
2694 void DebuggerPluginPrivate::extensionsInitialized()
2695 {
2696     ICore *core = ICore::instance();
2697     QTC_ASSERT(core, return);
2698     m_coreSettings = core->settings();
2699
2700     m_debuggerSettings = new DebuggerSettings(m_coreSettings);
2701     m_debuggerSettings->readSettings();
2702
2703     connect(core, SIGNAL(coreAboutToClose()), this, SLOT(coreShutdown()));
2704
2705     Core::ActionManager *am = core->actionManager();
2706     QTC_ASSERT(am, return);
2707
2708     m_plugin->addObject(this);
2709
2710     const Context globalcontext(CC::C_GLOBAL);
2711     const Context cppDebuggercontext(C_CPPDEBUGGER);
2712     const Context qmlDebuggerContext(C_QMLDEBUGGER);
2713     const Context cppeditorcontext(CppEditor::Constants::C_CPPEDITOR);
2714
2715     m_startIcon = QIcon(_(":/debugger/images/debugger_start_small.png"));
2716     m_startIcon.addFile(__(":/debugger/images/debugger_start.png"));
2717     m_exitIcon = QIcon(_(":/debugger/images/debugger_stop_small.png"));
2718     m_exitIcon.addFile(__(":/debugger/images/debugger_stop.png"));
2719     m_continueIcon = QIcon(__(":/debugger/images/debugger_continue_small.png"));
2720     m_continueIcon.addFile(__(":/debugger/images/debugger_continue.png"));
2721     m_interruptIcon = QIcon(_(":/debugger/images/debugger_interrupt_small.png"));
2722     m_interruptIcon.addFile(__(":/debugger/images/debugger_interrupt.png"));
2723     m_locationMarkIcon = QIcon(_(":/debugger/images/location_16.png"));
2724
2725     m_busy = false;
2726
2727     m_statusLabel = new Utils::StatusLabel;
2728
2729     m_breakHandler = new BreakHandler;
2730     m_breakWindow = new BreakWindow;
2731     m_breakWindow->setObjectName(DOCKWIDGET_BREAK);
2732     m_breakWindow->setModel(m_breakHandler->model());
2733
2734     //m_consoleWindow = new ConsoleWindow;
2735     //m_consoleWindow->setObjectName(QLatin1String("CppDebugConsole"));
2736     m_modulesWindow = new ModulesWindow;
2737     m_modulesWindow->setObjectName(DOCKWIDGET_MODULES);
2738     m_logWindow = new LogWindow;
2739     m_logWindow->setObjectName(DOCKWIDGET_OUTPUT);
2740     m_registerWindow = new RegisterWindow;
2741     m_registerWindow->setObjectName(DOCKWIDGET_REGISTER);
2742     m_stackWindow = new StackWindow;
2743     m_stackWindow->setObjectName(DOCKWIDGET_STACK);
2744     m_sourceFilesWindow = new SourceFilesWindow;
2745     m_sourceFilesWindow->setObjectName(DOCKWIDGET_SOURCE_FILES);
2746     m_threadsWindow = new ThreadsWindow;
2747     m_threadsWindow->setObjectName(DOCKWIDGET_THREADS);
2748     m_returnWindow = new WatchWindow(WatchWindow::ReturnType);
2749     m_returnWindow->setObjectName(QLatin1String("CppDebugReturn"));
2750     m_localsWindow = new WatchWindow(WatchWindow::LocalsType);
2751     m_localsWindow->setObjectName(QLatin1String("CppDebugLocals"));
2752     m_watchersWindow = new WatchWindow(WatchWindow::WatchersType);
2753     m_watchersWindow->setObjectName(QLatin1String("CppDebugWatchers"));
2754     m_scriptConsoleWindow = new ScriptConsole;
2755     m_scriptConsoleWindow->setWindowTitle(tr("QML Script Console"));
2756     m_scriptConsoleWindow->setObjectName(DOCKWIDGET_QML_SCRIPTCONSOLE);
2757     connect(m_scriptConsoleWindow, SIGNAL(expressionEntered(QString)),
2758         SLOT(scriptExpressionEntered(QString)));
2759
2760     // Snapshot
2761     m_snapshotHandler = new SnapshotHandler;
2762     m_snapshotWindow = new SnapshotWindow(m_snapshotHandler);
2763     m_snapshotWindow->setObjectName(DOCKWIDGET_SNAPSHOTS);
2764     m_snapshotWindow->setModel(m_snapshotHandler->model());
2765
2766     // Watchers
2767     connect(m_localsWindow->header(), SIGNAL(sectionResized(int,int,int)),
2768         SLOT(updateWatchersHeader(int,int,int)), Qt::QueuedConnection);
2769
2770     QAction *act = 0;
2771
2772     act = m_continueAction = new QAction(tr("Continue"), this);
2773     act->setIcon(m_continueIcon);
2774     connect(act, SIGNAL(triggered()), SLOT(handleExecContinue()));
2775
2776     act = m_exitAction = new QAction(tr("Exit Debugger"), this);
2777     act->setIcon(m_exitIcon);
2778     connect(act, SIGNAL(triggered()), SLOT(handleExecExit()));
2779
2780     act = m_interruptAction = new QAction(tr("Interrupt"), this);
2781     act->setIcon(m_interruptIcon);
2782     connect(act, SIGNAL(triggered()), SLOT(handleExecInterrupt()));
2783
2784     // A "disabled pause" seems to be a good choice.
2785     act = m_undisturbableAction = new QAction(tr("Debugger is Busy"), this);
2786     act->setIcon(m_interruptIcon);
2787     act->setEnabled(false);
2788
2789     act = m_resetAction = new QAction(tr("Abort Debugging"), this);
2790     act->setToolTip(tr("Aborts debugging and "
2791         "resets the debugger to the initial state."));
2792     connect(act, SIGNAL(triggered()), SLOT(handleExecReset()));
2793
2794     act = m_nextAction = new QAction(tr("Step Over"), this);
2795     act->setIcon(QIcon(__(":/debugger/images/debugger_stepover_small.png")));
2796     connect(act, SIGNAL(triggered()), SLOT(handleExecNext()));
2797
2798     act = m_stepAction = new QAction(tr("Step Into"), this);
2799     act->setIcon(QIcon(__(":/debugger/images/debugger_stepinto_small.png")));
2800     connect(act, SIGNAL(triggered()), SLOT(handleExecStep()));
2801
2802     act = m_stepOutAction = new QAction(tr("Step Out"), this);
2803     act->setIcon(QIcon(__(":/debugger/images/debugger_stepout_small.png")));
2804     connect(act, SIGNAL(triggered()), SLOT(handleExecStepOut()));
2805
2806     act = m_runToLineAction = new QAction(tr("Run to Line"), this);
2807     connect(act, SIGNAL(triggered()), SLOT(handleExecRunToLine()));
2808
2809     act = m_runToSelectedFunctionAction =
2810         new QAction(tr("Run to Selected Function"), this);
2811     connect(act, SIGNAL(triggered()), SLOT(handleExecRunToSelectedFunction()));
2812
2813     act = m_returnFromFunctionAction =
2814         new QAction(tr("Immediately Return From Inner Function"), this);
2815     connect(act, SIGNAL(triggered()), SLOT(handleExecReturn()));
2816
2817     act = m_jumpToLineAction = new QAction(tr("Jump to Line"), this);
2818     connect(act, SIGNAL(triggered()), SLOT(handleExecJumpToLine()));
2819
2820     act = m_breakAction = new QAction(tr("Toggle Breakpoint"), this);
2821
2822     act = m_watchAction1 = new QAction(tr("Add to Watch Window"), this);
2823     connect(act, SIGNAL(triggered()), SLOT(handleAddToWatchWindow()));
2824
2825     act = m_watchAction2 = new QAction(tr("Add to Watch Window"), this);
2826     connect(act, SIGNAL(triggered()), SLOT(handleAddToWatchWindow()));
2827
2828     //m_snapshotAction = new QAction(tr("Create Snapshot"), this);
2829     //m_snapshotAction->setProperty(Role, RequestCreateSnapshotRole);
2830     //m_snapshotAction->setIcon(
2831     //    QIcon(__(":/debugger/images/debugger_snapshot_small.png")));
2832
2833     act = m_reverseDirectionAction =
2834         new QAction(tr("Reverse Direction"), this);
2835     act->setCheckable(true);
2836     act->setChecked(false);
2837     act->setCheckable(false);
2838     act->setIcon(QIcon(__(":/debugger/images/debugger_reversemode_16.png")));
2839     act->setIconVisibleInMenu(false);
2840
2841     act = m_frameDownAction = new QAction(tr("Move to Called Frame"), this);
2842     connect(act, SIGNAL(triggered()), SLOT(handleFrameDown()));
2843
2844     act = m_frameUpAction = new QAction(tr("Move to Calling Frame"), this);
2845     connect(act, SIGNAL(triggered()), SLOT(handleFrameUp()));
2846
2847     connect(action(OperateByInstruction), SIGNAL(triggered(bool)),
2848         SLOT(handleOperateByInstructionTriggered(bool)));
2849
2850     ActionContainer *debugMenu =
2851         am->actionContainer(ProjectExplorer::Constants::M_DEBUG);
2852
2853     // Dock widgets
2854     QDockWidget *dock = 0;
2855     dock = m_mainWindow->createDockWidget(CppLanguage, m_modulesWindow);
2856     connect(dock->toggleViewAction(), SIGNAL(toggled(bool)),
2857         SLOT(modulesDockToggled(bool)), Qt::QueuedConnection);
2858
2859     dock = m_mainWindow->createDockWidget(CppLanguage, m_registerWindow);
2860     connect(dock->toggleViewAction(), SIGNAL(toggled(bool)),
2861         SLOT(registerDockToggled(bool)), Qt::QueuedConnection);
2862
2863     dock = m_mainWindow->createDockWidget(CppLanguage, m_sourceFilesWindow);
2864     connect(dock->toggleViewAction(), SIGNAL(toggled(bool)),
2865         SLOT(sourceFilesDockToggled(bool)), Qt::QueuedConnection);
2866
2867     dock = m_mainWindow->createDockWidget(AnyLanguage, m_logWindow);
2868     dock->setProperty(DOCKWIDGET_DEFAULT_AREA, Qt::TopDockWidgetArea);
2869
2870     m_mainWindow->createDockWidget(CppLanguage, m_breakWindow);
2871     //m_mainWindow->createDockWidget(CppLanguage, m_consoleWindow);
2872     m_mainWindow->createDockWidget(CppLanguage, m_snapshotWindow);
2873     m_mainWindow->createDockWidget(CppLanguage, m_stackWindow);
2874     m_mainWindow->createDockWidget(CppLanguage, m_threadsWindow);
2875     m_mainWindow->createDockWidget(QmlLanguage, m_scriptConsoleWindow);
2876
2877     QSplitter *localsAndWatchers = new Core::MiniSplitter(Qt::Vertical);
2878     localsAndWatchers->setObjectName(DOCKWIDGET_WATCHERS);
2879     localsAndWatchers->setWindowTitle(m_localsWindow->windowTitle());
2880     localsAndWatchers->addWidget(m_localsWindow);
2881     localsAndWatchers->addWidget(m_returnWindow);
2882     localsAndWatchers->addWidget(m_watchersWindow);
2883     localsAndWatchers->setStretchFactor(0, 3);
2884     localsAndWatchers->setStretchFactor(1, 1);
2885     localsAndWatchers->setStretchFactor(2, 1);
2886
2887     dock = m_mainWindow->createDockWidget(CppLanguage, localsAndWatchers);
2888     dock->setProperty(DOCKWIDGET_DEFAULT_AREA, Qt::RightDockWidgetArea);
2889
2890     m_commonOptionsPage = new CommonOptionsPage(m_globalDebuggerOptions);
2891     m_plugin->addAutoReleasedObject(m_commonOptionsPage);
2892
2893     // Do not fail to load the whole plugin if something goes wrong here.
2894     QString errorMessage;
2895     if (!parseArguments(m_arguments, &m_cmdLineEnabledEngines, &errorMessage)) {
2896         errorMessage = tr("Error evaluating command line arguments: %1")
2897             .arg(errorMessage);
2898         qWarning("%s\n", qPrintable(errorMessage));
2899     }
2900
2901     // Register factory of DebuggerRunControl.
2902     m_debuggerRunControlFactory = new DebuggerRunControlFactory
2903         (m_plugin, DebuggerEngineType(m_cmdLineEnabledEngines));
2904     m_plugin->addAutoReleasedObject(m_debuggerRunControlFactory);
2905
2906     // The main "Start Debugging" action.
2907     act = m_startAction = new QAction(this);
2908     QIcon debuggerIcon(":/projectexplorer/images/debugger_start_small.png");
2909     debuggerIcon.addFile(":/projectexplorer/images/debugger_start.png");
2910     act->setIcon(debuggerIcon);
2911     act->setText(tr("Start Debugging"));
2912     connect(act, SIGNAL(triggered()), this, SLOT(debugProject()));
2913
2914     // Handling of external applications.
2915     act = m_startExternalAction = new QAction(this);
2916     act->setText(tr("Start and Debug External Application..."));
2917     connect(act, SIGNAL(triggered()), SLOT(startExternalApplication()));
2918
2919 #ifdef WITH_LLDB
2920     act = m_startRemoteLldbAction = new QAction(this);
2921     act->setText(tr("Start and Debug External Application with External Engine..."));
2922     connect(act, SIGNAL(triggered()), SLOT(startRemoteEngine()));
2923 #endif
2924
2925     act = m_attachExternalAction = new QAction(this);
2926     act->setText(tr("Attach to Running External Application..."));
2927     connect(act, SIGNAL(triggered()), SLOT(attachExternalApplication()));
2928
2929     act = m_attachCoreAction = new QAction(this);
2930     act->setText(tr("Attach to Core..."));
2931     connect(act, SIGNAL(triggered()), SLOT(attachCore()));
2932
2933     act = m_startRemoteAction = new QAction(this);
2934     act->setText(tr("Start and Debug Remote Application..."));
2935     connect(act, SIGNAL(triggered()), SLOT(startRemoteApplication()));
2936
2937     act = m_attachRemoteAction = new QAction(this);
2938     act->setText(tr("Attach to Remote Debug Server..."));
2939     connect(act, SIGNAL(triggered()), SLOT(attachRemoteApplication()));
2940
2941     act = m_attachToQmlPortAction = new QAction(this);
2942     act->setText(tr("Attach to QML Port..."));
2943     connect(act, SIGNAL(triggered()), SLOT(attachToQmlPort()));
2944
2945 #ifdef Q_OS_WIN
2946     m_startRemoteCdbAction = new QAction(tr("Attach to Remote CDB Session..."), this);
2947     connect(m_startRemoteCdbAction, SIGNAL(triggered()),
2948         SLOT(startRemoteCdbSession()));
2949 #endif
2950
2951     act = m_detachAction = new QAction(this);
2952     act->setText(tr("Detach Debugger"));
2953     connect(act, SIGNAL(triggered()), SLOT(handleExecDetach()));
2954
2955     // "Start Debugging" sub-menu
2956     // groups:
2957     //   G_DEFAULT_ONE
2958     //   G_START_CPP
2959     //   G_START_QML
2960
2961     Command *cmd = 0;
2962     ActionContainer *mstart = am->actionContainer(PE::M_DEBUG_STARTDEBUGGING);
2963
2964     cmd = am->registerAction(m_startAction, Constants::DEBUG, globalcontext);
2965     cmd->setDefaultText(tr("Start Debugging"));
2966     cmd->setDefaultKeySequence(QKeySequence(Constants::DEBUG_KEY));
2967     cmd->setAttribute(Command::CA_UpdateText);
2968     mstart->addAction(cmd, CC::G_DEFAULT_ONE);
2969
2970     m_visibleStartAction = new Utils::ProxyAction(this);
2971     m_visibleStartAction->initialize(m_startAction);
2972     m_visibleStartAction->setAttribute(Utils::ProxyAction::UpdateText);
2973     m_visibleStartAction->setAttribute(Utils::ProxyAction::UpdateIcon);
2974     m_visibleStartAction->setAction(cmd->action());
2975
2976     ModeManager *modeManager = ModeManager::instance();
2977     modeManager->addAction(m_visibleStartAction, Constants::P_ACTION_DEBUG);
2978
2979     cmd = am->registerAction(m_startExternalAction,
2980         "Debugger.StartExternal", globalcontext);
2981     cmd->setAttribute(Command::CA_Hide);
2982     mstart->addAction(cmd, Constants::G_START_CPP);
2983
2984     cmd = am->registerAction(m_attachExternalAction,
2985         "Debugger.AttachExternal", globalcontext);
2986     cmd->setAttribute(Command::CA_Hide);
2987     mstart->addAction(cmd, Constants::G_START_CPP);
2988
2989     cmd = am->registerAction(m_attachCoreAction,
2990         "Debugger.AttachCore", globalcontext);
2991
2992     cmd->setAttribute(Command::CA_Hide);
2993     mstart->addAction(cmd, Constants::G_START_CPP);
2994
2995     cmd = am->registerAction(m_startRemoteAction,
2996         "Debugger.StartRemote", globalcontext);
2997     cmd->setAttribute(Command::CA_Hide);
2998     mstart->addAction(cmd, Constants::G_START_CPP);
2999
3000     cmd = am->registerAction(m_attachRemoteAction,
3001         "Debugger.AttachRemote", globalcontext);
3002     cmd->setAttribute(Command::CA_Hide);
3003     mstart->addAction(cmd, Constants::G_START_CPP);
3004
3005
3006 #ifdef WITH_LLDB
3007     cmd = am->registerAction(m_startRemoteLldbAction,
3008         "Debugger.RemoteLldb", globalcontext);
3009     cmd->setAttribute(Command::CA_Hide);
3010     mstart->addAction(cmd, Constants::G_START_CPP);
3011 #endif
3012
3013     if (m_startRemoteCdbAction) {
3014         cmd = am->registerAction(m_startRemoteCdbAction,
3015              "Debugger.AttachRemoteCdb", globalcontext);
3016         cmd->setAttribute(Command::CA_Hide);
3017         mstart->addAction(cmd, Constants::G_START_CPP);
3018     }
3019
3020     QAction *sep = new QAction(mstart);
3021     sep->setSeparator(true);
3022     cmd = am->registerAction(sep,
3023         "Debugger.Start.Qml", globalcontext);
3024     mstart->addAction(cmd, Constants::G_START_QML);
3025
3026     cmd = am->registerAction(m_attachToQmlPortAction,
3027         "Debugger.AttachToQmlPort", globalcontext);
3028     cmd->setAttribute(Command::CA_Hide);
3029     mstart->addAction(cmd, Constants::G_START_QML);
3030
3031     cmd = am->registerAction(m_detachAction,
3032         "Debugger.Detach", globalcontext);
3033     cmd->setAttribute(Command::CA_Hide);
3034     debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
3035
3036     cmd = am->registerAction(m_interruptAction,
3037         Constants::INTERRUPT, globalcontext);
3038     cmd->setDefaultText(tr("Interrupt Debugger"));
3039     debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
3040
3041     cmd = am->registerAction(m_continueAction,
3042         Constants::CONTINUE, globalcontext);
3043     cmd->setDefaultKeySequence(QKeySequence(Constants::DEBUG_KEY));
3044     debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
3045
3046     cmd = am->registerAction(m_exitAction,
3047         Constants::STOP, globalcontext);
3048     cmd->setDefaultText(tr("Stop Debugger"));
3049     debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
3050
3051     m_hiddenStopAction = new Utils::ProxyAction(this);
3052     m_hiddenStopAction->initialize(m_exitAction);
3053     m_hiddenStopAction->setAttribute(Utils::ProxyAction::UpdateText);
3054     m_hiddenStopAction->setAttribute(Utils::ProxyAction::UpdateIcon);
3055
3056     cmd = am->registerAction(m_hiddenStopAction,
3057         Constants::HIDDEN_STOP, globalcontext);
3058     cmd->setDefaultKeySequence(QKeySequence(Constants::STOP_KEY));
3059
3060     cmd = am->registerAction(m_resetAction,
3061         Constants::RESET, globalcontext);
3062     //cmd->setDefaultKeySequence(QKeySequence(Constants::RESET_KEY));
3063     cmd->setDefaultText(tr("Reset Debugger"));
3064     debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
3065
3066     sep = new QAction(this);
3067     sep->setSeparator(true);
3068     cmd = am->registerAction(sep, "Debugger.Sep.Step", globalcontext);
3069     debugMenu->addAction(cmd);
3070
3071     cmd = am->registerAction(m_nextAction,
3072         Constants::NEXT, globalcontext);
3073     cmd->setDefaultKeySequence(QKeySequence(Constants::NEXT_KEY));
3074     cmd->setAttribute(Command::CA_Hide);
3075     cmd->setAttribute(Command::CA_UpdateText);
3076     debugMenu->addAction(cmd);
3077
3078     cmd = am->registerAction(m_stepAction,
3079         Constants::STEP, globalcontext);
3080     cmd->setDefaultKeySequence(QKeySequence(Constants::STEP_KEY));
3081     cmd->setAttribute(Command::CA_Hide);
3082     cmd->setAttribute(Command::CA_UpdateText);
3083     debugMenu->addAction(cmd);
3084
3085     cmd = am->registerAction(m_stepOutAction,
3086         Constants::STEPOUT, cppDebuggercontext);
3087     cmd->setDefaultKeySequence(QKeySequence(Constants::STEPOUT_KEY));
3088     cmd->setAttribute(Command::CA_Hide);
3089     debugMenu->addAction(cmd);
3090
3091     cmd = am->registerAction(m_runToLineAction,
3092         "Debugger.RunToLine", cppDebuggercontext);
3093     cmd->setDefaultKeySequence(QKeySequence(Constants::RUN_TO_LINE_KEY));
3094     cmd->setAttribute(Command::CA_Hide);
3095     debugMenu->addAction(cmd);
3096
3097     cmd = am->registerAction(m_runToSelectedFunctionAction,
3098         "Debugger.RunToSelectedFunction", cppDebuggercontext);
3099     cmd->setDefaultKeySequence(QKeySequence(
3100         Constants::RUN_TO_SELECTED_FUNCTION_KEY));
3101     cmd->setAttribute(Command::CA_Hide);
3102     // Don't add to menu by default as keeping its enabled state
3103     // and text up-to-date is a lot of hassle.
3104     // debugMenu->addAction(cmd);
3105
3106     cmd = am->registerAction(m_jumpToLineAction,
3107         "Debugger.JumpToLine", cppDebuggercontext);
3108     cmd->setAttribute(Command::CA_Hide);
3109     debugMenu->addAction(cmd);
3110
3111     cmd = am->registerAction(m_returnFromFunctionAction,
3112         "Debugger.ReturnFromFunction", cppDebuggercontext);
3113     cmd->setAttribute(Command::CA_Hide);
3114     debugMenu->addAction(cmd);
3115
3116     cmd = am->registerAction(m_reverseDirectionAction,
3117         Constants::REVERSE, cppDebuggercontext);
3118     cmd->setDefaultKeySequence(QKeySequence(Constants::REVERSE_KEY));
3119     cmd->setAttribute(Command::CA_Hide);
3120     debugMenu->addAction(cmd);
3121
3122     sep = new QAction(this);
3123     sep->setSeparator(true);
3124     cmd = am->registerAction(sep, "Debugger.Sep.Break", globalcontext);
3125     debugMenu->addAction(cmd);
3126
3127     //cmd = am->registerAction(m_snapshotAction,
3128     //    "Debugger.Snapshot", cppDebuggercontext);
3129     //cmd->setDefaultKeySequence(QKeySequence(Constants::SNAPSHOT_KEY));
3130     //cmd->setAttribute(Command::CA_Hide);
3131     //debugMenu->addAction(cmd);
3132
3133     cmd = am->registerAction(m_frameDownAction,
3134         "Debugger.FrameDown", cppDebuggercontext);
3135     cmd = am->registerAction(m_frameUpAction,
3136         "Debugger.FrameUp", cppDebuggercontext);
3137
3138     cmd = am->registerAction(action(OperateByInstruction),
3139         Constants::OPERATE_BY_INSTRUCTION, cppDebuggercontext);
3140     cmd->setAttribute(Command::CA_Hide);
3141     debugMenu->addAction(cmd);
3142
3143     cmd = am->registerAction(m_breakAction,
3144         "Debugger.ToggleBreak", globalcontext);
3145     cmd->setDefaultKeySequence(QKeySequence(Constants::TOGGLE_BREAK_KEY));
3146     debugMenu->addAction(cmd);
3147     connect(m_breakAction, SIGNAL(triggered()),
3148         SLOT(toggleBreakpoint()));
3149
3150     sep = new QAction(this);
3151     sep->setSeparator(true);
3152     cmd = am->registerAction(sep, "Debugger.Sep.Watch", globalcontext);
3153     debugMenu->addAction(cmd);
3154
3155     // Don't add '1' to the string as it shows up in the shortcut dialog.
3156     cmd = am->registerAction(m_watchAction1,
3157         "Debugger.AddToWatch", cppeditorcontext);
3158     //cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+D,Ctrl+W")));
3159     debugMenu->addAction(cmd);
3160
3161     // If the CppEditor plugin is there, we want to add something to
3162     // the editor context menu.
3163     if (ActionContainer *editorContextMenu =
3164             am->actionContainer(CppEditor::Constants::M_CONTEXT)) {
3165         cmd = am->registerAction(sep, "Debugger.Sep.Views",
3166             cppDebuggercontext);
3167         editorContextMenu->addAction(cmd);
3168         cmd->setAttribute(Command::CA_Hide);
3169
3170         cmd = am->registerAction(m_watchAction2,
3171             "Debugger.AddToWatch2", cppDebuggercontext);
3172         cmd->action()->setEnabled(true);
3173         editorContextMenu->addAction(cmd);
3174         cmd->setAttribute(Command::CA_Hide);
3175         cmd->setAttribute(Command::CA_NonConfigurable);
3176         // Debugger.AddToWatch is enough.
3177     }
3178
3179     QList<Core::IOptionsPage *> engineOptionPages;
3180     if (m_cmdLineEnabledEngines & GdbEngineType)
3181         addGdbOptionPages(&engineOptionPages);
3182    addCdbOptionPages(&engineOptionPages);
3183 #ifdef WITH_LLDB
3184     if (m_cmdLineEnabledEngines & LldbEngineType)
3185         addLldbOptionPages(&engineOptionPages);
3186 #endif
3187
3188     //if (m_cmdLineEnabledEngines & ScriptEngineType)
3189     //    addScriptOptionPages(&engineOptionPages);
3190     //if (m_cmdLineEnabledEngines & TcfEngineType)
3191     //    addTcfOptionPages(&engineOptionPages);
3192     foreach (Core::IOptionsPage *op, engineOptionPages)
3193         m_plugin->addAutoReleasedObject(op);
3194     m_plugin->addAutoReleasedObject(new DebuggingHelperOptionPage);
3195
3196     connect(ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode*)),
3197         SLOT(onModeChanged(Core::IMode*)));
3198     connect(ICore::instance(), SIGNAL(coreAboutToOpen()),
3199         SLOT(onCoreAboutToOpen()));
3200
3201
3202     // Debug mode setup
3203     DebugMode *debugMode = new DebugMode;
3204     QWidget *widget = m_mainWindow->createContents(debugMode);
3205     widget->setFocusProxy(EditorManager::instance());
3206     debugMode->setWidget(widget);
3207
3208     m_plugin->addAutoReleasedObject(debugMode);
3209
3210     //
3211     //  Connections
3212     //
3213
3214     // Core
3215     connect(core, SIGNAL(saveSettingsRequested()), SLOT(writeSettings()));
3216
3217     // TextEditor
3218     connect(TextEditorSettings::instance(),
3219         SIGNAL(fontSettingsChanged(TextEditor::FontSettings)),
3220         SLOT(fontSettingsChanged(TextEditor::FontSettings)));
3221
3222     // ProjectExplorer
3223     connect(sessionManager(), SIGNAL(sessionLoaded()),
3224         SLOT(sessionLoaded()));
3225     connect(sessionManager(), SIGNAL(aboutToSaveSession()),
3226         SLOT(aboutToSaveSession()));
3227     connect(sessionManager(), SIGNAL(aboutToUnloadSession()),
3228         SLOT(aboutToUnloadSession()));
3229     connect(ProjectExplorerPlugin::instance(), SIGNAL(updateRunActions()),
3230         SLOT(updateDebugActions()));
3231
3232     // EditorManager
3233     QObject *editorManager = core->editorManager();
3234     connect(editorManager, SIGNAL(editorOpened(Core::IEditor*)),
3235         SLOT(editorOpened(Core::IEditor*)));
3236     connect(editorManager, SIGNAL(currentEditorChanged(Core::IEditor*)),
3237             SLOT(updateBreakMenuItem(Core::IEditor*)));
3238
3239     // Application interaction
3240     connect(action(SettingsDialog), SIGNAL(triggered()),
3241         SLOT(showSettingsDialog()));
3242
3243     // Toolbar
3244     QWidget *toolbarContainer = new QWidget;
3245
3246     QHBoxLayout *hbox = new QHBoxLayout(toolbarContainer);
3247     hbox->setMargin(0);
3248     hbox->setSpacing(0);
3249     hbox->addWidget(toolButton(m_visibleStartAction));
3250     hbox->addWidget(toolButton(m_exitAction));
3251     hbox->addWidget(toolButton(m_nextAction));
3252     hbox->addWidget(toolButton(m_stepAction));
3253     hbox->addWidget(toolButton(m_stepOutAction));
3254     hbox->addWidget(toolButton(action(OperateByInstruction)));
3255
3256     //hbox->addWidget(new Utils::StyledSeparator);
3257     m_reverseToolButton = toolButton(m_reverseDirectionAction);
3258     hbox->addWidget(m_reverseToolButton);
3259     //m_reverseToolButton->hide();
3260
3261     hbox->addWidget(new Utils::StyledSeparator);
3262     hbox->addWidget(new QLabel(tr("Threads:")));
3263
3264     m_threadBox = new QComboBox;
3265     m_threadBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
3266     connect(m_threadBox, SIGNAL(activated(int)), SLOT(selectThread(int)));
3267
3268     hbox->addWidget(m_threadBox);
3269     hbox->addSpacerItem(new QSpacerItem(4, 0));
3270     hbox->addWidget(m_statusLabel, 10);
3271
3272     m_mainWindow->setToolBar(CppLanguage, toolbarContainer);
3273
3274     connect(action(EnableReverseDebugging),
3275         SIGNAL(valueChanged(QVariant)),
3276         SLOT(enableReverseDebuggingTriggered(QVariant)));
3277
3278     setInitialState();
3279     connectEngine(0);
3280
3281     connect(sessionManager(),
3282         SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
3283         SLOT(onCurrentProjectChanged(ProjectExplorer::Project*)));
3284
3285     QTC_CHECK(m_coreSettings);
3286     m_globalDebuggerOptions->fromSettings(m_coreSettings);
3287     m_watchersWindow->setVisible(false);
3288     m_returnWindow->setVisible(false);
3289
3290     // time gdb -i mi -ex 'b debuggerplugin.cpp:800' -ex r -ex q bin/qtcreator.bin
3291     if (!m_scheduledStarts.isEmpty())
3292         QTimer::singleShot(0, this, SLOT(runScheduled()));
3293 }
3294
3295 Utils::SavedAction *DebuggerPluginPrivate::action(int code) const
3296 {
3297     return m_debuggerSettings->item(code);
3298 }
3299
3300 bool DebuggerPluginPrivate::boolSetting(int code) const
3301 {
3302     return m_debuggerSettings->item(code)->value().toBool();
3303 }
3304
3305 QString DebuggerPluginPrivate::stringSetting(int code) const
3306 {
3307     return m_debuggerSettings->item(code)->value().toString();
3308 }
3309
3310 void DebuggerPluginPrivate::showModuleSymbols(const QString &moduleName,
3311     const Symbols &symbols)
3312 {
3313     QTreeWidget *w = new QTreeWidget;
3314     w->setColumnCount(5);
3315     w->setRootIsDecorated(false);
3316     w->setAlternatingRowColors(true);
3317     w->setSortingEnabled(true);
3318     w->setObjectName("Symbols." + moduleName);
3319     QStringList header;
3320     header.append(tr("Symbol"));
3321     header.append(tr("Address"));
3322     header.append(tr("Code"));
3323     header.append(tr("Section"));
3324     header.append(tr("Name"));
3325     w->setHeaderLabels(header);
3326     w->setWindowTitle(tr("Symbols in \"%1\"").arg(moduleName));
3327     foreach (const Symbol &s, symbols) {
3328         QTreeWidgetItem *it = new QTreeWidgetItem;
3329         it->setData(0, Qt::DisplayRole, s.name);
3330         it->setData(1, Qt::DisplayRole, s.address);
3331         it->setData(2, Qt::DisplayRole, s.state);
3332         it->setData(3, Qt::DisplayRole, s.section);
3333         it->setData(4, Qt::DisplayRole, s.demangled);
3334         w->addTopLevelItem(it);
3335     }
3336     createNewDock(w);
3337 }
3338
3339 void DebuggerPluginPrivate::aboutToShutdown()
3340 {
3341     m_plugin->removeObject(this);
3342     disconnect(sessionManager(),
3343         SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
3344         this, 0);
3345 }
3346
3347 } // namespace Internal
3348
3349
3350 ///////////////////////////////////////////////////////////////////////
3351 //
3352 // DebuggerPlugin
3353 //
3354 ///////////////////////////////////////////////////////////////////////
3355
3356 using namespace Debugger::Internal;
3357
3358 /*!
3359     \class Debugger::DebuggerPlugin
3360
3361     This is the "external" interface of the debugger plugin that's visible
3362     from Qt Creator core. The internal interface to global debugger
3363     functionality that is used by debugger views and debugger engines
3364     is DebuggerCore, implemented in DebuggerPluginPrivate. */
3365
3366 DebuggerPlugin::DebuggerPlugin()
3367 {
3368     theDebuggerCore = new DebuggerPluginPrivate(this);
3369 }
3370
3371 DebuggerPlugin::~DebuggerPlugin()
3372 {
3373     delete theDebuggerCore;
3374     theDebuggerCore = 0;
3375 }
3376
3377 bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMessage)
3378 {
3379     ICore *core = ICore::instance();
3380     QTC_ASSERT(core, return true);
3381
3382     // Menu groups
3383     const Context globalcontext(CC::C_GLOBAL);
3384
3385     Core::ActionManager *am = core->actionManager();
3386     ActionContainer *mstart = am->actionContainer(PE::M_DEBUG_STARTDEBUGGING);
3387
3388     mstart->appendGroup(Constants::G_START_CPP);
3389     mstart->appendGroup(Constants::G_START_QML);
3390
3391     // add cpp separator
3392     QAction *sep = new QAction(mstart);
3393     sep->setSeparator(true);
3394     Command *cmd = am->registerAction(sep,
3395         "Debugger.Start.Cpp", globalcontext);
3396     mstart->addAction(cmd, Constants::G_START_CPP);
3397
3398     return theDebuggerCore->initialize(arguments, errorMessage);
3399 }
3400
3401 ExtensionSystem::IPlugin::ShutdownFlag DebuggerPlugin::aboutToShutdown()
3402 {
3403     theDebuggerCore->aboutToShutdown();
3404     return SynchronousShutdown;
3405 }
3406
3407 void DebuggerPlugin::remoteCommand(const QStringList &options,
3408     const QStringList &list)
3409 {
3410     theDebuggerCore->remoteCommand(options, list);
3411 }
3412
3413 DebuggerRunControl *DebuggerPlugin::createDebugger
3414     (const DebuggerStartParameters &sp, RunConfiguration *rc)
3415 {
3416     return theDebuggerCore->createDebugger(sp, rc);
3417 }
3418
3419 void DebuggerPlugin::startDebugger(RunControl *runControl)
3420 {
3421     theDebuggerCore->startDebugger(runControl);
3422 }
3423
3424 void DebuggerPlugin::extensionsInitialized()
3425 {
3426     theDebuggerCore->extensionsInitialized();
3427 }
3428
3429 bool DebuggerPlugin::isActiveDebugLanguage(int language)
3430 {
3431     return theDebuggerCore->isActiveDebugLanguage(language);
3432 }
3433
3434 DebuggerMainWindow *DebuggerPlugin::mainWindow()
3435 {
3436     return theDebuggerCore->m_mainWindow;
3437 }
3438
3439 QAction *DebuggerPlugin::visibleDebugAction()
3440 {
3441     return theDebuggerCore->m_visibleStartAction;
3442 }
3443
3444 } // namespace Debugger
3445
3446 #include "debuggerplugin.moc"
3447
3448 Q_EXPORT_PLUGIN(Debugger::DebuggerPlugin)