Qt 4.8
qscriptenginedebugger.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qscriptenginedebugger.h"
43 #include "qscriptdebugger_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
57 {
58  Q_INIT_RESOURCE(scripttools_debugging);
59 }
60 
62 
64 {
65 public:
67  // call outside-the-namespace function
69  }
70 };
71 
252  : public QObjectPrivate
253 {
255 public:
258 
259  // private slots
260  void _q_showStandardWindow();
261 
262  void createDebugger();
263 
266 #ifndef QT_NO_MAINWINDOW
268 #endif
269  bool autoShow;
270 
272 };
273 
274 namespace {
275 
276 class WidgetClosedNotifier : public QObject
277 {
278  Q_OBJECT
279 public:
280  WidgetClosedNotifier(QWidget *w, QObject *parent = 0)
281  : QObject(parent), widget(w)
282  {
283  w->installEventFilter(this);
284  }
285 
286  bool eventFilter(QObject *watched, QEvent *e)
287  {
288  if (watched != widget)
289  return false;
290  if (e->type() != QEvent::Close)
291  return false;
292  emit widgetClosed();
293  return true;
294  }
295 
296 Q_SIGNALS:
297  void widgetClosed();
298 
299 private:
300  QWidget *widget;
301 };
302 
303 } // namespace
304 
306 
308 {
309  debugger = 0;
310  frontend = 0;
311 #ifndef QT_NO_MAINWINDOW
312  standardWindow = 0;
313 #endif
314  autoShow = true;
315 }
316 
318 {
319  delete debugger;
320  delete frontend;
321 #ifndef QT_NO_MAINWINDOW
322  if (standardWindow) {
323  QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
324  QByteArray geometry = standardWindow->saveGeometry();
325  settings.setValue(QLatin1String("Qt/scripttools/debugging/mainWindowGeometry"), geometry);
326  QByteArray state = standardWindow->saveState();
327  settings.setValue(QLatin1String("Qt/scripttools/debugging/mainWindowState"), state);
328  if (standardWindow->parent() == 0)
329  delete standardWindow;
330  }
331 #endif
332 }
333 
334 #ifndef QT_NO_MAINWINDOW
336 {
338  (void)q->standardWindow(); // ensure it's created
339  standardWindow->show();
340 }
341 #endif
342 
344 {
346  if (!debugger) {
347  debugger = new QScriptDebugger();
348  debugger->setWidgetFactory(new QScriptDebuggerStandardWidgetFactory(q));
349  QObject::connect(debugger, SIGNAL(started()),
350  q, SIGNAL(evaluationResumed()));
351  QObject::connect(debugger, SIGNAL(stopped()),
352  q, SIGNAL(evaluationSuspended()));
353  if (autoShow) {
354  QObject::connect(q, SIGNAL(evaluationSuspended()),
355  q, SLOT(_q_showStandardWindow()));
356  }
357  }
358 }
359 
369  : QObject(*new QScriptEngineDebuggerPrivate, parent)
370 {
371 }
372 
377 {
378 }
379 
392 {
394  if (!engine) {
395  detach();
396  return;
397  }
398  d->createDebugger();
399  if (!d->frontend)
400  d->frontend = new QScriptEngineDebuggerFrontend();
401  d->frontend->attachTo(engine);
402  d->debugger->setFrontend(d->frontend);
403 }
404 
411 {
413  if (d->frontend)
414  d->frontend->detach();
415  if (d->debugger)
416  d->debugger->setFrontend(0);
417 }
418 
431 {
432  Q_D(const QScriptEngineDebugger);
433  return !d->debugger || !d->debugger->isInteractive() ? SuspendedState : RunningState;
434 }
435 
457 {
458  Q_D(const QScriptEngineDebugger);
459  const_cast<QScriptEngineDebuggerPrivate*>(d)->createDebugger();
460  return d->debugger->widget(static_cast<QScriptDebugger::DebuggerWidget>(static_cast<int>(widget)));
461 }
462 
480 {
481  Q_D(const QScriptEngineDebugger);
482  QScriptEngineDebugger *that = const_cast<QScriptEngineDebugger*>(this);
483  that->d_func()->createDebugger();
484  return d->debugger->action(static_cast<QScriptDebugger::DebuggerAction>(static_cast<int>(action)), that);
485 }
486 
494 {
495  Q_D(const QScriptEngineDebugger);
496  return d->autoShow;
497 }
498 
505 {
507  if (autoShow == d->autoShow)
508  return;
509  if (autoShow) {
511  this, SLOT(_q_showStandardWindow()));
512  } else {
514  this, SLOT(_q_showStandardWindow()));
515  }
516  d->autoShow = autoShow;
517 }
518 
525 #ifndef QT_NO_MAINWINDOW
527 {
528  Q_D(const QScriptEngineDebugger);
529  if (d->standardWindow)
530  return d->standardWindow;
531  if (!QApplication::instance())
532  return 0;
533  QScriptEngineDebugger *that = const_cast<QScriptEngineDebugger*>(this);
534 
535  QMainWindow *win = new QMainWindow();
536  QDockWidget *scriptsDock = new QDockWidget(win);
537  scriptsDock->setObjectName(QLatin1String("qtscriptdebugger_scriptsDockWidget"));
538  scriptsDock->setWindowTitle(tr("Loaded Scripts"));
539  scriptsDock->setWidget(widget(ScriptsWidget));
540  win->addDockWidget(Qt::LeftDockWidgetArea, scriptsDock);
541 
542  QDockWidget *breakpointsDock = new QDockWidget(win);
543  breakpointsDock->setObjectName(QLatin1String("qtscriptdebugger_breakpointsDockWidget"));
544  breakpointsDock->setWindowTitle(tr("Breakpoints"));
545  breakpointsDock->setWidget(widget(BreakpointsWidget));
546  win->addDockWidget(Qt::LeftDockWidgetArea, breakpointsDock);
547 
548  QDockWidget *stackDock = new QDockWidget(win);
549  stackDock->setObjectName(QLatin1String("qtscriptdebugger_stackDockWidget"));
550  stackDock->setWindowTitle(tr("Stack"));
551  stackDock->setWidget(widget(StackWidget));
552  win->addDockWidget(Qt::RightDockWidgetArea, stackDock);
553 
554  QDockWidget *localsDock = new QDockWidget(win);
555  localsDock->setObjectName(QLatin1String("qtscriptdebugger_localsDockWidget"));
556  localsDock->setWindowTitle(tr("Locals"));
557  localsDock->setWidget(widget(LocalsWidget));
558  win->addDockWidget(Qt::RightDockWidgetArea, localsDock);
559 
560  QDockWidget *consoleDock = new QDockWidget(win);
561  consoleDock->setObjectName(QLatin1String("qtscriptdebugger_consoleDockWidget"));
562  consoleDock->setWindowTitle(tr("Console"));
563  consoleDock->setWidget(widget(ConsoleWidget));
564  win->addDockWidget(Qt::BottomDockWidgetArea, consoleDock);
565 
566  QDockWidget *debugOutputDock = new QDockWidget(win);
567  debugOutputDock->setObjectName(QLatin1String("qtscriptdebugger_debugOutputDockWidget"));
568  debugOutputDock->setWindowTitle(tr("Debug Output"));
569  debugOutputDock->setWidget(widget(DebugOutputWidget));
570  win->addDockWidget(Qt::BottomDockWidgetArea, debugOutputDock);
571 
572  QDockWidget *errorLogDock = new QDockWidget(win);
573  errorLogDock->setObjectName(QLatin1String("qtscriptdebugger_errorLogDockWidget"));
574  errorLogDock->setWindowTitle(tr("Error Log"));
575  errorLogDock->setWidget(widget(ErrorLogWidget));
576  win->addDockWidget(Qt::BottomDockWidgetArea, errorLogDock);
577 
578  win->tabifyDockWidget(errorLogDock, debugOutputDock);
579  win->tabifyDockWidget(debugOutputDock, consoleDock);
580 
582 
583 #ifndef QT_NO_MENUBAR
584  win->menuBar()->addMenu(that->createStandardMenu(win));
585 
586  QMenu *editMenu = win->menuBar()->addMenu(tr("Search"));
587  editMenu->addAction(action(FindInScriptAction));
590  editMenu->addSeparator();
591  editMenu->addAction(action(GoToLineAction));
592 
593  QMenu *viewMenu = win->menuBar()->addMenu(tr("View"));
594  viewMenu->addAction(scriptsDock->toggleViewAction());
595  viewMenu->addAction(breakpointsDock->toggleViewAction());
596  viewMenu->addAction(stackDock->toggleViewAction());
597  viewMenu->addAction(localsDock->toggleViewAction());
598  viewMenu->addAction(consoleDock->toggleViewAction());
599  viewMenu->addAction(debugOutputDock->toggleViewAction());
600  viewMenu->addAction(errorLogDock->toggleViewAction());
601 #endif
602 
603  QWidget *central = new QWidget();
604  QVBoxLayout *vbox = new QVBoxLayout(central);
605  vbox->setMargin(0);
606  vbox->addWidget(widget(CodeWidget));
609  win->setCentralWidget(central);
610 
611  win->setWindowTitle(tr("Qt Script Debugger"));
613 
614  QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
615  QVariant geometry = settings.value(QLatin1String("Qt/scripttools/debugging/mainWindowGeometry"));
616  if (geometry.isValid())
617  win->restoreGeometry(geometry.toByteArray());
618  QVariant state = settings.value(QLatin1String("Qt/scripttools/debugging/mainWindowState"));
619  if (state.isValid())
620  win->restoreState(state.toByteArray());
621 
622  WidgetClosedNotifier *closedNotifier = new WidgetClosedNotifier(win, that);
623  QObject::connect(closedNotifier, SIGNAL(widgetClosed()),
624  action(ContinueAction), SLOT(trigger()));
625 
626  const_cast<QScriptEngineDebuggerPrivate*>(d)->standardWindow = win;
627  return win;
628 }
629 #endif // QT_NO_MAINWINDOW
630 
638 {
640  d->createDebugger();
641  return d->debugger->createStandardMenu(parent, this);
642 }
643 
650 #ifndef QT_NO_TOOLBAR
652 {
654  d->createDebugger();
655  return d->debugger->createStandardToolBar(parent, this);
656 }
657 #endif
658 
685 
686 #include "qscriptenginedebugger.moc"
687 
688 #include "moc_qscriptenginedebugger.cpp"
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
double d
Definition: qnumeric_p.h:62
QToolBar * createStandardToolBar(QWidget *parent=0)
Creates a standard debugger toolbar with the given parent.
void setValue(const QString &key, const QVariant &value)
Sets the value of setting key to value.
Definition: qsettings.cpp:3328
QScriptEngineDebuggerFrontend * frontend
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
Returns the value for setting key.
Definition: qsettings.cpp:3460
QScriptEngineDebugger(QObject *parent=0)
Constructs a new QScriptEngineDebugger object with the given parent.
DebuggerWidget
This enum decides the widget that the widget() function should retrieve.
void setCentralWidget(QWidget *widget)
Sets the given widget to be the main window&#39;s central widget.
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QPointer< QWidget > widget
DebuggerAction
This enum specifies the action that the action() function should retrieve.
The QDockWidget class provides a widget that can be docked inside a QMainWindow or floated as a top-l...
Definition: qdockwidget.h:60
static void initScriptEngineDebuggerResources()
QWidget * widget(DebuggerWidget widget) const
Returns a pointer to the instance of the specified standard widget.
The QSettings class provides persistent platform-independent application settings.
Definition: qsettings.h:73
QAction * toggleViewAction() const
Returns a checkable action that can be used to show or close this dock widget.
bool autoShowStandardWindow() const
Returns whether the standard debugger window is automatically shown when evaluation is suspended...
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
#define SLOT(a)
Definition: qobjectdefs.h:226
void setAutoShowStandardWindow(bool autoShow)
Sets whether the standard debugger window is automatically shown when evaluation is suspended...
The QScriptEngineDebugger class provides a QScriptEngine debugger.
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
static QString tr(const char *sourceText, const char *comment=0, int n=-1)
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
DebuggerState
This enum specifies the current state of the debugger.
QAction * addAction(const QString &text)
This convenience function creates a new action with text.
Definition: qmenu.cpp:1453
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
#define Q_D(Class)
Definition: qglobal.h:2482
#define Q_SIGNALS
Definition: qobjectdefs.h:72
void addWidget(QWidget *, int stretch=0, Qt::Alignment alignment=0)
Adds widget to the end of this box layout, with a stretch factor of stretch and alignment alignment...
QByteArray toByteArray() const
Returns the variant as a QByteArray if the variant has type() ByteArray or String (converted using QS...
Definition: qvariant.cpp:2383
void setObjectName(const QString &name)
Definition: qobject.cpp:1112
#define Q_Q(Class)
Definition: qglobal.h:2483
~QScriptEngineDebugger()
Destroys this QScriptEngineDebugger.
#define SIGNAL(a)
Definition: qobjectdefs.h:227
void setWindowTitle(const QString &)
Definition: qwidget.cpp:6312
The QScriptEngine class provides an environment for evaluating Qt Script code.
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
#define Q_INIT_RESOURCE(name)
Definition: qglobal.h:965
bool restoreState(const QByteArray &state, int version=0)
Restores the state of this mainwindow&#39;s toolbars and dockwidgets.
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
Definition: qobject.cpp:2580
The QToolBar class provides a movable panel that contains a set of controls.
Definition: qtoolbar.h:62
#define emit
Definition: qobjectdefs.h:76
void tabifyDockWidget(QDockWidget *first, QDockWidget *second)
Moves second dock widget on top of first dock widget, creating a tabbed docked area in the main windo...
QAction * addSeparator()
This convenience function creates a new separator action, i.e.
Definition: qmenu.cpp:1583
void setWidget(QWidget *widget)
Sets the widget for the dock widget to widget.
The QScriptEngineDebuggerFrontend class provides an in-process debugger frontend. ...
#define Q_OBJECT
Definition: qobjectdefs.h:157
void hide()
Hides the widget.
Definition: qwidget.h:501
QMenuBar * menuBar() const
Returns the menu bar for the main window.
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
Disconnects signal in object sender from method in object receiver.
Definition: qobject.cpp:2895
QAction * addMenu(QMenu *menu)
Appends menu to the menu bar.
Definition: qmenubar.cpp:937
void addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget)
Adds the given dockwidget to the specified area.
#define Q_DECLARE_PUBLIC(Class)
Definition: qglobal.h:2477
void addToolBar(Qt::ToolBarArea area, QToolBar *toolbar)
Adds the toolbar into the specified area in this main window.
The QMenu class provides a menu widget for use in menu bars, context menus, and other popup menus...
Definition: qmenu.h:72
static QCoreApplication * instance()
Returns a pointer to the application&#39;s QCoreApplication (or QApplication) instance.
QAction * action(DebuggerAction action) const
Returns a pointer to the specified action.
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
void installEventFilter(QObject *)
Installs an event filter filterObj on this object.
Definition: qobject.cpp:2070
The QMainWindow class provides a main application window.
Definition: qmainwindow.h:63
QMainWindow * standardWindow() const
Returns a main window with a standard configuration of the debugger&#39;s components. ...
The QScriptDebugger class provides a Qt Script debugger.
friend class QWidget
Definition: qobject.h:329
static QtScriptDebuggerResourceInitializer resourceInitializer
The QVBoxLayout class lines up widgets vertically.
Definition: qboxlayout.h:149
void detach()
Detaches from the current script engine, if any.
bool isValid() const
Returns true if the storage type of this variant is not QVariant::Invalid; otherwise returns false...
Definition: qvariant.h:485
void setUnifiedTitleAndToolBarOnMac(bool set)
void attachTo(QScriptEngine *engine)
Attaches to the given engine.
QMenu * createStandardMenu(QWidget *parent=0)
Creates a standard debugger menu with the given parent.
void setMargin(int)
Definition: qlayout.cpp:464
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
Type type() const
Returns the event type.
Definition: qcoreevent.h:303
bool restoreGeometry(const QByteArray &geometry)
Restores the geometry and state top-level widgets stored in the byte array geometry.
Definition: qwidget.cpp:7313
The QAction class provides an abstract user interface action that can be inserted into widgets...
Definition: qaction.h:64
void evaluationSuspended()
This signal is emitted when the debugger has suspended script evaluation for whatever reason (e...
DebuggerState state() const
Returns the current state of the debugger.