1/****************************************************************************
2**
3** Copyright (C) 2018 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtSCriptTools module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qscriptenginedebugger.h"
41#include "qscriptdebugger_p.h"
42#include "qscriptenginedebuggerfrontend_p.h"
43#include "qscriptdebuggerstandardwidgetfactory_p.h"
44#include <private/qobject_p.h>
45
46#include <QtCore/qsettings.h>
47#include <QtWidgets/qapplication.h>
48#include <QtWidgets/qdockwidget.h>
49#include <QtWidgets/qmainwindow.h>
50#include <QtWidgets/qmenubar.h>
51#include <QtWidgets/qboxlayout.h>
52
53// this has to be outside the namespace
54static void initScriptEngineDebuggerResources()
55{
56 Q_INIT_RESOURCE(scripttools_debugging);
57}
58
59QT_BEGIN_NAMESPACE
60
61class QtScriptDebuggerResourceInitializer
62{
63public:
64 QtScriptDebuggerResourceInitializer() {
65 // call outside-the-namespace function
66 initScriptEngineDebuggerResources();
67 }
68};
69
70/*!
71 \since 4.5
72 \class QScriptEngineDebugger
73 \inmodule QtScriptTools
74 \brief The QScriptEngineDebugger class provides a QScriptEngine debugger.
75
76 \ingroup script
77
78
79 The QScriptEngineDebugger class provides a debugger that can be
80 embedded into Qt applications that use Qt Script. The debugger
81 enables the application user to inspect the state of the script
82 environment and control script execution.
83
84 To attach the debugger to a script engine, call the attachTo()
85 function.
86
87 \snippet src.scripttools.qscriptenginedebugger.cpp 0
88
89 Once the debugger has been attached to a script engine, you can
90 proceed to evaluate scripts as usual, e.g. by calling
91 QScriptEngine::evaluate(). The debugger will be triggered when an
92 uncaught exception occurs, or when a \c{debugger} statement is
93 encountered in a script. It is also possible to interrupt script
94 evaluation at an arbitrary time by triggering the InterruptAction.
95 For instance, to start the debugger when script evaluation starts,
96 you trigger the action before you begin to \l{QScriptEngine::}{evaluate()}
97 the script.
98
99 \snippet scriptdebugger.cpp 2
100
101 By default, the \l{standardWindow()}{standard debugger window} is shown when
102 evaluation is suspended. This can be changed by calling the
103 setAutoShowStandardWindow() function.
104
105 The debugger defines a set of \l{DebuggerAction}{actions} that are
106 available, such as stopping execution or printing the contents of a
107 variable. It also provides a set of widgets (components) that
108 display the information available from the debugger and that trigger
109 the actions on request. The actions available are identified by the
110 DebuggerAction enum, and the widgets are identified by the
111 DebuggerWidget enum.
112
113 Access to the individual debugger widgets is provided by the
114 widget() function. This makes it possible to arrange the widgets in
115 a custom manner. Similarly, the action() function provides access
116 to the various debugger actions.
117
118 The createStandardToolBar() function creates a standard toolbar, and the
119 createStandardMenu() function creates a standard menu; these functions can
120 be useful if you are creating a custom debugger configuration.
121
122 The evaluationSuspended() signal is emitted when the debugger has
123 suspended script evaluation and entered interactive mode, i.e., the
124 mode in which it accepts input from the user. The
125 evaluationResumed() signal is emitted when script evaluation is
126 resumed, i.e, when execution control is given back to the script
127 engine. The state() function returns the debugger's current state.
128
129 When calling QScriptEngine::evaluate() it is useful to pass a
130 descriptive script name (file name) as second argument, as this is
131 the name that will be displayed by the debugger in the
132 ScriptsWidget; if a name is not passed, the script will be labelled
133 "anonymous".
134
135 When evaluation is suspended, the debugger will also suspend the
136 event loop of the script. In the following snippet, the call to
137 QScriptEngine::evaluate() causes the debugger to be triggered, and
138 the function call does not return until the user has finished
139 interacting with the debugger.
140
141 \snippet src.scripttools.qscriptenginedebugger.cpp 1
142
143 When the Qt Script debugger is running, the C++ application itself
144 is not "frozen". This means that it is possible that more scripts
145 are evaluated, even though the debugger has suspended evaluation of
146 the \b{current} script evaluation. For example, a C++ timer might
147 trigger that causes a script function to be called, or the user
148 might click on a button in the main application user interface whose
149 clicked() signal is connected to a script function. This kind of
150 nested evaluation is permitted. The debugger will enter interactive
151 mode for the new script if an exception is thrown or a breakpoint is
152 reached. Note that it will not stop when encountering \c{debugger}
153 statements. \omit The effects are similar to those achieved by
154 typing a program into the debugger's console and evaluating
155 it. \endomit
156
157 Nested evaluation requires some thought when deciding
158 how the debugger is presented to the user; for example, whether a
159 modal dialog is suitable, or whether some parts of the main
160 application user interface should be disabled while the debugger is
161 running. \omit Seems unfinished somehow \endomit
162
163 Debugging inside of a \l{QWidget::paintEvent()}{paintEvent}() is
164 currently not supported. If you need to debug painting-related
165 script code, that code should be evaluated outside of the C++
166 paintEvent(), e.g. by rendering to an image, like the Context2D and
167 Tetrix Qt Script examples do. This will make the code safe for
168 debugging.
169
170 The debugger adds some special properties to the script engine:
171 \c{__FILE__} holds the name of the script in which the current
172 evaluation occurs, and \c{__LINE__} holds the current line
173 number. These are useful when doing print()-style debugging (the
174 messages appear in the debugger's debug output widget).
175
176 The \l{Qt Script Debugger Manual} describes how to use the debugger.
177 The \l{Context2D Example}{Context2D example} shows how to integrate
178 the debugger in applications.
179
180 \sa QScriptEngine, {Context2D Example}
181*/
182
183/*!
184 \enum QScriptEngineDebugger::DebuggerWidget
185
186 This enum decides the widget that the widget() function should
187 retrieve. We treat these widgets in more detail in the \l{Qt
188 Script Debugger Manual}.
189
190 \value ConsoleWidget Provides a command-line interface to the debugger.
191 \value StackWidget Shows a backtrace of the script's execution state.
192 \value ScriptsWidget Displays a list of currently loaded scripts.
193 \value LocalsWidget Shows the local variables of the current stack frame.
194 \value CodeWidget Displays the code of the current script.
195 \value CodeFinderWidget Provides a widget that can search for text in the script shown in the
196 CodeWidget.
197 \value BreakpointsWidget Shows breakpoints that have been set.
198 \value DebugOutputWidget Contains output from the \c print() script function.
199 \value ErrorLogWidget Shows error messages that have been generated.
200*/
201
202/*!
203 \enum QScriptEngineDebugger::DebuggerAction
204
205 This enum specifies the action that the action() function should
206 retrieve. The actions retrieved can be connected to any slot and
207 connected to any widget. Please see the \l{Qt Script Debugger Manual}'s
208 \l{Console Command Reference} for a detailed description of these actions.
209
210 \value InterruptAction Suspends script execution as soon as the next script statement is reached.
211 \value ContinueAction Gives the execution control back to the script engine.
212 \value StepIntoAction Performs a step action.
213 \value StepOverAction Performs a next action.
214 \value StepOutAction Executes the script until the current function returns.
215 \value RunToCursorAction Continues execution to the selected line (which contains the cursor) in the CodeWidget.
216 \value RunToNewScriptAction Returns control to the script engine until a new script is executed.
217 \value ToggleBreakpointAction Toggles a breakpoint at the selected line in the CodeWidget.
218 \value ClearDebugOutputAction Clears the contents of the DebugOutputWidget.
219 \value ClearErrorLogAction Clears the contents of the ErrorLogWidget.
220 \value ClearConsoleAction Clears the contents of the ConsoleWidget.
221 \value FindInScriptAction Displays the CodeFinderWidget.
222 \value FindNextInScriptAction Finds next occurrence in the CodeWidget.
223 \value FindPreviousInScriptAction Finds previous occurrence in the CodeWidget.
224 \value GoToLineAction Shows the "Go to Line" dialog.
225*/
226
227/*!
228 \enum QScriptEngineDebugger::DebuggerState
229 \since 4.6
230
231 This enum specifies the current state of the debugger.
232
233 \value RunningState The debugger is running. (Script evaluation is allowed.)
234 \value SuspendedState The debugger has suspended script evaluation.
235*/
236
237class QScriptEngineDebuggerPrivate
238 : public QObjectPrivate
239{
240 Q_DECLARE_PUBLIC(QScriptEngineDebugger)
241public:
242 QScriptEngineDebuggerPrivate();
243 ~QScriptEngineDebuggerPrivate();
244
245 // private slots
246 void _q_showStandardWindow();
247
248 void createDebugger();
249
250 QScriptDebugger *debugger;
251 QScriptEngineDebuggerFrontend *frontend;
252#ifndef QT_NO_MAINWINDOW
253 QMainWindow *standardWindow;
254#endif
255 bool autoShow;
256
257 static QtScriptDebuggerResourceInitializer resourceInitializer;
258};
259
260namespace {
261
262class WidgetClosedNotifier : public QObject
263{
264 Q_OBJECT
265public:
266 WidgetClosedNotifier(QWidget *w, QObject *parent = 0)
267 : QObject(parent), widget(w)
268 {
269 w->installEventFilter(filterObj: this);
270 }
271
272 bool eventFilter(QObject *watched, QEvent *e)
273 {
274 if (watched != widget)
275 return false;
276 if (e->type() != QEvent::Close)
277 return false;
278 emit widgetClosed();
279 return true;
280 }
281
282Q_SIGNALS:
283 void widgetClosed();
284
285private:
286 QWidget *widget;
287};
288
289} // namespace
290
291QtScriptDebuggerResourceInitializer QScriptEngineDebuggerPrivate::resourceInitializer;
292
293QScriptEngineDebuggerPrivate::QScriptEngineDebuggerPrivate()
294{
295 debugger = 0;
296 frontend = 0;
297#ifndef QT_NO_MAINWINDOW
298 standardWindow = 0;
299#endif
300 autoShow = true;
301}
302
303QScriptEngineDebuggerPrivate::~QScriptEngineDebuggerPrivate()
304{
305 delete debugger;
306 delete frontend;
307#ifndef QT_NO_MAINWINDOW
308 if (standardWindow) {
309 QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
310 QByteArray geometry = standardWindow->saveGeometry();
311 settings.setValue(key: QLatin1String("Qt/scripttools/debugging/mainWindowGeometry"), value: geometry);
312 QByteArray state = standardWindow->saveState();
313 settings.setValue(key: QLatin1String("Qt/scripttools/debugging/mainWindowState"), value: state);
314 if (standardWindow->parent() == 0)
315 delete standardWindow;
316 }
317#endif
318}
319
320#ifndef QT_NO_MAINWINDOW
321void QScriptEngineDebuggerPrivate::_q_showStandardWindow()
322{
323 Q_Q(QScriptEngineDebugger);
324 (void)q->standardWindow(); // ensure it's created
325 standardWindow->show();
326}
327#endif
328
329void QScriptEngineDebuggerPrivate::createDebugger()
330{
331 Q_Q(QScriptEngineDebugger);
332 if (!debugger) {
333 debugger = new QScriptDebugger();
334 debugger->setWidgetFactory(new QScriptDebuggerStandardWidgetFactory(q));
335 QObject::connect(sender: debugger, SIGNAL(started()),
336 receiver: q, SIGNAL(evaluationResumed()));
337 QObject::connect(sender: debugger, SIGNAL(stopped()),
338 receiver: q, SIGNAL(evaluationSuspended()));
339 if (autoShow) {
340 QObject::connect(sender: q, SIGNAL(evaluationSuspended()),
341 receiver: q, SLOT(_q_showStandardWindow()));
342 }
343 }
344}
345
346/*!
347 Constructs a new QScriptEngineDebugger object with the given \a
348 parent.
349
350 To attach a QScriptEngine to the debugger, use attachTo()
351 function.
352
353*/
354QScriptEngineDebugger::QScriptEngineDebugger(QObject *parent)
355 : QObject(*new QScriptEngineDebuggerPrivate, parent)
356{
357}
358
359/*!
360 Destroys this QScriptEngineDebugger.
361*/
362QScriptEngineDebugger::~QScriptEngineDebugger()
363{
364}
365
366/*!
367 Attaches to the given \a engine.
368
369 The debugger will install a custom agent (using
370 QScriptEngine::setAgent()) to monitor the engine. While the debugger
371 is attached, you should not change the agent; however, if you do
372 have to perform additional monitoring, you must set a proxy agent
373 that forwards all events to the debugger's agent.
374
375 \sa detach()
376*/
377void QScriptEngineDebugger::attachTo(QScriptEngine *engine)
378{
379 Q_D(QScriptEngineDebugger);
380 if (!engine) {
381 detach();
382 return;
383 }
384 d->createDebugger();
385 if (!d->frontend)
386 d->frontend = new QScriptEngineDebuggerFrontend();
387 d->frontend->attachTo(engine);
388 d->debugger->setFrontend(d->frontend);
389}
390
391/*!
392 Detaches from the current script engine, if any.
393
394 \sa attachTo()
395*/
396void QScriptEngineDebugger::detach()
397{
398 Q_D(QScriptEngineDebugger);
399 if (d->frontend)
400 d->frontend->detach();
401 if (d->debugger)
402 d->debugger->setFrontend(0);
403}
404
405/*!
406 \since 4.6
407
408 Returns the current state of the debugger.
409
410 \sa evaluationResumed()
411 \sa evaluationSuspended()
412*/
413QScriptEngineDebugger::DebuggerState QScriptEngineDebugger::state() const
414{
415 Q_D(const QScriptEngineDebugger);
416 return !d->debugger || !d->debugger->isInteractive() ? SuspendedState : RunningState;
417}
418
419/*!
420
421 Returns a pointer to the instance of the specified standard \a
422 widget. The widgets available are defined by the DebuggerWidget
423 enum.
424
425 A main window containing all widgets is returned by
426 standardWindow(). If you do not want to use this window, you can
427 fetch the individual widgets with this function. For instance, the
428 code example below shows how to set up a layout containing a
429 \l{QScriptEngineDebugger::CodeWidget}{code window} and a
430 \l{QScriptEngineDebugger::StackWidget}{stack widget}.
431
432 \snippet scriptdebugger.cpp 0
433
434 Note that you need to set setAutoShowStandardWindow() to false; if
435 not, the standard window will be shown regardless.
436
437 \sa action(), standardWindow(), setAutoShowStandardWindow()
438*/
439QWidget *QScriptEngineDebugger::widget(DebuggerWidget widget) const
440{
441 Q_D(const QScriptEngineDebugger);
442 const_cast<QScriptEngineDebuggerPrivate*>(d)->createDebugger();
443 return d->debugger->widget(widget: static_cast<QScriptDebugger::DebuggerWidget>(static_cast<int>(widget)));
444}
445
446/*!
447 Returns a pointer to the specified \a action. The actions available
448 are given by the DebuggerAction enum.
449
450 With this function, you can add the actions to your own widgets,
451 toolbars, and menus. It is also convenient if you, for example,
452 wish to spice things up with your own groovy icons. The code
453 example below shows how to add actions to a QToolBar.
454
455 \snippet scriptdebugger.cpp 1
456
457 Note that QScriptEngineDebugger has already added the actions to
458 its \l{DebuggerWidget}{standard widgets} and \l{standardWindow()}{standard window}.
459
460 \sa widget(), createStandardMenu(), createStandardToolBar(), standardWindow()
461*/
462QAction *QScriptEngineDebugger::action(DebuggerAction action) const
463{
464 Q_D(const QScriptEngineDebugger);
465 QScriptEngineDebugger *that = const_cast<QScriptEngineDebugger*>(this);
466 that->d_func()->createDebugger();
467 return d->debugger->action(action: static_cast<QScriptDebugger::DebuggerAction>(static_cast<int>(action)), parent: that);
468}
469
470/*!
471 Returns whether the standard debugger window is automatically shown when
472 evaluation is suspended.
473
474 The default is true.
475*/
476bool QScriptEngineDebugger::autoShowStandardWindow() const
477{
478 Q_D(const QScriptEngineDebugger);
479 return d->autoShow;
480}
481
482/*!
483 Sets whether the standard debugger window is automatically shown when
484 evaluation is suspended. If \a autoShow is true, the window will be
485 automatically shown, otherwise it will not.
486*/
487void QScriptEngineDebugger::setAutoShowStandardWindow(bool autoShow)
488{
489 Q_D(QScriptEngineDebugger);
490 if (autoShow == d->autoShow)
491 return;
492 if (autoShow) {
493 QObject::connect(sender: this, SIGNAL(evaluationSuspended()),
494 receiver: this, SLOT(_q_showStandardWindow()));
495 } else {
496 QObject::disconnect(sender: this, SIGNAL(evaluationSuspended()),
497 receiver: this, SLOT(_q_showStandardWindow()));
498 }
499 d->autoShow = autoShow;
500}
501
502/*!
503 Returns a main window with a standard configuration of the debugger's
504 components.
505
506 \sa createStandardMenu(), createStandardToolBar()
507*/
508#ifndef QT_NO_MAINWINDOW
509QMainWindow *QScriptEngineDebugger::standardWindow() const
510{
511 Q_D(const QScriptEngineDebugger);
512 if (d->standardWindow)
513 return d->standardWindow;
514 if (!QApplication::instance())
515 return 0;
516 QScriptEngineDebugger *that = const_cast<QScriptEngineDebugger*>(this);
517
518 QMainWindow *win = new QMainWindow();
519#ifndef QT_NO_DOCKWIDGET
520 QDockWidget *scriptsDock = new QDockWidget(win);
521 scriptsDock->setObjectName(QLatin1String("qtscriptdebugger_scriptsDockWidget"));
522 scriptsDock->setWindowTitle(tr(s: "Loaded Scripts"));
523 scriptsDock->setWidget(widget(widget: ScriptsWidget));
524 win->addDockWidget(area: Qt::LeftDockWidgetArea, dockwidget: scriptsDock);
525
526 QDockWidget *breakpointsDock = new QDockWidget(win);
527 breakpointsDock->setObjectName(QLatin1String("qtscriptdebugger_breakpointsDockWidget"));
528 breakpointsDock->setWindowTitle(tr(s: "Breakpoints"));
529 breakpointsDock->setWidget(widget(widget: BreakpointsWidget));
530 win->addDockWidget(area: Qt::LeftDockWidgetArea, dockwidget: breakpointsDock);
531
532 QDockWidget *stackDock = new QDockWidget(win);
533 stackDock->setObjectName(QLatin1String("qtscriptdebugger_stackDockWidget"));
534 stackDock->setWindowTitle(tr(s: "Stack"));
535 stackDock->setWidget(widget(widget: StackWidget));
536 win->addDockWidget(area: Qt::RightDockWidgetArea, dockwidget: stackDock);
537
538 QDockWidget *localsDock = new QDockWidget(win);
539 localsDock->setObjectName(QLatin1String("qtscriptdebugger_localsDockWidget"));
540 localsDock->setWindowTitle(tr(s: "Locals"));
541 localsDock->setWidget(widget(widget: LocalsWidget));
542 win->addDockWidget(area: Qt::RightDockWidgetArea, dockwidget: localsDock);
543
544 QDockWidget *consoleDock = new QDockWidget(win);
545 consoleDock->setObjectName(QLatin1String("qtscriptdebugger_consoleDockWidget"));
546 consoleDock->setWindowTitle(tr(s: "Console"));
547 consoleDock->setWidget(widget(widget: ConsoleWidget));
548 win->addDockWidget(area: Qt::BottomDockWidgetArea, dockwidget: consoleDock);
549
550 QDockWidget *debugOutputDock = new QDockWidget(win);
551 debugOutputDock->setObjectName(QLatin1String("qtscriptdebugger_debugOutputDockWidget"));
552 debugOutputDock->setWindowTitle(tr(s: "Debug Output"));
553 debugOutputDock->setWidget(widget(widget: DebugOutputWidget));
554 win->addDockWidget(area: Qt::BottomDockWidgetArea, dockwidget: debugOutputDock);
555
556 QDockWidget *errorLogDock = new QDockWidget(win);
557 errorLogDock->setObjectName(QLatin1String("qtscriptdebugger_errorLogDockWidget"));
558 errorLogDock->setWindowTitle(tr(s: "Error Log"));
559 errorLogDock->setWidget(widget(widget: ErrorLogWidget));
560 win->addDockWidget(area: Qt::BottomDockWidgetArea, dockwidget: errorLogDock);
561
562 win->tabifyDockWidget(first: errorLogDock, second: debugOutputDock);
563 win->tabifyDockWidget(first: debugOutputDock, second: consoleDock);
564#endif
565
566#ifndef QT_NO_TOOLBAR
567 win->addToolBar(area: Qt::TopToolBarArea, toolbar: that->createStandardToolBar());
568#endif
569
570#ifndef QT_NO_MENUBAR
571 win->menuBar()->addMenu(menu: that->createStandardMenu(parent: win));
572
573 QMenu *editMenu = win->menuBar()->addMenu(title: tr(s: "Search"));
574 editMenu->addAction(action: action(action: FindInScriptAction));
575 editMenu->addAction(action: action(action: FindNextInScriptAction));
576 editMenu->addAction(action: action(action: FindPreviousInScriptAction));
577 editMenu->addSeparator();
578 editMenu->addAction(action: action(action: GoToLineAction));
579
580#ifndef QT_NO_DOCKWIDGET
581 QMenu *viewMenu = win->menuBar()->addMenu(title: tr(s: "View"));
582 viewMenu->addAction(action: scriptsDock->toggleViewAction());
583 viewMenu->addAction(action: breakpointsDock->toggleViewAction());
584 viewMenu->addAction(action: stackDock->toggleViewAction());
585 viewMenu->addAction(action: localsDock->toggleViewAction());
586 viewMenu->addAction(action: consoleDock->toggleViewAction());
587 viewMenu->addAction(action: debugOutputDock->toggleViewAction());
588 viewMenu->addAction(action: errorLogDock->toggleViewAction());
589#endif
590#endif
591
592 QWidget *central = new QWidget();
593 QVBoxLayout *vbox = new QVBoxLayout(central);
594 vbox->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
595 vbox->addWidget(widget(widget: CodeWidget));
596 vbox->addWidget(widget(widget: CodeFinderWidget));
597 widget(widget: CodeFinderWidget)->hide();
598 win->setCentralWidget(central);
599
600 win->setWindowTitle(tr(s: "Qt Script Debugger"));
601#ifndef QT_NO_TOOLBAR
602 win->setUnifiedTitleAndToolBarOnMac(true);
603#endif
604
605 QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
606 QVariant geometry = settings.value(key: QLatin1String("Qt/scripttools/debugging/mainWindowGeometry"));
607 if (geometry.isValid())
608 win->restoreGeometry(geometry: geometry.toByteArray());
609 QVariant state = settings.value(key: QLatin1String("Qt/scripttools/debugging/mainWindowState"));
610 if (state.isValid())
611 win->restoreState(state: state.toByteArray());
612
613 WidgetClosedNotifier *closedNotifier = new WidgetClosedNotifier(win, that);
614 QObject::connect(sender: closedNotifier, SIGNAL(widgetClosed()),
615 receiver: action(action: ContinueAction), SLOT(trigger()));
616
617 const_cast<QScriptEngineDebuggerPrivate*>(d)->standardWindow = win;
618 return win;
619}
620#endif // QT_NO_MAINWINDOW
621
622/*!
623 Creates a standard debugger menu with the given \a parent.
624 Returns the new menu object.
625
626 \sa createStandardToolBar()
627*/
628QMenu *QScriptEngineDebugger::createStandardMenu(QWidget *parent)
629{
630 Q_D(QScriptEngineDebugger);
631 d->createDebugger();
632 return d->debugger->createStandardMenu(widgetParent: parent, actionParent: this);
633}
634
635/*!
636 Creates a standard debugger toolbar with the given \a parent.
637 Returns the new toolbar object.
638
639 \sa createStandardMenu()
640*/
641#ifndef QT_NO_TOOLBAR
642QToolBar *QScriptEngineDebugger::createStandardToolBar(QWidget *parent)
643{
644 Q_D(QScriptEngineDebugger);
645 d->createDebugger();
646 return d->debugger->createStandardToolBar(widgetParent: parent, actionParent: this);
647}
648#endif
649
650/*!
651 \fn QScriptEngineDebugger::evaluationSuspended()
652
653 This signal is emitted when the debugger has suspended script
654 evaluation for whatever reason (e.g. due to an uncaught script
655 exception, or due to a breakpoint being triggered).
656
657 \sa evaluationResumed()
658*/
659
660/*!
661 \fn QScriptEngineDebugger::evaluationResumed()
662
663 This signal is emitted when the debugger has resumed script
664 evaluation (e.g. the user gave the "continue" command).
665
666 \sa evaluationSuspended()
667*/
668
669QT_END_NAMESPACE
670
671#include "qscriptenginedebugger.moc"
672
673#include "moc_qscriptenginedebugger.cpp"
674

source code of qtscript/src/scripttools/debugging/qscriptenginedebugger.cpp