0
|
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"
|