src/scripttools/debugging/qscriptenginedebugger.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     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"