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