/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtSCriptTools module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qscriptdebugger_p.h"
#include "qscriptdebuggerconsole_p.h"
#include "qscriptdebuggerconsolecommandmanager_p.h"
#include "qscriptdebuggerconsolecommandjob_p.h"
#include "qscriptstdmessagehandler_p.h"
#include "qscriptdebuggerfrontend_p.h"
#include "qscriptdebuggereventhandlerinterface_p.h"
#include "qscriptdebuggerresponsehandlerinterface_p.h"
#include "qscriptdebuggerjobschedulerinterface_p.h"
#include "qscriptdebuggerconsolewidgetinterface_p.h"
#include "qscriptcompletionproviderinterface_p.h"
#include "qscriptcompletiontask_p.h"
#include "qscripttooltipproviderinterface_p.h"
#include "qscriptdebuggerstackwidgetinterface_p.h"
#include "qscriptdebuggerstackmodel_p.h"
#include "qscriptdebuggerscriptswidgetinterface_p.h"
#include "qscriptdebuggerscriptsmodel_p.h"
#include "qscriptdebuggerlocalswidgetinterface_p.h"
#include "qscriptdebuggerlocalsmodel_p.h"
#include "qscriptdebuggercodewidgetinterface_p.h"
#include "qscriptdebuggercodeviewinterface_p.h"
#include "qscriptdebuggercodefinderwidgetinterface_p.h"
#include "qscriptbreakpointswidgetinterface_p.h"
#include "qscriptbreakpointsmodel_p.h"
#include "qscriptdebugoutputwidgetinterface_p.h"
#include "qscripterrorlogwidgetinterface_p.h"
#include "qscriptdebuggerwidgetfactoryinterface_p.h"
#include "qscriptdebuggerevent_p.h"
#include "qscriptdebuggervalue_p.h"
#include "qscriptdebuggerresponse_p.h"
#include "qscriptdebuggercommand_p.h"
#include "qscriptdebuggercommandschedulerfrontend_p.h"
#include "qscriptdebuggercommandschedulerjob_p.h"
#include "qscriptdebuggerjob_p_p.h"
#include "qscriptxmlparser_p.h"

#include "private/qobject_p.h"

#include <QtScript/qscriptcontext.h>
#include <QtScript/qscriptcontextinfo.h>

#include <QtCore/qcoreapplication.h>
#include <QtCore/qdir.h>
#include <QtCore/qfileinfo.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qdebug.h>

#include <QtWidgets/qaction.h>
#include <QtGui/qevent.h>
#include <QtGui/qicon.h>
#include <QtWidgets/qinputdialog.h>
#include <QtWidgets/qmenu.h>
#include <QtWidgets/qtoolbar.h>
#include <QtWidgets/qtooltip.h>

QT_BEGIN_NAMESPACE
typedef QPair<QList<qint64>, QList<qint64> > QScriptScriptsDelta;
typedef QPair<QList<qint64>, QList<qint64> > QScriptContextsDelta;
QT_END_NAMESPACE

Q_DECLARE_METATYPE(QScriptScriptsDelta)

QT_BEGIN_NAMESPACE

Q_SCRIPT_EXPORT QString qt_scriptToXml(const QString &program, int lineNumber = 1);

namespace {

static int scriptDebuggerCount = 0;
static bool eventCallbackRegistered = false;
static bool widgetInPaintEvent = false;

static bool scriptDebuggerEventCallback(void **data)
{
    QEvent *event = reinterpret_cast<QEvent*>(data[1]);
    if (event->type() == QEvent::Paint) {
        QObject *receiver = reinterpret_cast<QObject*>(data[0]);
        bool was = widgetInPaintEvent;
        widgetInPaintEvent = true;
        QCoreApplication::instance()->notify(receiver, event);
        widgetInPaintEvent = was;
        bool *result = reinterpret_cast<bool*>(data[2]);
        *result = true;
        return true;
    }
    return false;
}

}

/*!
  \since 4.5
  \class QScriptDebugger
  \internal

  \brief The QScriptDebugger class provides a Qt Script debugger.

  \ingroup script
*/

class QScriptDebuggerPrivate
    : public QObjectPrivate,
      public QScriptDebuggerCommandSchedulerInterface,
      public QScriptDebuggerJobSchedulerInterface,
      public QScriptDebuggerEventHandlerInterface,
      public QScriptDebuggerResponseHandlerInterface,
      public QScriptCompletionProviderInterface,
      public QScriptToolTipProviderInterface
{
    Q_DECLARE_PUBLIC(QScriptDebugger)
public:
    QScriptDebuggerPrivate();
    ~QScriptDebuggerPrivate();

    int scheduleJob(QScriptDebuggerJob *job);
    void finishJob(QScriptDebuggerJob *job);
    void hibernateUntilEvaluateFinished(QScriptDebuggerJob *job);

    void maybeStartNewJob();

    int scheduleCommand(const QScriptDebuggerCommand &command,
                        QScriptDebuggerResponseHandlerInterface *responseHandler);

    void handleResponse(
        const QScriptDebuggerResponse &response, int commandId);
    bool debuggerEvent(const QScriptDebuggerEvent &event);

    QScriptCompletionTaskInterface *createCompletionTask(
        const QString &contents, int cursorPosition, int frameIndex, int options);

    void showToolTip(const QPoint &pos, int frameIndex,
                     int lineNumber, const QStringList &path);

    static QPixmap pixmap(const QString &path);

    void startInteraction(QScriptDebuggerEvent::Type type,
                          qint64 scriptId, int lineNumber);
    void sync();
    void loadLocals(int frameIndex);
    QScriptDebuggerLocalsModel *createLocalsModel();
    void selectScriptForFrame(int frameIndex);
    void emitStoppedSignal();

    void maybeDelete(QWidget *widget);

    // private slots
    void _q_onLineEntered(const QString &contents);
    void _q_onCurrentFrameChanged(int frameIndex);
    void _q_onCurrentScriptChanged(qint64 scriptId);
    void _q_onScriptLocationSelected(int lineNumber);
    void _q_interrupt();
    void _q_continue();
    void _q_stepInto();
    void _q_stepOver();
    void _q_stepOut();
    void _q_runToCursor();
    void _q_runToNewScript();
    void _q_toggleBreakpoint();
    void _q_clearDebugOutput();
    void _q_clearErrorLog();
    void _q_clearConsole();
    void _q_findInScript();
    void _q_findNextInScript();
    void _q_findPreviousInScript();
    void _q_onFindCodeRequest(const QString &, int);
    void _q_goToLine();

    void executeConsoleCommand(const QString &command);
    void findCode(const QString &exp, int options);

    QScriptDebuggerFrontend *frontend;

    bool interactive;
    QScriptDebuggerConsole *console;

    int nextJobId;
    QList<QScriptDebuggerJob*> pendingJobs;
    QList<int> pendingJobIds;
    QScriptDebuggerJob *activeJob;
    bool activeJobHibernating;
    QHash<int, QScriptDebuggerCommand> watchedCommands;
    QHash<int, QScriptDebuggerResponseHandlerInterface*> responseHandlers;

    QScriptDebuggerConsoleWidgetInterface *consoleWidget;
    QScriptDebuggerStackWidgetInterface *stackWidget;
    QScriptDebuggerStackModel *stackModel;
    QScriptDebuggerScriptsWidgetInterface *scriptsWidget;
    QScriptDebuggerScriptsModel *scriptsModel;
    QScriptDebuggerLocalsWidgetInterface *localsWidget;
    QHash<int, QScriptDebuggerLocalsModel*> localsModels;
    QScriptDebuggerCodeWidgetInterface *codeWidget;
    QScriptDebuggerCodeFinderWidgetInterface *codeFinderWidget;
    QScriptBreakpointsWidgetInterface *breakpointsWidget;
    QScriptBreakpointsModel *breakpointsModel;
    QScriptDebugOutputWidgetInterface *debugOutputWidget;
    QScriptErrorLogWidgetInterface *errorLogWidget;
    QScriptDebuggerWidgetFactoryInterface *widgetFactory;

    QAction *interruptAction;
    QAction *continueAction;
    QAction *stepIntoAction;
    QAction *stepOverAction;
    QAction *stepOutAction;
    QAction *runToCursorAction;
    QAction *runToNewScriptAction;

    QAction *toggleBreakpointAction;

    QAction *clearDebugOutputAction;
    QAction *clearErrorLogAction;
    QAction *clearConsoleAction;

    QAction *findInScriptAction;
    QAction *findNextInScriptAction;
    QAction *findPreviousInScriptAction;
    QAction *goToLineAction;

    int updatesEnabledTimerId;
};

QScriptDebuggerPrivate::QScriptDebuggerPrivate()
{
    frontend = 0;
    activeJob = 0;
    activeJobHibernating = false;
    nextJobId = 0;
    interactive = false;

    console = new QScriptDebuggerConsole();
    QString scriptsPath = QLatin1String(":/qt/scripttools/debugging/scripts/commands");
    QScriptStdMessageHandler tmp;
    console->loadScriptedCommands(scriptsPath, &tmp);

    consoleWidget = 0;
    stackWidget = 0;
    stackModel = 0;
    scriptsWidget = 0;
    scriptsModel = 0;
    localsWidget = 0;
    codeWidget = 0;
    codeFinderWidget = 0;
    breakpointsWidget = 0;
    breakpointsModel = 0;
    debugOutputWidget = 0;
    errorLogWidget = 0;
    widgetFactory = 0;

    interruptAction = 0;
    continueAction = 0;
    stepIntoAction = 0;
    stepOverAction = 0;
    stepOutAction = 0;
    runToCursorAction = 0;
    runToNewScriptAction = 0;

    toggleBreakpointAction = 0;

    clearErrorLogAction = 0;
    clearDebugOutputAction = 0;
    clearConsoleAction = 0;

    findInScriptAction = 0;
    findNextInScriptAction = 0;
    findPreviousInScriptAction = 0;
    goToLineAction = 0;

    updatesEnabledTimerId = -1;
}

QScriptDebuggerPrivate::~QScriptDebuggerPrivate()
{
    delete console;
    qDeleteAll(pendingJobs);
    delete activeJob;
    maybeDelete(consoleWidget);
    maybeDelete(stackWidget);
    maybeDelete(scriptsWidget);
    maybeDelete(localsWidget);
    maybeDelete(codeWidget);
    maybeDelete(codeFinderWidget);
    maybeDelete(breakpointsWidget);
    maybeDelete(debugOutputWidget);
    maybeDelete(errorLogWidget);
}

void QScriptDebuggerPrivate::maybeDelete(QWidget *widget)
{
    if (widget && !widget->parent())
        delete widget;
}

QPixmap QScriptDebuggerPrivate::pixmap(const QString &path)
{
    static QString prefix = QString::fromLatin1(":/qt/scripttools/debugging/images/");
    return QPixmap(prefix + path);
}

/*
  \reimp
*/
int QScriptDebuggerPrivate::scheduleJob(QScriptDebuggerJob *job)
{
    QScriptDebuggerJobPrivate *priv = QScriptDebuggerJobPrivate::get(job);
    Q_ASSERT(priv->jobScheduler == 0);
    priv->jobScheduler = this;
    int id = nextJobId;
    pendingJobs.append(job);
    pendingJobIds.append(id);
    maybeStartNewJob();
    return id;
}

/*
  \reimp
*/
void QScriptDebuggerPrivate::finishJob(QScriptDebuggerJob *job)
{
    Q_UNUSED(job);
    Q_ASSERT(activeJob == job);
    delete activeJob;
    activeJob = 0;
    activeJobHibernating = false;
    maybeStartNewJob();
}

/*
  \reimp
*/
void QScriptDebuggerPrivate::hibernateUntilEvaluateFinished(QScriptDebuggerJob *job)
{
    Q_UNUSED(job);
    Q_ASSERT(activeJob == job);
    activeJobHibernating = true;
}

/*
  Starts a new job if appropriate.
*/
void QScriptDebuggerPrivate::maybeStartNewJob()
{
    if (activeJob || pendingJobs.isEmpty())
        return;
    activeJob = pendingJobs.takeFirst();
    activeJob->start();
}

/*
  \reimp
*/
int QScriptDebuggerPrivate::scheduleCommand(
    const QScriptDebuggerCommand &command,
    QScriptDebuggerResponseHandlerInterface *responseHandler)
{
    if (!frontend)
        return -1;
    int id = frontend->scheduleCommand(command, this);
    if (responseHandler && (responseHandler != this))
        responseHandlers.insert(id, responseHandler);
    if ((command.type() == QScriptDebuggerCommand::SetBreakpoint)
        || (command.type() == QScriptDebuggerCommand::SetBreakpointData)
        || (command.type() == QScriptDebuggerCommand::DeleteBreakpoint)) {
        // need to watch this command and update the breakpoints model afterwards
        watchedCommands.insert(id, command);
    }
    return id;
}

/*
  \reimp
*/
void QScriptDebuggerPrivate::handleResponse(
    const QScriptDebuggerResponse &response, int commandId)
{
    Q_Q(QScriptDebugger);
    if (watchedCommands.contains(commandId)) {
        QScriptDebuggerCommand command = watchedCommands.take(commandId);
        if (response.error() == QScriptDebuggerResponse::NoError) {
            if (!breakpointsModel)
                breakpointsModel = new QScriptBreakpointsModel(this, this, q);
            switch (command.type()) {
            case QScriptDebuggerCommand::SetBreakpoint: {
                int breakpointId = response.resultAsInt();
                QScriptBreakpointData data = command.breakpointData();
                breakpointsModel->addBreakpoint(breakpointId, data);
            }   break;
            case QScriptDebuggerCommand::SetBreakpointData: {
                int breakpointId = command.breakpointId();
                QScriptBreakpointData data = command.breakpointData();
                breakpointsModel->modifyBreakpoint(breakpointId, data);
            }   break;
            case QScriptDebuggerCommand::DeleteBreakpoint: {
                int breakpointId = command.breakpointId();
                breakpointsModel->removeBreakpoint(breakpointId);
            }   break;
            default:
                Q_ASSERT(false);
            }
        }
    } else if (response.async()) {
        interactive = false;
        // disable/invalidate/enable stuff
        if (continueAction)
            continueAction->setEnabled(false);
        if (stepIntoAction)
            stepIntoAction->setEnabled(false);
        if (stepOverAction)
            stepOverAction->setEnabled(false);
        if (stepOutAction)
            stepOutAction->setEnabled(false);
        if (runToCursorAction)
            runToCursorAction->setEnabled(false);
        if (runToNewScriptAction)
            runToNewScriptAction->setEnabled(false);
        if (interruptAction)
            interruptAction->setEnabled(true);

        // the timer is to avoid flicker when stepping
        if (stackWidget) {
            stackWidget->setUpdatesEnabled(false);
            stackWidget->setEnabled(false);
            if (updatesEnabledTimerId == -1)
                updatesEnabledTimerId = q->startTimer(75);
        }
        if (localsWidget) {
            localsWidget->setUpdatesEnabled(false);
            localsWidget->setEnabled(false);
            if (updatesEnabledTimerId == -1)
                updatesEnabledTimerId = q->startTimer(75);
        }
        if (codeWidget)
            codeWidget->invalidateExecutionLineNumbers();

        emit q->started();
    }

    QScriptDebuggerResponseHandlerInterface *realHandler = responseHandlers.take(commandId);
    if (realHandler)
        realHandler->handleResponse(response, commandId);
}

/*
  \reimp

  Handles a debugger event from the frontend.
*/
bool QScriptDebuggerPrivate::debuggerEvent(const QScriptDebuggerEvent &event)
{
    Q_Q(QScriptDebugger);
    switch (event.type()) {
    case QScriptDebuggerEvent::None:
    case QScriptDebuggerEvent::UserEvent:
    case QScriptDebuggerEvent::MaxUserEvent:
        Q_ASSERT(false);
        break;

    case QScriptDebuggerEvent::Trace:
        if (!debugOutputWidget && widgetFactory)
            q->setDebugOutputWidget(widgetFactory->createDebugOutputWidget());
        if (debugOutputWidget)
            debugOutputWidget->message(QtDebugMsg, event.message());
        return true; // trace doesn't stall execution

    case QScriptDebuggerEvent::SteppingFinished: {
        if (!consoleWidget && widgetFactory)
            q->setConsoleWidget(widgetFactory->createConsoleWidget());
        if (consoleWidget) {
            QString msg = event.message();
            if (!msg.isEmpty())
                consoleWidget->message(QtDebugMsg, msg);
        }
    }   break;

    case QScriptDebuggerEvent::Interrupted:
    case QScriptDebuggerEvent::LocationReached:
        break;

    case QScriptDebuggerEvent::Breakpoint: {
        int bpId = event.breakpointId();
        if (!consoleWidget && widgetFactory)
            q->setConsoleWidget(widgetFactory->createConsoleWidget());
        if (consoleWidget) {
            consoleWidget->message(QtDebugMsg,
                                   QString::fromLatin1("Breakpoint %0 at %1, line %2.")
                                   .arg(bpId).arg(event.fileName())
                                   .arg(event.lineNumber()));
        }
        if (breakpointsModel->breakpointData(bpId).isSingleShot())
            breakpointsModel->removeBreakpoint(bpId);
    }   break;

    case QScriptDebuggerEvent::Exception: {
        if (event.hasExceptionHandler()) {
            // Let the exception be handled like normal.
            // We may want to add a "Break on all exceptions" option
            // to be able to customize this behavior.
            return true;
        }
        if (!consoleWidget && widgetFactory)
            q->setConsoleWidget(widgetFactory->createConsoleWidget());
        if (!errorLogWidget && widgetFactory)
            q->setErrorLogWidget(widgetFactory->createErrorLogWidget());
        if (consoleWidget || errorLogWidget) {
            QString fn = event.fileName();
            if (fn.isEmpty()) {
                if (event.scriptId() != -1)
                    fn = QString::fromLatin1("<anonymous script, id=%0>").arg(event.scriptId());
                else
                    fn = QString::fromLatin1("<native>");
            }
            QString msg = QString::fromLatin1("Uncaught exception at %0:%1: %2").arg(fn)
                          .arg(event.lineNumber()).arg(event.message());
            if (consoleWidget)
                consoleWidget->message(QtCriticalMsg, msg);
            if (errorLogWidget)
                errorLogWidget->message(QtCriticalMsg, msg);
        }
    }   break;

    case QScriptDebuggerEvent::InlineEvalFinished: {
        QScriptDebuggerValue result = event.scriptValue();
        Q_ASSERT(console != 0);
        int action = console->evaluateAction();
        console->setEvaluateAction(0);
        switch (action) {
        case 0: { // eval command
            if (activeJob) {
                if (activeJobHibernating) {
                    activeJobHibernating = false;
                    activeJob->evaluateFinished(result);
                }
            } else if (consoleWidget) {
                // ### if the result is an object, need to do a tostring job on it
//          messageHandler->message(QtDebugMsg, result.toString());
                if (result.type() != QScriptDebuggerValue::UndefinedValue)
                    consoleWidget->message(QtDebugMsg, event.message());
            }
        }   break;
        case 1: { // return command
            QScriptDebuggerCommandSchedulerFrontend frontend(this, this);
            frontend.scheduleForceReturn(console->currentFrameIndex(), result);
        }   return false;
        }
        if (!event.isNestedEvaluate()) {
            // in the case when evaluate() was called while the
            // engine was not running, we don't want to enter interactive mode
            return true;
        }
    }   break;

    case QScriptDebuggerEvent::DebuggerInvocationRequest: {
        if (!consoleWidget && widgetFactory)
            q->setConsoleWidget(widgetFactory->createConsoleWidget());
        if (consoleWidget) {
            QString fn = event.fileName();
            if (fn.isEmpty())
                fn = QString::fromLatin1("<anonymous script, id=%0>").arg(event.scriptId());
            consoleWidget->message(QtDebugMsg,
                                   QString::fromLatin1("Debugger invoked from %1, line %2.")
                                   .arg(fn).arg(event.lineNumber()));
        }
    }   break;

    case QScriptDebuggerEvent::ForcedReturn: {
    }   break;

    }

    if (widgetInPaintEvent) {
        QString msg = QString::fromLatin1("Suspending evaluation in paintEvent() is not supported; resuming.");
        if (!consoleWidget && widgetFactory)
            q->setConsoleWidget(widgetFactory->createConsoleWidget());
        if (!errorLogWidget && widgetFactory)
            q->setErrorLogWidget(widgetFactory->createErrorLogWidget());
        if (consoleWidget)
            consoleWidget->message(QtWarningMsg, msg);
        if (errorLogWidget)
            errorLogWidget->message(QtCriticalMsg, msg);
        return true;
    }

    if (activeJobHibernating) {
        // evaluate() did not finish normally (e.g. due to a breakpoint),
        // so cancel the job that's waiting for it
        delete activeJob;
        activeJob = 0;
        activeJobHibernating = false;
    }

    startInteraction(event.type(), event.scriptId(), event.lineNumber());
    return !interactive;
}

class QScriptToolTipJob : public QScriptDebuggerCommandSchedulerJob
{
public:
    QScriptToolTipJob(const QPoint &pos, int frameIndex,
                      int lineNumber, const QStringList &path,
                      QScriptDebuggerCommandSchedulerInterface *scheduler)
        : QScriptDebuggerCommandSchedulerJob(scheduler), m_pos(pos),
          m_frameIndex(frameIndex), m_lineNumber(lineNumber), m_path(path)
        {}

    void start()
    {
        QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this);
        frontend.scheduleGetPropertyExpressionValue(m_frameIndex, m_lineNumber, m_path);
    }
    void handleResponse(const QScriptDebuggerResponse &response, int /*commandId*/)
    {
        QString tip = response.result().toString();
        if (tip.indexOf(QLatin1Char('\n')) != -1) {
            QStringList lines = tip.split(QLatin1Char('\n'));
            int lineCount = lines.size();
            if (lineCount > 5) {
                lines = lines.mid(0, 5);
                lines.append(QString::fromLatin1("(... %0 more lines ...)").arg(lineCount - 5));
            }
            tip = lines.join(QLatin1String("\n"));
        }
#if QT_CONFIG(tooltip)
        QToolTip::showText(m_pos, tip);
#endif
        finish();
    }

private:
    QPoint m_pos;
    int m_frameIndex;
    int m_lineNumber;
    QStringList m_path;
};

/*
  \reimp
*/
void QScriptDebuggerPrivate::showToolTip(const QPoint &pos, int frameIndex,
                                         int lineNumber, const QStringList &path)
{
    if (frameIndex == -1) {
        if (stackWidget)
            frameIndex = stackWidget->currentFrameIndex();
        else
            frameIndex = console->currentFrameIndex();
    }
    QScriptDebuggerJob *job = new QScriptToolTipJob(pos, frameIndex, lineNumber, path, this);
    scheduleJob(job);
}

/*
  \reimp
*/
QScriptCompletionTaskInterface *QScriptDebuggerPrivate::createCompletionTask(
    const QString &contents, int cursorPosition, int frameIndex, int options)
{
    return new QScriptCompletionTask(
        contents, cursorPosition, frameIndex, this, this,
        (options & QScriptCompletionProviderInterface::ConsoleCommandCompletion) ? console : 0);
}

/*
  Slot called when a line has been entered in the console widget.
*/
void QScriptDebuggerPrivate::_q_onLineEntered(const QString &contents)
{
    QScriptDebuggerConsoleCommandJob *commandJob;
    commandJob = console->consumeInput(contents, consoleWidget, this);
    if (commandJob != 0) {
        scheduleJob(commandJob);
        consoleWidget->setLineContinuationMode(false);
    } else if (console->hasIncompleteInput()) {
        consoleWidget->setLineContinuationMode(true);
    }
}

/*
  Slot called when the current index has changed in the stack widget.
*/
void QScriptDebuggerPrivate::_q_onCurrentFrameChanged(int frameIndex)
{
    loadLocals(frameIndex);
    selectScriptForFrame(frameIndex);
}

/*
  Slot called when the current script has changed in the scripts widget.
*/
void QScriptDebuggerPrivate::_q_onCurrentScriptChanged(qint64 scriptId)
{
    if (codeWidget && (codeWidget->currentScriptId() != scriptId)) {
        codeWidget->setCurrentScript(scriptId);
        QScriptDebuggerCodeViewInterface *view = codeWidget->currentView();
        if (view)
            view->setExecutionLineNumber(-1, /*error=*/false);
    }
}

void QScriptDebuggerPrivate::_q_onScriptLocationSelected(int lineNumber)
{
    QScriptDebuggerCodeViewInterface *view = codeWidget->currentView();
    if (!view)
        return;
    view->gotoLine(lineNumber);
}

void QScriptDebuggerPrivate::_q_interrupt()
{
    executeConsoleCommand(QString::fromLatin1("interrupt"));
}

void QScriptDebuggerPrivate::_q_continue()
{
    executeConsoleCommand(QString::fromLatin1("continue"));
}

void QScriptDebuggerPrivate::_q_stepInto()
{
    executeConsoleCommand(QString::fromLatin1("step"));
}

void QScriptDebuggerPrivate::_q_stepOver()
{
    executeConsoleCommand(QString::fromLatin1("next"));
}

void QScriptDebuggerPrivate::_q_stepOut()
{
    executeConsoleCommand(QString::fromLatin1("finish"));
}

void QScriptDebuggerPrivate::_q_runToCursor()
{
    qint64 scriptId = codeWidget->currentScriptId();
    int lineNumber = codeWidget->currentView()->cursorLineNumber();
    QScriptDebuggerCommandSchedulerFrontend frontend(this, this);
    frontend.scheduleRunToLocation(scriptId, lineNumber);
}

void QScriptDebuggerPrivate::_q_runToNewScript()
{
    QScriptDebuggerCommandSchedulerFrontend frontend(this, this);
    frontend.scheduleRunToLocation(QString(), -1);
}

void QScriptDebuggerPrivate::_q_toggleBreakpoint()
{
    Q_ASSERT(codeWidget != 0);
    QScriptDebuggerCodeViewInterface *view = codeWidget->currentView();
    if (!view)
        return;
    qint64 scriptId = codeWidget->currentScriptId();
    int lineNumber = view->cursorLineNumber();
    Q_ASSERT(breakpointsModel != 0);
    int bpId = breakpointsModel->resolveBreakpoint(scriptId, lineNumber);
    if (bpId != -1) {
        breakpointsModel->deleteBreakpoint(bpId);
    } else {
        QScriptBreakpointData data(scriptId, lineNumber);
        if (scriptsModel)
            data.setFileName(scriptsModel->scriptData(scriptId).fileName());
        breakpointsModel->setBreakpoint(data);
    }
}

void QScriptDebuggerPrivate::_q_clearDebugOutput()
{
    if (debugOutputWidget)
        debugOutputWidget->clear();
}

void QScriptDebuggerPrivate::_q_clearErrorLog()
{
    if (errorLogWidget)
        errorLogWidget->clear();
}

void QScriptDebuggerPrivate::_q_clearConsole()
{
    if (consoleWidget)
        consoleWidget->clear();
}

void QScriptDebuggerPrivate::executeConsoleCommand(const QString &command)
{
    QString tmp = console->incompleteInput();
    console->setIncompleteInput(QString());
    QScriptDebuggerJob *job = console->consumeInput(console->commandPrefix() + command, debugOutputWidget, this);
    console->setIncompleteInput(tmp);
    if (job != 0) {
        scheduleJob(job);
        // once to send the command...
        QCoreApplication::processEvents();
        // ... and once to receive the response
        QCoreApplication::processEvents();
    }
}

void QScriptDebuggerPrivate::_q_findInScript()
{
    if (!codeFinderWidget && widgetFactory)
        q_func()->setCodeFinderWidget(widgetFactory->createCodeFinderWidget());
    if (codeFinderWidget) {
        codeFinderWidget->show();
        codeFinderWidget->setFocus(Qt::OtherFocusReason);
    }
}

void QScriptDebuggerPrivate::_q_findNextInScript()
{
    findCode(codeFinderWidget->text(), codeFinderWidget->findOptions());
}

void QScriptDebuggerPrivate::_q_findPreviousInScript()
{
    int options = codeFinderWidget->findOptions();
    options |= QTextDocument::FindBackward;
    findCode(codeFinderWidget->text(), options);
}

void QScriptDebuggerPrivate::_q_onFindCodeRequest(
    const QString &exp, int options)
{
    findCode(exp, options);
    if (findNextInScriptAction)
        findNextInScriptAction->setEnabled(!exp.isEmpty());
    if (findPreviousInScriptAction)
        findPreviousInScriptAction->setEnabled(!exp.isEmpty());
}

void QScriptDebuggerPrivate::findCode(const QString &exp, int options)
{
    QScriptDebuggerCodeViewInterface *view = codeWidget->currentView();
    if (!view)
        return;
    int result = view->find(exp, options);
    codeFinderWidget->setOK(((result & 0x1) != 0) || exp.isEmpty());
    codeFinderWidget->setWrapped((result & 0x2) != 0);
}

void QScriptDebuggerPrivate::_q_goToLine()
{
    QScriptDebuggerCodeViewInterface *view = codeWidget->currentView();
    if (!view)
        return;
#ifndef QT_NO_INPUTDIALOG
    bool ok = false;
    int lineNumber = QInputDialog::getInt(0, QScriptDebugger::tr("Go to Line"),
                                          QScriptDebugger::tr("Line:"),
                                          view->cursorLineNumber(),
                                          1, INT_MAX, 1, &ok);
    if (ok)
        view->gotoLine(lineNumber);
#endif
}

class QScriptDebuggerShowLineJob : public QScriptDebuggerCommandSchedulerJob
{
public:
    QScriptDebuggerShowLineJob(qint64 scriptId, int lineNumber,
                               QScriptMessageHandlerInterface *messageHandler,
                               QScriptDebuggerCommandSchedulerInterface *scheduler)
        : QScriptDebuggerCommandSchedulerJob(scheduler),
          m_scriptId(scriptId), m_lineNumber(lineNumber),
        m_messageHandler(messageHandler) {}

    void start()
    {
        QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this);
        frontend.scheduleGetScriptData(m_scriptId);
    }
    void handleResponse(const QScriptDebuggerResponse &response, int /*commandId*/)
    {
        QScriptScriptData data = response.resultAsScriptData();
        QString line = data.lines(m_lineNumber, 1).value(0);
        m_messageHandler->message(QtDebugMsg, QString::fromLatin1("%0\t%1")
                                  .arg(m_lineNumber).arg(line));
        finish();
    }

private:
    qint64 m_scriptId;
    int m_lineNumber;
    QScriptMessageHandlerInterface *m_messageHandler;
};

namespace {

class SyncStackJob : public QScriptDebuggerCommandSchedulerJob
{
public:
    SyncStackJob(QScriptDebuggerPrivate *debugger)
        : QScriptDebuggerCommandSchedulerJob(debugger),
          m_debugger(debugger), m_index(0) {}
    void start()
    {
        QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this);
        frontend.scheduleGetContextInfo(m_index); // ### getContextInfos()
    }
    void handleResponse(const QScriptDebuggerResponse &response,
                        int)
    {
        QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this);
        if (response.error() != QScriptDebuggerResponse::InvalidContextIndex) {
            m_infos.append(response.resultAsContextInfo());
            frontend.scheduleGetContextInfo(++m_index);
        } else {
            m_debugger->stackModel->setContextInfos(m_infos);
            if (m_debugger->stackWidget->currentFrameIndex() == -1)
                m_debugger->stackWidget->setCurrentFrameIndex(0);
            m_debugger->stackWidget->setUpdatesEnabled(true);
            m_debugger->stackWidget->setEnabled(true);
            finish();
        }
    }

private:
    QScriptDebuggerPrivate *m_debugger;
    int m_index;
    QList<QScriptContextInfo> m_infos;
};

class SyncScriptsJob : public QScriptDebuggerCommandSchedulerJob
{
public:
    SyncScriptsJob(QScriptDebuggerPrivate *debugger)
        : QScriptDebuggerCommandSchedulerJob(debugger),
          m_debugger(debugger), m_index(-1) {}

    void start()
    {
        QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this);
        frontend.scheduleScriptsCheckpoint();
    }
    void handleResponse(const QScriptDebuggerResponse &response,
                        int)
    {
        QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this);
        if (m_index == -1) {
            QScriptScriptsDelta delta;
            delta = qvariant_cast<QScriptScriptsDelta>(response.result());

            const QList<qint64> &removed = delta.second;
            for (int i = 0; i < removed.size(); ++i)
                m_debugger->scriptsModel->removeScript(removed.at(i));

            m_added = delta.first;
            if (!m_added.isEmpty()) {
                frontend.scheduleGetScriptData(m_added.at(++m_index));
            } else {
                m_debugger->scriptsModel->commit();
                finish();
            }
        } else {
            QScriptScriptData data = response.resultAsScriptData();
            qint64 scriptId = m_added.at(m_index);
            m_debugger->scriptsModel->addScript(scriptId, data);

            // ### could be slow, might want to do this in a separate thread
//            Q_ASSERT_X(false, Q_FUNC_INFO, "implement me");
            QString xml; // = qt_scriptToXml(data.contents(), data.baseLineNumber());
            QScriptXmlParser::Result extraInfo = QScriptXmlParser::parse(xml);
            m_debugger->scriptsModel->addExtraScriptInfo(
                scriptId, extraInfo.functionsInfo, extraInfo.executableLineNumbers);

            if (++m_index < m_added.size())
                frontend.scheduleGetScriptData(m_added.at(m_index));
            else {
                m_debugger->scriptsModel->commit();
                finish();
            }
        }
    }

private:
    QScriptDebuggerPrivate *m_debugger;
    int m_index;
    QList<qint64> m_added;
};

class SyncBreakpointsJob : public QScriptDebuggerCommandSchedulerJob
{
public:
    SyncBreakpointsJob(QScriptDebuggerPrivate *debugger)
        : QScriptDebuggerCommandSchedulerJob(debugger),
          m_debugger(debugger) {}
    void start()
    {
        QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this);
        frontend.scheduleGetBreakpoints();
    }
    void handleResponse(const QScriptDebuggerResponse &response,
                        int)
    {
        QScriptBreakpointMap breakpoints = response.resultAsBreakpoints();
        QScriptBreakpointMap::const_iterator it;
        for (it = breakpoints.constBegin(); it != breakpoints.constEnd(); ++it) {
            int id = it.key();
            QScriptBreakpointData newData = it.value();
            QScriptBreakpointData existingData = m_debugger->breakpointsModel->breakpointData(id);
            if (existingData.isValid() && (existingData != newData))
                m_debugger->breakpointsModel->modifyBreakpoint(id, newData);
        }
        finish();
    }

private:
    QScriptDebuggerPrivate *m_debugger;
    QList<QScriptContextInfo> m_infos;
};

class SyncLocalsJob : public QScriptDebuggerCommandSchedulerJob
{
public:
    SyncLocalsJob(QScriptDebuggerPrivate *debugger)
        : QScriptDebuggerCommandSchedulerJob(debugger),
          m_debugger(debugger) {}

    void start()
    {
        QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this);
        frontend.scheduleContextsCheckpoint();
    }
    void handleResponse(const QScriptDebuggerResponse &response,
                        int)
    {
        QScriptContextsDelta delta = qvariant_cast<QScriptContextsDelta>(response.result());
        for (int i = 0; i < delta.first.size(); ++i) {
            QScriptDebuggerLocalsModel *model = m_debugger->localsModels.take(delta.first.at(i));
            delete model;
        }
        finish();
    }

private:
    QScriptDebuggerPrivate *m_debugger;
};

class LoadLocalsJob : public QScriptDebuggerCommandSchedulerJob
{
public:
    LoadLocalsJob(QScriptDebuggerPrivate *debugger, int frameIndex)
        : QScriptDebuggerCommandSchedulerJob(debugger),
          m_debugger(debugger), m_frameIndex(frameIndex) {}

    void start()
    {
        QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this);
        frontend.scheduleGetContextId(m_frameIndex);
    }
    void handleResponse(const QScriptDebuggerResponse &response,
                        int)
    {
        QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this);
        qint64 contextId = response.resultAsLongLong();
        QScriptDebuggerLocalsModel *model = m_debugger->localsModels.value(contextId);
        if (model) {
            model->sync(m_frameIndex);
        } else {
            model = m_debugger->createLocalsModel();
            m_debugger->localsModels.insert(contextId, model);
            model->init(m_frameIndex);
        }
        if (m_debugger->localsWidget) {
            if (m_debugger->localsWidget->localsModel() != model) // ### bug in qtreeview
                m_debugger->localsWidget->setLocalsModel(model);
            m_debugger->localsWidget->setUpdatesEnabled(true);
            m_debugger->localsWidget->setEnabled(true);
        }
        finish();
    }

private:
    QScriptDebuggerPrivate *m_debugger;
    int m_frameIndex;
};

class EmitStoppedSignalJob : public QScriptDebuggerJob
{
public:
    EmitStoppedSignalJob(QScriptDebuggerPrivate *debugger)
        : m_debugger(debugger) {}

    void start()
    {
        m_debugger->emitStoppedSignal();
        finish();
    }

private:
    QScriptDebuggerPrivate *m_debugger;
};

} // namespace

void QScriptDebuggerPrivate::startInteraction(QScriptDebuggerEvent::Type type,
                                              qint64 scriptId, int lineNumber)
{
    Q_Q(QScriptDebugger);
    if (type != QScriptDebuggerEvent::InlineEvalFinished) {
        if (stackWidget)
            stackWidget->setCurrentFrameIndex(0);
        console->setCurrentFrameIndex(0);
        console->setCurrentScriptId(scriptId);
        console->setCurrentLineNumber(lineNumber);
    }

    if ((scriptId != -1) && consoleWidget) {
        QScriptDebuggerJob *job = new QScriptDebuggerShowLineJob(scriptId, lineNumber, consoleWidget, this);
        scheduleJob(job);
    }

    sync();

    if (!interactive) {
        interactive = true;
        if (updatesEnabledTimerId != -1) {
            q->killTimer(updatesEnabledTimerId);
            updatesEnabledTimerId = -1;
        }
        console->bumpSessionId();
        scheduleJob(new EmitStoppedSignalJob(this));
    }

    if (consoleWidget)
        consoleWidget->activateWindow();
    else if (codeWidget)
        codeWidget->activateWindow();

    if (continueAction)
        continueAction->setEnabled(true);
    if (stepIntoAction)
        stepIntoAction->setEnabled(true);
    if (stepOverAction)
        stepOverAction->setEnabled(true);
    if (stepOutAction)
        stepOutAction->setEnabled(true);
    if (runToCursorAction)
        runToCursorAction->setEnabled(true);
    if (runToNewScriptAction)
        runToNewScriptAction->setEnabled(true);
    if (interruptAction)
        interruptAction->setEnabled(false);

    bool hasScript = (codeWidget != 0);
    if (findInScriptAction)
        findInScriptAction->setEnabled(hasScript);
    if (toggleBreakpointAction)
        toggleBreakpointAction->setEnabled(hasScript);
    if (goToLineAction)
        goToLineAction->setEnabled(hasScript);
}

void QScriptDebuggerPrivate::sync()
{
    if (localsWidget) {
        QScriptDebuggerJob *job = new SyncLocalsJob(this);
        scheduleJob(job);
    }
    if (scriptsModel) {
        QScriptDebuggerJob *job = new SyncScriptsJob(this);
        scheduleJob(job);
    }
    if (stackModel) {
        QScriptDebuggerJob *job = new SyncStackJob(this);
        scheduleJob(job);
    }
    if (breakpointsModel) {
        // need to sync because the ignore-count could have changed
        QScriptDebuggerJob *job = new SyncBreakpointsJob(this);
        scheduleJob(job);
    }

    if (stackWidget && (stackWidget->currentFrameIndex() != -1)) {
        int index = stackWidget->currentFrameIndex();
        loadLocals(index);
        selectScriptForFrame(index);
    } else if (codeWidget && (console->currentFrameIndex() != -1)) {
        selectScriptForFrame(console->currentFrameIndex());
    }
}

void QScriptDebuggerPrivate::loadLocals(int frameIndex)
{
    LoadLocalsJob *job = new LoadLocalsJob(this, frameIndex);
    scheduleJob(job);
}

QScriptDebuggerLocalsModel *QScriptDebuggerPrivate::createLocalsModel()
{
    return new QScriptDebuggerLocalsModel(this, this, q_func());
}

namespace {

class ShowFrameCodeJob : public QScriptDebuggerCommandSchedulerJob
{
public:
    ShowFrameCodeJob(QScriptDebuggerPrivate *debugger, int frameIndex)
        : QScriptDebuggerCommandSchedulerJob(debugger),
          m_debugger(debugger), m_frameIndex(frameIndex) {}

    void start()
    {
        QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this);
        frontend.scheduleGetContextInfo(m_frameIndex);
    }
    void handleResponse(const QScriptDebuggerResponse &response,
                        int)
    {
        if (m_info.isNull()) {
            m_info = response.resultAsContextInfo();
            QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this);
            frontend.scheduleGetContextState(m_frameIndex);
        } else {
            int contextState = response.resultAsInt();
            bool error = (contextState == QScriptContext::ExceptionState);
            if (m_debugger->scriptsWidget) {
                m_debugger->scriptsWidget->setCurrentScript(m_info.scriptId());
            }
            if (m_debugger->codeWidget) {
                m_debugger->codeWidget->setCurrentScript(m_info.scriptId());
                QScriptDebuggerCodeViewInterface *view = m_debugger->codeWidget->currentView();
                if (view)
                    view->setExecutionLineNumber(m_info.lineNumber(), error);
            }
            finish();
        }
    }

private:
    QScriptDebuggerPrivate *m_debugger;
    int m_frameIndex;
    QScriptContextInfo m_info;
};

} // namespace

void QScriptDebuggerPrivate::selectScriptForFrame(int frameIndex)
{
    QScriptDebuggerJob *job = new ShowFrameCodeJob(this, frameIndex);
    scheduleJob(job);
}

void QScriptDebuggerPrivate::emitStoppedSignal()
{
    emit q_func()->stopped();
}

/*!
  Constructs a new QScriptDebugger object.
*/
QScriptDebugger::QScriptDebugger(QObject *parent)
    : QObject(*new QScriptDebuggerPrivate, parent)
{
    ++scriptDebuggerCount;
}

/*!
  Destroys this QScriptDebugger.
*/
QScriptDebugger::~QScriptDebugger()
{
    --scriptDebuggerCount;
    if ((scriptDebuggerCount == 0) && eventCallbackRegistered) {
        eventCallbackRegistered = false;
        QInternal::unregisterCallback(QInternal::EventNotifyCallback,
                                      scriptDebuggerEventCallback);
    }
}

/*!
  \internal
*/
QScriptDebugger::QScriptDebugger(QScriptDebuggerPrivate &dd, QObject *parent)
    : QObject(dd, parent)
{
}

QScriptDebuggerFrontend *QScriptDebugger::frontend() const
{
    Q_D(const QScriptDebugger);
    return d->frontend;
}

void QScriptDebugger::setFrontend(QScriptDebuggerFrontend *frontend)
{
    Q_D(QScriptDebugger);
    if (d->frontend)
        d->frontend->setEventHandler(0);
    d->frontend = frontend;
    if (frontend) {
        frontend->setEventHandler(d);
        if (!eventCallbackRegistered) {
            eventCallbackRegistered = true;
            QInternal::registerCallback(QInternal::EventNotifyCallback,
                                        scriptDebuggerEventCallback);
        }
    }
}

QAction *QScriptDebugger::action(DebuggerAction action, QObject *parent)
{
    switch (action) {
    case InterruptAction:
        return interruptAction(parent);
    case ContinueAction:
        return continueAction(parent);
    case StepIntoAction:
        return stepIntoAction(parent);
    case StepOverAction:
        return stepOverAction(parent);
    case StepOutAction:
        return stepOutAction(parent);
    case RunToCursorAction:
        return runToCursorAction(parent);
    case RunToNewScriptAction:
        return runToNewScriptAction(parent);
    case ToggleBreakpointAction:
        return toggleBreakpointAction(parent);
    case ClearDebugOutputAction:
        return clearDebugOutputAction(parent);
    case ClearErrorLogAction:
        return clearErrorLogAction(parent);
    case ClearConsoleAction:
        return clearConsoleAction(parent);
    case FindInScriptAction:
        return findInScriptAction(parent);
    case FindNextInScriptAction:
        return findNextInScriptAction(parent);
    case FindPreviousInScriptAction:
        return findPreviousInScriptAction(parent);
    case GoToLineAction:
        return goToLineAction(parent);
    }
    return 0;
}

QWidget *QScriptDebugger::widget(DebuggerWidget widget)
{
    switch (widget) {
    case ConsoleWidget: {
        QScriptDebuggerConsoleWidgetInterface *w = consoleWidget();
        if (!w && widgetFactory()) {
            w = widgetFactory()->createConsoleWidget();
            setConsoleWidget(w);
        }
        return w;
    }
    case StackWidget: {
        QScriptDebuggerStackWidgetInterface *w = stackWidget();
        if (!w && widgetFactory()) {
            w = widgetFactory()->createStackWidget();
            setStackWidget(w);
        }
        return w;
    }
    case ScriptsWidget: {
        QScriptDebuggerScriptsWidgetInterface *w = scriptsWidget();
        if (!w && widgetFactory()) {
            w = widgetFactory()->createScriptsWidget();
            setScriptsWidget(w);
        }
        return w;
    }
    case LocalsWidget: {
        QScriptDebuggerLocalsWidgetInterface *w = localsWidget();
        if (!w && widgetFactory()) {
            w = widgetFactory()->createLocalsWidget();
            setLocalsWidget(w);
        }
        return w;
    }
    case CodeWidget: {
        QScriptDebuggerCodeWidgetInterface *w = codeWidget();
        if (!w && widgetFactory()) {
            w = widgetFactory()->createCodeWidget();
            setCodeWidget(w);
        }
        return w;
    }
    case CodeFinderWidget: {
        QScriptDebuggerCodeFinderWidgetInterface *w = codeFinderWidget();
        if (!w && widgetFactory()) {
            w = widgetFactory()->createCodeFinderWidget();
            setCodeFinderWidget(w);
        }
        return w;
    }
    case BreakpointsWidget: {
        QScriptBreakpointsWidgetInterface *w = breakpointsWidget();
        if (!w && widgetFactory()) {
            w = widgetFactory()->createBreakpointsWidget();
            setBreakpointsWidget(w);
        }
        return w;
    }
    case DebugOutputWidget: {
        QScriptDebugOutputWidgetInterface *w = debugOutputWidget();
        if (!w && widgetFactory()) {
            w = widgetFactory()->createDebugOutputWidget();
            setDebugOutputWidget(w);
        }
        return w;
    }
    case ErrorLogWidget: {
        QScriptErrorLogWidgetInterface *w = errorLogWidget();
        if (!w && widgetFactory()) {
            w = widgetFactory()->createErrorLogWidget();
            setErrorLogWidget(w);
        }
        return w;
    }
    }
    return 0;
}

QScriptDebuggerConsoleWidgetInterface *QScriptDebugger::consoleWidget() const
{
    Q_D(const QScriptDebugger);
    return d->consoleWidget;
}

void QScriptDebugger::setConsoleWidget(QScriptDebuggerConsoleWidgetInterface *consoleWidget)
{
    Q_D(QScriptDebugger);
    if (d->consoleWidget) {
        QObject::disconnect(d->consoleWidget, 0, this, 0);
    }
    d->consoleWidget = consoleWidget;
    if (consoleWidget) {
        consoleWidget->setCommandHistorian(d->console);
        consoleWidget->setCompletionProvider(d);
        QObject::connect(consoleWidget, SIGNAL(lineEntered(QString)),
                         this, SLOT(_q_onLineEntered(QString)));

        d->console->showDebuggerInfoMessage(consoleWidget);
    }
}

QScriptDebuggerStackWidgetInterface *QScriptDebugger::stackWidget() const
{
    Q_D(const QScriptDebugger);
    return d->stackWidget;
}

void QScriptDebugger::setStackWidget(QScriptDebuggerStackWidgetInterface *stackWidget)
{
    Q_D(QScriptDebugger);
    if (d->stackWidget) {
        QObject::disconnect(d->stackWidget, 0, this, 0);
    }
    d->stackWidget = stackWidget;
    if (stackWidget) {
        if (!d->stackModel) {
            d->stackModel = new QScriptDebuggerStackModel(this);
            if (d->interactive)
                d->scheduleJob(new SyncStackJob(d));
        }
        stackWidget->setStackModel(d->stackModel);
        QObject::connect(stackWidget, SIGNAL(currentFrameChanged(int)),
                         this, SLOT(_q_onCurrentFrameChanged(int)));
    }
}

QScriptDebuggerScriptsWidgetInterface *QScriptDebugger::scriptsWidget() const
{
    Q_D(const QScriptDebugger);
    return d->scriptsWidget;
}

void QScriptDebugger::setScriptsWidget(QScriptDebuggerScriptsWidgetInterface *scriptsWidget)
{
    Q_D(QScriptDebugger);
    if (d->scriptsWidget) {
        QObject::disconnect(d->scriptsWidget, 0, this, 0);
    }
    d->scriptsWidget = scriptsWidget;
    if (scriptsWidget) {
        if (!d->scriptsModel) {
            d->scriptsModel = new QScriptDebuggerScriptsModel(this);
            if (d->interactive)
                d->scheduleJob(new SyncScriptsJob(d));
        }
        scriptsWidget->setScriptsModel(d->scriptsModel);
        QObject::connect(scriptsWidget, SIGNAL(currentScriptChanged(qint64)),
                         this, SLOT(_q_onCurrentScriptChanged(qint64)));
        QObject::connect(d->scriptsWidget, SIGNAL(scriptLocationSelected(int)),
                         this, SLOT(_q_onScriptLocationSelected(int)));
    }
}

QScriptDebuggerLocalsWidgetInterface *QScriptDebugger::localsWidget() const
{
    Q_D(const QScriptDebugger);
    return d->localsWidget;
}

void QScriptDebugger::setLocalsWidget(QScriptDebuggerLocalsWidgetInterface *localsWidget)
{
    Q_D(QScriptDebugger);
    if (d->localsWidget) {
        // ### d->localsWidget->setLocalsModel(0);
    }
    localsWidget->setCompletionProvider(d);
    d->localsWidget = localsWidget;
}

QScriptDebuggerCodeWidgetInterface *QScriptDebugger::codeWidget() const
{
    Q_D(const QScriptDebugger);
    return d->codeWidget;
}

void QScriptDebugger::setCodeWidget(QScriptDebuggerCodeWidgetInterface *codeWidget)
{
    Q_D(QScriptDebugger);
    if (d->codeWidget) {
        d->codeWidget->removeEventFilter(this);
    }
    d->codeWidget = codeWidget;
    if (codeWidget) {
        if (!d->scriptsModel) {
            d->scriptsModel = new QScriptDebuggerScriptsModel(this);
            if (d->interactive)
                d->scheduleJob(new SyncScriptsJob(d));
        }
        codeWidget->setScriptsModel(d->scriptsModel);
        if (!d->breakpointsModel) {
            d->breakpointsModel = new QScriptBreakpointsModel(d, d, this);
            if (d->interactive)
                d->scheduleJob(new SyncBreakpointsJob(d));
        }
        codeWidget->setBreakpointsModel(d->breakpointsModel);
        codeWidget->setToolTipProvider(d);
        codeWidget->installEventFilter(this);
    }
    bool hasScript = (codeWidget != 0) && (codeWidget->currentView() != 0);
    if (d->findInScriptAction)
        d->findInScriptAction->setEnabled(hasScript && (d->codeFinderWidget != 0));
    if (d->goToLineAction)
        d->goToLineAction->setEnabled(hasScript);
    if (d->toggleBreakpointAction)
        d->toggleBreakpointAction->setEnabled(hasScript);
}

QScriptDebuggerCodeFinderWidgetInterface *QScriptDebugger::codeFinderWidget() const
{
    Q_D(const QScriptDebugger);
    return d->codeFinderWidget;
}

void QScriptDebugger::setCodeFinderWidget(QScriptDebuggerCodeFinderWidgetInterface *codeFinderWidget)
{
    Q_D(QScriptDebugger);
    if (d->codeFinderWidget) {
        QObject::disconnect(d->codeFinderWidget, 0, this, 0);
    }
    d->codeFinderWidget = codeFinderWidget;
    if (codeFinderWidget) {
        QObject::connect(codeFinderWidget, SIGNAL(findRequest(QString,int)),
                         this, SLOT(_q_onFindCodeRequest(QString,int)));
    }
    if (d->findInScriptAction) {
        d->findInScriptAction->setEnabled(
            (codeFinderWidget != 0)
            && (d->codeWidget != 0)
            && (d->codeWidget->currentView() != 0));
    }
}

QScriptDebugOutputWidgetInterface *QScriptDebugger::debugOutputWidget() const
{
    Q_D(const QScriptDebugger);
    return d->debugOutputWidget;
}

void QScriptDebugger::setDebugOutputWidget(QScriptDebugOutputWidgetInterface *debugOutputWidget)
{
    Q_D(QScriptDebugger);
    d->debugOutputWidget = debugOutputWidget;
}

QScriptBreakpointsWidgetInterface *QScriptDebugger::breakpointsWidget() const
{
    Q_D(const QScriptDebugger);
    return d->breakpointsWidget;
}

void QScriptDebugger::setBreakpointsWidget(QScriptBreakpointsWidgetInterface *breakpointsWidget)
{
    Q_D(QScriptDebugger);
    if (d->breakpointsWidget) {
        // ### invalidate
    }
    d->breakpointsWidget = breakpointsWidget;
    if (breakpointsWidget) {
        if (!d->breakpointsModel) {
            d->breakpointsModel = new QScriptBreakpointsModel(d, d, this);
            if (d->interactive)
                d->scheduleJob(new SyncBreakpointsJob(d));
        }
        d->breakpointsWidget->setBreakpointsModel(d->breakpointsModel);
        d->breakpointsWidget->setScriptsModel(d->scriptsModel);
    }
}

QScriptErrorLogWidgetInterface *QScriptDebugger::errorLogWidget() const
{
    Q_D(const QScriptDebugger);
    return d->errorLogWidget;
}

void QScriptDebugger::setErrorLogWidget(QScriptErrorLogWidgetInterface *errorLogWidget)
{
    Q_D(QScriptDebugger);
    d->errorLogWidget = errorLogWidget;
}

QScriptDebuggerWidgetFactoryInterface *QScriptDebugger::widgetFactory() const
{
    Q_D(const QScriptDebugger);
    return d->widgetFactory;
}

void QScriptDebugger::setWidgetFactory(QScriptDebuggerWidgetFactoryInterface *factory)
{
    Q_D(QScriptDebugger);
    d->widgetFactory = factory;
}

QAction *QScriptDebugger::interruptAction(QObject *parent) const
{
    Q_D(const QScriptDebugger);
    if (!d->interruptAction) {
        QIcon interruptIcon;
        interruptIcon.addPixmap(d->pixmap(QString::fromLatin1("interrupt.png")), QIcon::Normal);
        interruptIcon.addPixmap(d->pixmap(QString::fromLatin1("d_interrupt.png")), QIcon::Disabled);
        QScriptDebugger *that = const_cast<QScriptDebugger*>(this);
        that->d_func()->interruptAction = new QAction(interruptIcon, QScriptDebugger::tr("Interrupt"), parent);
        d->interruptAction->setEnabled(!d->interactive);
#ifndef QT_NO_SHORTCUT
        d->interruptAction->setShortcut(QScriptDebugger::tr("Shift+F5"));
#endif
        QObject::connect(d->interruptAction, SIGNAL(triggered()),
                         that, SLOT(_q_interrupt()));
    }
    return d->interruptAction;
}

QAction *QScriptDebugger::continueAction(QObject *parent) const
{
    Q_D(const QScriptDebugger);
    if (!d->continueAction) {
        QIcon continueIcon;
        continueIcon.addPixmap(d->pixmap(QString::fromLatin1("play.png")), QIcon::Normal);
        continueIcon.addPixmap(d->pixmap(QString::fromLatin1("d_play.png")), QIcon::Disabled);
        QScriptDebugger *that = const_cast<QScriptDebugger*>(this);
        that->d_func()->continueAction = new QAction(continueIcon, QScriptDebugger::tr("Continue"), parent);
        d->continueAction->setEnabled(d->interactive);
#ifndef QT_NO_SHORTCUT
        d->continueAction->setShortcut(QScriptDebugger::tr("F5"));
#endif
        QObject::connect(d->continueAction, SIGNAL(triggered()),
                         that, SLOT(_q_continue()));
    }
    return d->continueAction;
}

QAction *QScriptDebugger::stepIntoAction(QObject *parent) const
{
    Q_D(const QScriptDebugger);
    if (!d->stepIntoAction) {
        QIcon stepIntoIcon;
        stepIntoIcon.addPixmap(d->pixmap(QString::fromLatin1("stepinto.png")), QIcon::Normal);
        stepIntoIcon.addPixmap(d->pixmap(QString::fromLatin1("d_stepinto.png")), QIcon::Disabled);
        QScriptDebugger *that = const_cast<QScriptDebugger*>(this);
        that->d_func()->stepIntoAction = new QAction(stepIntoIcon, QScriptDebugger::tr("Step Into"), parent);
        d->stepIntoAction->setEnabled(d->interactive);
#ifndef QT_NO_SHORTCUT
        d->stepIntoAction->setShortcut(QScriptDebugger::tr("F11"));
#endif
        QObject::connect(d->stepIntoAction, SIGNAL(triggered()),
                         that, SLOT(_q_stepInto()));
    }
    return d->stepIntoAction;
}

QAction *QScriptDebugger::stepOverAction(QObject *parent) const
{
    Q_D(const QScriptDebugger);
    if (!d->stepOverAction) {
        QIcon stepOverIcon;
        stepOverIcon.addPixmap(d->pixmap(QString::fromLatin1("stepover.png")), QIcon::Normal);
        stepOverIcon.addPixmap(d->pixmap(QString::fromLatin1("d_stepover.png")), QIcon::Disabled);
        QScriptDebugger *that = const_cast<QScriptDebugger*>(this);
        that->d_func()->stepOverAction = new QAction(stepOverIcon, QScriptDebugger::tr("Step Over"), parent);
        d->stepOverAction->setEnabled(d->interactive);
#ifndef QT_NO_SHORTCUT
        d->stepOverAction->setShortcut(QScriptDebugger::tr("F10"));
#endif
        QObject::connect(d->stepOverAction, SIGNAL(triggered()),
                         that, SLOT(_q_stepOver()));
    }
    return d->stepOverAction;
}

QAction *QScriptDebugger::stepOutAction(QObject *parent) const
{
    Q_D(const QScriptDebugger);
    if (!d->stepOutAction) {
        QIcon stepOutIcon;
        stepOutIcon.addPixmap(d->pixmap(QString::fromLatin1("stepout.png")), QIcon::Normal);
        stepOutIcon.addPixmap(d->pixmap(QString::fromLatin1("d_stepout.png")), QIcon::Disabled);
        QScriptDebugger *that = const_cast<QScriptDebugger*>(this);
        that->d_func()->stepOutAction = new QAction(stepOutIcon, QScriptDebugger::tr("Step Out"), parent);
        d->stepOutAction->setEnabled(d->interactive);
#ifndef QT_NO_SHORTCUT
        d->stepOutAction->setShortcut(QScriptDebugger::tr("Shift+F11"));
#endif
        QObject::connect(d->stepOutAction, SIGNAL(triggered()),
                         that, SLOT(_q_stepOut()));
    }
    return d->stepOutAction;
}

QAction *QScriptDebugger::runToCursorAction(QObject *parent) const
{
    Q_D(const QScriptDebugger);
    if (!d->runToCursorAction) {
        QIcon runToCursorIcon;
        runToCursorIcon.addPixmap(d->pixmap(QString::fromLatin1("runtocursor.png")), QIcon::Normal);
        runToCursorIcon.addPixmap(d->pixmap(QString::fromLatin1("d_runtocursor.png")), QIcon::Disabled);
        QScriptDebugger *that = const_cast<QScriptDebugger*>(this);
        that->d_func()->runToCursorAction = new QAction(runToCursorIcon, QScriptDebugger::tr("Run to Cursor"), parent);
        d->runToCursorAction->setEnabled(d->interactive);
#ifndef QT_NO_SHORTCUT
        d->runToCursorAction->setShortcut(QScriptDebugger::tr("Ctrl+F10"));
#endif
        QObject::connect(d->runToCursorAction, SIGNAL(triggered()),
                         that, SLOT(_q_runToCursor()));
    }
    return d->runToCursorAction;
}

QAction *QScriptDebugger::runToNewScriptAction(QObject *parent) const
{
    Q_D(const QScriptDebugger);
    if (!d->runToNewScriptAction) {
        QIcon runToNewScriptIcon;
        runToNewScriptIcon.addPixmap(d->pixmap(QString::fromLatin1("runtonewscript.png")), QIcon::Normal);
        runToNewScriptIcon.addPixmap(d->pixmap(QString::fromLatin1("d_breakonscriptload.png")), QIcon::Disabled);
        QScriptDebugger *that = const_cast<QScriptDebugger*>(this);
        that->d_func()->runToNewScriptAction = new QAction(runToNewScriptIcon,
                                                           QScriptDebugger::tr("Run to New Script"), parent);
        d->runToNewScriptAction->setEnabled(d->interactive);
        QObject::connect(d->runToNewScriptAction, SIGNAL(triggered()),
                         that, SLOT(_q_runToNewScript()));
    }
    return d->runToNewScriptAction;
}

QAction *QScriptDebugger::toggleBreakpointAction(QObject *parent) const
{
    Q_D(const QScriptDebugger);
    if (!d->toggleBreakpointAction) {
        QIcon toggleBreakpointIcon;
        QScriptDebugger *that = const_cast<QScriptDebugger*>(this);
        that->d_func()->toggleBreakpointAction = new QAction(toggleBreakpointIcon,
                                                             QScriptDebugger::tr("Toggle Breakpoint"), parent);
#ifndef QT_NO_SHORTCUT
        d->toggleBreakpointAction->setShortcut(QScriptDebugger::tr("F9"));
#endif
        d->toggleBreakpointAction->setEnabled((d->codeWidget != 0) && (d->codeWidget->currentView() != 0));
        QObject::connect(d->toggleBreakpointAction, SIGNAL(triggered()),
                         that, SLOT(_q_toggleBreakpoint()));
    }
    return d->toggleBreakpointAction;
}

QAction *QScriptDebugger::clearDebugOutputAction(QObject *parent) const
{
    Q_D(const QScriptDebugger);
    if (!d->clearDebugOutputAction) {
        QIcon clearDebugOutputIcon;
        QScriptDebugger *that = const_cast<QScriptDebugger*>(this);
        that->d_func()->clearDebugOutputAction = new QAction(clearDebugOutputIcon, QScriptDebugger::tr("Clear Debug Output"), parent);
        QObject::connect(d->clearDebugOutputAction, SIGNAL(triggered()),
                         that, SLOT(_q_clearDebugOutput()));
    }
    return d->clearDebugOutputAction;
}

QAction *QScriptDebugger::clearErrorLogAction(QObject *parent) const
{
    Q_D(const QScriptDebugger);
    if (!d->clearErrorLogAction) {
        QIcon clearErrorLogIcon;
        QScriptDebugger *that = const_cast<QScriptDebugger*>(this);
        that->d_func()->clearErrorLogAction = new QAction(clearErrorLogIcon, QScriptDebugger::tr("Clear Error Log"), parent);
        QObject::connect(d->clearErrorLogAction, SIGNAL(triggered()),
                         that, SLOT(_q_clearErrorLog()));
    }
    return d->clearErrorLogAction;
}

QAction *QScriptDebugger::clearConsoleAction(QObject *parent) const
{
    Q_D(const QScriptDebugger);
    if (!d->clearConsoleAction) {
        QIcon clearConsoleIcon;
        QScriptDebugger *that = const_cast<QScriptDebugger*>(this);
        that->d_func()->clearConsoleAction = new QAction(clearConsoleIcon, QScriptDebugger::tr("Clear Console"), parent);
        QObject::connect(d->clearConsoleAction, SIGNAL(triggered()),
                         that, SLOT(_q_clearConsole()));
    }
    return d->clearConsoleAction;
}

QAction *QScriptDebugger::findInScriptAction(QObject *parent) const
{
    Q_D(const QScriptDebugger);
    if (!d->findInScriptAction) {
        QIcon findInScriptIcon;
        findInScriptIcon.addPixmap(d->pixmap(QString::fromLatin1("find.png")), QIcon::Normal);
        QScriptDebugger *that = const_cast<QScriptDebugger*>(this);
        that->d_func()->findInScriptAction = new QAction(findInScriptIcon, QScriptDebugger::tr("&Find in Script..."), parent);
#ifndef QT_NO_SHORTCUT
        d->findInScriptAction->setShortcut(QScriptDebugger::tr("Ctrl+F"));
#endif
        d->findInScriptAction->setEnabled(
            (d->codeFinderWidget != 0)
            && (d->codeWidget != 0)
            && (d->codeWidget->currentView() != 0));
        QObject::connect(d->findInScriptAction, SIGNAL(triggered()),
                         that, SLOT(_q_findInScript()));
    }
    return d->findInScriptAction;
}

QAction *QScriptDebugger::findNextInScriptAction(QObject *parent) const
{
    Q_D(const QScriptDebugger);
    if (!d->findNextInScriptAction) {
        QIcon findNextInScriptIcon;
        QScriptDebugger *that = const_cast<QScriptDebugger*>(this);
        that->d_func()->findNextInScriptAction = new QAction(findNextInScriptIcon, QScriptDebugger::tr("Find &Next"), parent);
        d->findNextInScriptAction->setEnabled(d->codeFinderWidget && !d->codeFinderWidget->text().isEmpty());
#ifndef QT_NO_SHORTCUT
        d->findNextInScriptAction->setShortcut(QScriptDebugger::tr("F3"));
#endif
        QObject::connect(d->findNextInScriptAction, SIGNAL(triggered()),
                         that, SLOT(_q_findNextInScript()));
    }
    return d->findNextInScriptAction;
}

QAction *QScriptDebugger::findPreviousInScriptAction(QObject *parent) const
{
    Q_D(const QScriptDebugger);
    if (!d->findPreviousInScriptAction) {
        QIcon findPreviousInScriptIcon;
        QScriptDebugger *that = const_cast<QScriptDebugger*>(this);
        that->d_func()->findPreviousInScriptAction = new QAction(findPreviousInScriptIcon, QScriptDebugger::tr("Find &Previous"), parent);
        d->findPreviousInScriptAction->setEnabled(d->codeFinderWidget && !d->codeFinderWidget->text().isEmpty());
#ifndef QT_NO_SHORTCUT
        d->findPreviousInScriptAction->setShortcut(QScriptDebugger::tr("Shift+F3"));
#endif
        QObject::connect(d->findPreviousInScriptAction, SIGNAL(triggered()),
                         that, SLOT(_q_findPreviousInScript()));
    }
    return d->findPreviousInScriptAction;
}

QAction *QScriptDebugger::goToLineAction(QObject *parent) const
{
    Q_D(const QScriptDebugger);
    if (!d->goToLineAction) {
        QIcon goToLineIcon;
        QScriptDebugger *that = const_cast<QScriptDebugger*>(this);
        that->d_func()->goToLineAction = new QAction(goToLineIcon, QScriptDebugger::tr("Go to Line"), parent);
#ifndef QT_NO_SHORTCUT
        d->goToLineAction->setShortcut(QScriptDebugger::tr("Ctrl+G"));
#endif
        d->goToLineAction->setEnabled((d->codeWidget != 0) && (d->codeWidget->currentView() != 0));
        QObject::connect(d->goToLineAction, SIGNAL(triggered()),
                         that, SLOT(_q_goToLine()));
    }
    return d->goToLineAction;
}

QMenu *QScriptDebugger::createStandardMenu(QWidget *widgetParent, QObject *actionParent)
{
    QMenu *menu = new QMenu(widgetParent);
    menu->setTitle(QScriptDebugger::tr("Debug"));
    menu->addAction(action(ContinueAction, actionParent));
    menu->addAction(action(InterruptAction, actionParent));
    menu->addAction(action(StepIntoAction, actionParent));
    menu->addAction(action(StepOverAction, actionParent));
    menu->addAction(action(StepOutAction, actionParent));
    menu->addAction(action(RunToCursorAction, actionParent));
    menu->addAction(action(RunToNewScriptAction, actionParent));

    menu->addSeparator();
    menu->addAction(action(ToggleBreakpointAction, actionParent));

    menu->addSeparator();
    menu->addAction(action(ClearDebugOutputAction, actionParent));
    menu->addAction(action(ClearErrorLogAction, actionParent));
    menu->addAction(action(ClearConsoleAction, actionParent));

    return menu;
}

#ifndef QT_NO_TOOLBAR
QToolBar *QScriptDebugger::createStandardToolBar(QWidget *widgetParent, QObject *actionParent)
{
    QToolBar *tb = new QToolBar(widgetParent);
    tb->setObjectName(QLatin1String("qtscriptdebugger_standardToolBar"));
    tb->addAction(action(ContinueAction, actionParent));
    tb->addAction(action(InterruptAction, actionParent));
    tb->addAction(action(StepIntoAction, actionParent));
    tb->addAction(action(StepOverAction, actionParent));
    tb->addAction(action(StepOutAction, actionParent));
    tb->addAction(action(RunToCursorAction, actionParent));
    tb->addAction(action(RunToNewScriptAction, actionParent));
    tb->addSeparator();
    tb->addAction(action(FindInScriptAction, actionParent));
    return tb;
}
#endif

bool QScriptDebugger::isInteractive() const
{
    Q_D(const QScriptDebugger);
    return d->interactive;
}

/*!
  \reimp
*/
bool QScriptDebugger::eventFilter(QObject *watched, QEvent *e)
{
    Q_D(QScriptDebugger);
    if (watched == d->codeWidget) {
        if (e->type() == QEvent::KeyPress) {
            d->_q_findInScript();
            d->codeFinderWidget->setText(static_cast<QKeyEvent*>(e)->text());
            return true;
        }
    }
    return false;
}

/*!
  \reimp
*/
void QScriptDebugger::timerEvent(QTimerEvent *e)
{
    Q_D(QScriptDebugger);
    if (e->timerId() == d->updatesEnabledTimerId) {
        killTimer(d->updatesEnabledTimerId);
        d->updatesEnabledTimerId = -1;
        if (d->stackWidget)
            d->stackWidget->setUpdatesEnabled(true);
        if (d->localsWidget)
            d->localsWidget->setUpdatesEnabled(true);
    } else {
        QObject::timerEvent(e);
    }
}

QT_END_NAMESPACE

#include "moc_qscriptdebugger_p.cpp"
