diff options
Diffstat (limited to 'src/scripttools/debugging')
22 files changed, 763 insertions, 358 deletions
diff --git a/src/scripttools/debugging/debugging.pri b/src/scripttools/debugging/debugging.pri index fa39e83..2082fd0 100644 --- a/src/scripttools/debugging/debugging.pri +++ b/src/scripttools/debugging/debugging.pri @@ -111,7 +111,8 @@ SOURCES += \ $$PWD/qscriptbreakpointswidget.cpp \ $$PWD/qscriptbreakpointsmodel.cpp \ $$PWD/qscripterrorlogwidgetinterface.cpp \ - $$PWD/qscripterrorlogwidget.cpp + $$PWD/qscripterrorlogwidget.cpp \ + $$PWD/qscriptdebuggerstandardwidgetfactory.cpp HEADERS += \ $$PWD/qscriptdebuggerconsolewidgetinterface_p_p.h \ @@ -148,7 +149,8 @@ HEADERS += \ $$PWD/qscripterrorlogwidgetinterface_p_p.h \ $$PWD/qscripterrorlogwidgetinterface_p.h \ $$PWD/qscripterrorlogwidget_p.h \ - $$PWD/qscriptdebuggerwidgetfactoryinterface_p.h + $$PWD/qscriptdebuggerwidgetfactoryinterface_p.h \ + $$PWD/qscriptdebuggerstandardwidgetfactory_p.h SOURCES += \ $$PWD/qscriptenginedebugger.cpp diff --git a/src/scripttools/debugging/qscriptcompletiontask.cpp b/src/scripttools/debugging/qscriptcompletiontask.cpp index 0c67075..8880bb5 100644 --- a/src/scripttools/debugging/qscriptcompletiontask.cpp +++ b/src/scripttools/debugging/qscriptcompletiontask.cpp @@ -44,12 +44,10 @@ #include "qscriptdebuggerconsole_p.h" #include "qscriptdebuggerconsolecommand_p.h" #include "qscriptdebuggerconsolecommandmanager_p.h" - -#include "qscriptenginedebuggerfrontend_p.h" // ### kill -#include "qscriptdebuggerbackend_p.h" // ### kill -#include <QtScript/qscriptcontext.h> -#include <QtScript/qscriptvalue.h> -#include <QtScript/qscriptvalueiterator.h> +#include "qscriptdebuggercommandschedulerjob_p.h" +#include "qscriptdebuggercommandschedulerfrontend_p.h" +#include "qscriptdebuggerjobschedulerinterface_p.h" +#include "qscriptdebuggerresponse_p.h" #include "private/qobject_p.h" @@ -67,11 +65,13 @@ public: ~QScriptCompletionTaskPrivate(); void completeScriptExpression(); + void emitFinished(); QString contents; int cursorPosition; int frameIndex; - QScriptDebuggerFrontend *frontend; + QScriptDebuggerCommandSchedulerInterface *commandScheduler; + QScriptDebuggerJobSchedulerInterface *jobScheduler; QScriptDebuggerConsole *console; }; @@ -83,28 +83,33 @@ QScriptCompletionTaskPrivate::~QScriptCompletionTaskPrivate() { } -QScriptCompletionTask::QScriptCompletionTask( - const QString &contents, int cursorPosition, - int frameIndex, QScriptDebuggerFrontend *frontend, - QScriptDebuggerConsole *console, - QObject *parent) - : QScriptCompletionTaskInterface( - *new QScriptCompletionTaskPrivate, parent) +class QScriptCompleteExpressionJob : public QScriptDebuggerCommandSchedulerJob { - Q_D(QScriptCompletionTask); - d->contents = contents; - d->cursorPosition = cursorPosition; - if ((frameIndex == -1) && console) - d->frameIndex = console->currentFrameIndex(); - else - d->frameIndex = frameIndex; - d->frontend = frontend; - d->console = console; -} +public: + QScriptCompleteExpressionJob(int frameIndex, const QStringList &path, + QScriptCompletionTaskPrivate *task, + QScriptDebuggerCommandSchedulerInterface *scheduler) + : QScriptDebuggerCommandSchedulerJob(scheduler), + m_frameIndex(frameIndex), m_path(path), m_task(task) + {} -QScriptCompletionTask::~QScriptCompletionTask() -{ -} + void start() + { + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + frontend.scheduleGetCompletions(m_frameIndex, m_path); + } + void handleResponse(const QScriptDebuggerResponse &response, int /*commandId*/) + { + m_task->results = response.result().toStringList(); + m_task->emitFinished(); + finish(); + } + +private: + int m_frameIndex; + QStringList m_path; + QScriptCompletionTaskPrivate *m_task; +}; namespace { @@ -122,17 +127,49 @@ static bool isPrefixOf(const QString &prefix, const QString &what) } // namespace +class QScriptCompleteScriptsJob : public QScriptDebuggerCommandSchedulerJob +{ +public: + QScriptCompleteScriptsJob(const QString &prefix, QScriptCompletionTaskPrivate *task, + QScriptDebuggerCommandSchedulerInterface *scheduler) + : QScriptDebuggerCommandSchedulerJob(scheduler), + m_prefix(prefix), m_task(task) + {} + + void start() + { + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + frontend.scheduleGetScripts(); + } + void handleResponse(const QScriptDebuggerResponse &response, int /*commandId*/) + { + QScriptScriptMap scripts = response.resultAsScripts(); + QScriptScriptMap::const_iterator it; + for (it = scripts.constBegin(); it != scripts.constEnd(); ++it) { + QString fileName = it.value().fileName(); + if (isPrefixOf(m_prefix, fileName)) + m_task->results.append(fileName); + } + m_task->emitFinished(); + finish(); + } +private: + QString m_prefix; + QScriptCompletionTaskPrivate *m_task; +}; + void QScriptCompletionTaskPrivate::completeScriptExpression() { int pos = cursorPosition; if ((pos > 0) && contents.at(pos-1).isNumber()) { // completion of numbers is pointless + emitFinished(); return; } while ((pos > 0) && isIdentChar(contents.at(pos-1))) --pos; - int pos2 = cursorPosition; + int pos2 = cursorPosition - 1; while ((pos2 < contents.size()-1) && isIdentChar(contents.at(pos2+1))) ++pos2; QString ident = contents.mid(pos, pos2 - pos + 1); @@ -148,65 +185,41 @@ void QScriptCompletionTaskPrivate::completeScriptExpression() path.prepend(contents.mid(pos, pos2 - pos)); } - // ### super-cheating for now; have to use the async API - QScriptEngineDebuggerFrontend *edf = static_cast<QScriptEngineDebuggerFrontend*>(frontend); - QScriptDebuggerBackend *backend = edf->backend(); - QScriptContext *ctx = backend->context(frameIndex); - QScriptValueList objects; - QString prefix = path.last(); - QSet<QString> matches; - if (path.size() > 1) { - const QString &topLevelIdent = path.at(0); - QScriptValue obj; - if (topLevelIdent == QString::fromLatin1("this")) { - obj = ctx->thisObject(); - } else { - QScriptValueList scopeChain; - scopeChain = ctx->scopeChain(); - for (int i = 0; i < scopeChain.size(); ++i) { - QScriptValue oo = scopeChain.at(i).property(topLevelIdent); - if (oo.isObject()) { - obj = oo; - break; - } - } - } - for (int i = 1; obj.isObject() && (i < path.size()-1); ++i) - obj = obj.property(path.at(i)); - if (obj.isValid()) - objects.append(obj); - } else { - objects << ctx->scopeChain(); - QStringList keywords; - keywords.append(QString::fromLatin1("this")); - keywords.append(QString::fromLatin1("true")); - keywords.append(QString::fromLatin1("false")); - keywords.append(QString::fromLatin1("null")); - for (int i = 0; i < keywords.size(); ++i) { - const QString &kwd = keywords.at(i); - if (isPrefixOf(prefix, kwd)) - matches.insert(kwd); - } - } + length = path.last().length(); + type = QScriptCompletionTask::ScriptIdentifierCompletion; - for (int i = 0; i < objects.size(); ++i) { - QScriptValue obj = objects.at(i); - while (obj.isObject()) { - QScriptValueIterator it(obj); - while (it.hasNext()) { - it.next(); - QString propertyName = it.name(); - if (isPrefixOf(prefix, propertyName)) - matches.insert(propertyName); - } - obj = obj.prototype(); - } - } - results = matches.toList(); - qStableSort(results); + QScriptDebuggerJob *job = new QScriptCompleteExpressionJob(frameIndex, path, this, commandScheduler); + jobScheduler->scheduleJob(job); +} - length = prefix.length(); - type = QScriptCompletionTask::ScriptIdentifierCompletion; +void QScriptCompletionTaskPrivate::emitFinished() +{ + emit q_func()->finished(); +} + +QScriptCompletionTask::QScriptCompletionTask( + const QString &contents, int cursorPosition, int frameIndex, + QScriptDebuggerCommandSchedulerInterface *commandScheduler, + QScriptDebuggerJobSchedulerInterface *jobScheduler, + QScriptDebuggerConsole *console, + QObject *parent) + : QScriptCompletionTaskInterface( + *new QScriptCompletionTaskPrivate, parent) +{ + Q_D(QScriptCompletionTask); + d->contents = contents; + d->cursorPosition = cursorPosition; + if ((frameIndex == -1) && console) + d->frameIndex = console->currentFrameIndex(); + else + d->frameIndex = frameIndex; + d->commandScheduler = commandScheduler; + d->jobScheduler = jobScheduler; + d->console = console; +} + +QScriptCompletionTask::~QScriptCompletionTask() +{ } void QScriptCompletionTask::start() @@ -223,7 +236,6 @@ void QScriptCompletionTask::start() if ((d->cursorPosition >= cmdIndex) && (d->cursorPosition <= (cmdIndex+len))) { // editing command --> get command completions d->results = d->console->commandManager()->completions(prefix); - qStableSort(d->results); d->position = cmdRx.pos(1); d->length = prefix.length(); d->type = CommandNameCompletion; @@ -256,41 +268,37 @@ void QScriptCompletionTask::start() } QString argType = cmd->argumentTypes().value(argNum); if (!argType.isEmpty()) { - if (argType == QString::fromLatin1("command-or-group-name")) { + if (argType == QLatin1String("command-or-group-name")) { d->results = d->console->commandManager()->completions(arg); - } else if (argType == QString::fromLatin1("script-filename")) { - // ### super-cheating for now; have to use the async API - QScriptEngineDebuggerFrontend *edf = static_cast<QScriptEngineDebuggerFrontend*>(d->frontend); - QScriptDebuggerBackend *backend = edf->backend(); - QScriptScriptMap scripts = backend->scripts(); - QScriptScriptMap::const_iterator it; - for (it = scripts.constBegin(); it != scripts.constEnd(); ++it) { - QString fileName = it.value().fileName(); - if (isPrefixOf(arg, fileName)) - d->results.append(fileName); - } - } else if (argType == QString::fromLatin1("subcommand-name")) { + } else if (argType == QLatin1String("script-filename")) { + d->position = pos; + d->length = arg.length(); + d->type = CommandArgumentCompletion; + QScriptDebuggerJob *job = new QScriptCompleteScriptsJob(arg, d, d->commandScheduler); + d->jobScheduler->scheduleJob(job); + } else if (argType == QLatin1String("subcommand-name")) { for (int i = 0; i < cmd->subCommands().size(); ++i) { QString name = cmd->subCommands().at(i); if (isPrefixOf(arg, name)) d->results.append(name); } - } else if (argType == QString::fromLatin1("script")) { + qStableSort(d->results); + } else if (argType == QLatin1String("script")) { d->completeScriptExpression(); + } else { + emit finished(); } if ((d->type == NoCompletion) && !d->results.isEmpty()) { - qStableSort(d->results); d->position = pos; d->length = arg.length(); d->type = CommandArgumentCompletion; + emit finished(); } } - emit finished(); } } else { // assume it's an eval expression d->completeScriptExpression(); - emit finished(); } } diff --git a/src/scripttools/debugging/qscriptcompletiontask_p.h b/src/scripttools/debugging/qscriptcompletiontask_p.h index 2dd2025..1dd80c0 100644 --- a/src/scripttools/debugging/qscriptcompletiontask_p.h +++ b/src/scripttools/debugging/qscriptcompletiontask_p.h @@ -60,7 +60,8 @@ QT_BEGIN_NAMESPACE -class QScriptDebuggerFrontend; +class QScriptDebuggerCommandSchedulerInterface; +class QScriptDebuggerJobSchedulerInterface; class QScriptDebuggerConsole; class QScriptCompletionTaskPrivate; @@ -70,9 +71,9 @@ class Q_AUTOTEST_EXPORT QScriptCompletionTask Q_OBJECT public: QScriptCompletionTask( - const QString &contents, int cursorPosition, - int frameIndex, - QScriptDebuggerFrontend *frontend, + const QString &contents, int cursorPosition, int frameIndex, + QScriptDebuggerCommandSchedulerInterface *commandScheduler, + QScriptDebuggerJobSchedulerInterface *jobScheduler, QScriptDebuggerConsole *console, QObject *parent = 0); ~QScriptCompletionTask(); diff --git a/src/scripttools/debugging/qscriptdebugger.cpp b/src/scripttools/debugging/qscriptdebugger.cpp index 0a580ce..9cca8ad 100644 --- a/src/scripttools/debugging/qscriptdebugger.cpp +++ b/src/scripttools/debugging/qscriptdebugger.cpp @@ -94,6 +94,9 @@ #include <QtGui/qevent.h> #include <QtGui/qicon.h> #include <QtGui/qinputdialog.h> +#include <QtGui/qmenu.h> +#include <QtGui/qtoolbar.h> +#include <QtGui/qtooltip.h> QT_BEGIN_NAMESPACE typedef QPair<QList<qint64>, QList<qint64> > QScriptScriptsDelta; @@ -171,8 +174,8 @@ public: QScriptCompletionTaskInterface *createCompletionTask( const QString &contents, int cursorPosition, int frameIndex, int options); - QString toolTip(int frameIndex, int lineNumber, - const QStringList &path); + void showToolTip(const QPoint &pos, int frameIndex, + int lineNumber, const QStringList &path); static QPixmap pixmap(const QString &path); @@ -633,11 +636,49 @@ bool QScriptDebuggerPrivate::debuggerEvent(const QScriptDebuggerEvent &event) 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")); + } + QToolTip::showText(m_pos, tip); + finish(); + } + +private: + QPoint m_pos; + int m_frameIndex; + int m_lineNumber; + QStringList m_path; +}; + /*! \reimp */ -QString QScriptDebuggerPrivate::toolTip(int frameIndex, int lineNumber, - const QStringList &path) +void QScriptDebuggerPrivate::showToolTip(const QPoint &pos, int frameIndex, + int lineNumber, const QStringList &path) { if (frameIndex == -1) { if (stackWidget) @@ -645,40 +686,8 @@ QString QScriptDebuggerPrivate::toolTip(int frameIndex, int lineNumber, else frameIndex = console->currentFrameIndex(); } - // ### cheating for now, need to use async API - QScriptEngineDebuggerFrontend *edf = static_cast<QScriptEngineDebuggerFrontend*>(frontend); - QScriptDebuggerBackend *backend = edf->backend(); - QScriptContext *ctx = backend->context(frameIndex); - if (!ctx || path.isEmpty()) - return QString(); - QScriptContextInfo ctxInfo(ctx); - if (ctx->callee().isValid() - && ((lineNumber < ctxInfo.functionStartLineNumber()) - || (lineNumber > ctxInfo.functionEndLineNumber()))) { - return QString(); - } - QScriptValueList objects; - int pathIndex = 0; - if (path.at(0) == QLatin1String("this")) { - objects.append(ctx->thisObject()); - ++pathIndex; - } else { - objects << ctx->scopeChain(); - } - for (int i = 0; i < objects.size(); ++i) { - QScriptValue val = objects.at(i); - for (int j = pathIndex; val.isValid() && (j < path.size()); ++j) { - val = val.property(path.at(j)); - } - if (val.isValid()) { - bool hadException = (ctx->state() == QScriptContext::ExceptionState); - QString str = val.toString(); - if (!hadException && backend->engine()->hasUncaughtException()) - backend->engine()->clearExceptions(); - return str; - } - } - return QString(); + QScriptDebuggerJob *job = new QScriptToolTipJob(pos, frameIndex, lineNumber, path, this); + scheduleJob(job); } /*! @@ -688,7 +697,7 @@ QScriptCompletionTaskInterface *QScriptDebuggerPrivate::createCompletionTask( const QString &contents, int cursorPosition, int frameIndex, int options) { return new QScriptCompletionTask( - contents, cursorPosition, frameIndex, frontend, + contents, cursorPosition, frameIndex, this, this, (options & QScriptCompletionProviderInterface::ConsoleCommandCompletion) ? console : 0); } @@ -1072,7 +1081,7 @@ class LoadLocalsJob : public QScriptDebuggerCommandSchedulerJob public: LoadLocalsJob(QScriptDebuggerPrivate *debugger, int frameIndex) : QScriptDebuggerCommandSchedulerJob(debugger), - m_debugger(debugger), m_frameIndex(frameIndex), m_state(0) {} + m_debugger(debugger), m_frameIndex(frameIndex) {} void start() { @@ -1104,7 +1113,6 @@ public: private: QScriptDebuggerPrivate *m_debugger; int m_frameIndex; - int m_state; }; class EmitStoppedSignalJob : public QScriptDebuggerJob @@ -1331,6 +1339,122 @@ void QScriptDebugger::setFrontend(QScriptDebuggerFrontend *frontend) } } +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); @@ -1783,6 +1907,45 @@ QAction *QScriptDebugger::goToLineAction(QObject *parent) const return d->goToLineAction; } +QMenu *QScriptDebugger::createStandardMenu(QWidget *widgetParent, QObject *actionParent) +{ + QMenu *menu = new QMenu(widgetParent); + menu->setTitle(QObject::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; +} + +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; +} + /*! \reimp */ diff --git a/src/scripttools/debugging/qscriptdebugger_p.h b/src/scripttools/debugging/qscriptdebugger_p.h index 1f347aa..9ed7e0a 100644 --- a/src/scripttools/debugging/qscriptdebugger_p.h +++ b/src/scripttools/debugging/qscriptdebugger_p.h @@ -70,18 +70,54 @@ class QScriptErrorLogWidgetInterface; class QScriptDebuggerWidgetFactoryInterface; class QAction; class QEvent; +class QMenu; +class QToolBar; class QScriptDebuggerPrivate; class Q_AUTOTEST_EXPORT QScriptDebugger : public QObject { Q_OBJECT public: + // mirrors QScriptEngineDebugger::DebuggerWidget + enum DebuggerWidget { + ConsoleWidget, + StackWidget, + ScriptsWidget, + LocalsWidget, + CodeWidget, + CodeFinderWidget, + BreakpointsWidget, + DebugOutputWidget, + ErrorLogWidget + }; + // mirrors QScriptEngineDebugger::DebuggerAction + enum DebuggerAction { + InterruptAction, + ContinueAction, + StepIntoAction, + StepOverAction, + StepOutAction, + RunToCursorAction, + RunToNewScriptAction, + ToggleBreakpointAction, + ClearDebugOutputAction, + ClearErrorLogAction, + ClearConsoleAction, + FindInScriptAction, + FindNextInScriptAction, + FindPreviousInScriptAction, + GoToLineAction + }; + QScriptDebugger(QObject *parent = 0); ~QScriptDebugger(); QScriptDebuggerFrontend *frontend() const; void setFrontend(QScriptDebuggerFrontend *frontend); + QWidget *widget(DebuggerWidget widget); + QAction *action(DebuggerAction action, QObject *parent); + QScriptDebuggerConsoleWidgetInterface *consoleWidget() const; void setConsoleWidget(QScriptDebuggerConsoleWidgetInterface *consoleWidget); @@ -131,6 +167,9 @@ public: QAction *clearConsoleAction(QObject *parent) const; QAction *clearErrorLogAction(QObject *parent) const; + QMenu *createStandardMenu(QWidget *widgetParent, QObject *actionParent); + QToolBar *createStandardToolBar(QWidget *widgetParent, QObject *actionParent); + bool eventFilter(QObject *, QEvent *e); Q_SIGNALS: diff --git a/src/scripttools/debugging/qscriptdebuggerbackend.cpp b/src/scripttools/debugging/qscriptdebuggerbackend.cpp index 524ee0d..9eaf571 100644 --- a/src/scripttools/debugging/qscriptdebuggerbackend.cpp +++ b/src/scripttools/debugging/qscriptdebuggerbackend.cpp @@ -292,7 +292,7 @@ QScriptValue QScriptDebuggerBackendPrivate::trace(QScriptContext *context, QString str; for (int i = 0; i < context->argumentCount(); ++i) { if (i > 0) - str.append(QLatin1String(" ")); + str.append(QLatin1Char(' ')); str.append(context->argument(i).toString()); } QScriptDebuggerEvent e(QScriptDebuggerEvent::Trace); diff --git a/src/scripttools/debugging/qscriptdebuggercodeview.cpp b/src/scripttools/debugging/qscriptdebuggercodeview.cpp index a240b94..fe358b8 100644 --- a/src/scripttools/debugging/qscriptdebuggercodeview.cpp +++ b/src/scripttools/debugging/qscriptdebuggercodeview.cpp @@ -214,7 +214,6 @@ bool QScriptDebuggerCodeView::event(QEvent *e) if (contents.isEmpty()) return false; int linePosition = cursor.position() - block.position(); - linePosition -= 3; if (linePosition < 0) linePosition = 0; @@ -233,7 +232,7 @@ bool QScriptDebuggerCodeView::event(QEvent *e) // ignore string literals return false; } - int pos2 = linePosition; + int pos2 = linePosition - 1; while ((pos2 < contents.size()-1) && isIdentChar(contents.at(pos2+1))) ++pos2; QString ident = contents.mid(pos, pos2 - pos + 1); diff --git a/src/scripttools/debugging/qscriptdebuggercodewidget.cpp b/src/scripttools/debugging/qscriptdebuggercodewidget.cpp index e2f394e..a058b3d 100644 --- a/src/scripttools/debugging/qscriptdebuggercodewidget.cpp +++ b/src/scripttools/debugging/qscriptdebuggercodewidget.cpp @@ -49,7 +49,6 @@ #include <QtCore/qdebug.h> #include <QtGui/qboxlayout.h> #include <QtGui/qstackedwidget.h> -#include <QtGui/qtooltip.h> QT_BEGIN_NAMESPACE @@ -197,17 +196,7 @@ void QScriptDebuggerCodeWidgetPrivate::_q_onScriptsChanged() void QScriptDebuggerCodeWidgetPrivate::_q_onToolTipRequest( const QPoint &pos, int lineNumber, const QStringList &path) { - QString tip = toolTipProvider->toolTip(/*frameIndex=*/-1, lineNumber, path); - 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")); - } - QToolTip::showText(pos, tip); + toolTipProvider->showToolTip(pos, /*frameIndex=*/-1, lineNumber, path); } QScriptDebuggerCodeWidget::QScriptDebuggerCodeWidget(QWidget *parent) diff --git a/src/scripttools/debugging/qscriptdebuggercommand.cpp b/src/scripttools/debugging/qscriptdebuggercommand.cpp index b447f7b..b2809db 100644 --- a/src/scripttools/debugging/qscriptdebuggercommand.cpp +++ b/src/scripttools/debugging/qscriptdebuggercommand.cpp @@ -45,6 +45,7 @@ #include <QtCore/qhash.h> #include <QtCore/qdatastream.h> +#include <QtCore/qstringlist.h> Q_DECLARE_METATYPE(QScriptBreakpointData) Q_DECLARE_METATYPE(QScriptDebuggerValue) @@ -558,6 +559,25 @@ QScriptDebuggerCommand QScriptDebuggerCommand::contextsCheckpoint() return cmd; } +QScriptDebuggerCommand QScriptDebuggerCommand::getPropertyExpressionValue( + int contextIndex, int lineNumber, const QStringList &path) +{ + QScriptDebuggerCommand cmd(GetPropertyExpressionValue); + cmd.setContextIndex(contextIndex); + cmd.setLineNumber(lineNumber); + cmd.setAttribute(UserAttribute, path); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::getCompletions( + int contextIndex, const QStringList &path) +{ + QScriptDebuggerCommand cmd(GetCompletions); + cmd.setContextIndex(contextIndex); + cmd.setAttribute(UserAttribute, path); + return cmd; +} + QScriptDebuggerCommand QScriptDebuggerCommand::newScriptObjectSnapshotCommand() { QScriptDebuggerCommand cmd(NewScriptObjectSnapshot); diff --git a/src/scripttools/debugging/qscriptdebuggercommand_p.h b/src/scripttools/debugging/qscriptdebuggercommand_p.h index 7ae6780..9960d42 100644 --- a/src/scripttools/debugging/qscriptdebuggercommand_p.h +++ b/src/scripttools/debugging/qscriptdebuggercommand_p.h @@ -106,6 +106,8 @@ public: GetActivationObject, GetScopeChain, ContextsCheckpoint, + GetPropertyExpressionValue, + GetCompletions, NewScriptObjectSnapshot, ScriptObjectSnapshotCapture, @@ -229,6 +231,9 @@ public: static QScriptDebuggerCommand getActivationObjectCommand(int contextIndex); static QScriptDebuggerCommand getScopeChainCommand(int contextIndex); static QScriptDebuggerCommand contextsCheckpoint(); + static QScriptDebuggerCommand getPropertyExpressionValue(int contextIndex, int lineNumber, + const QStringList &path); + static QScriptDebuggerCommand getCompletions(int contextIndex, const QStringList &path); static QScriptDebuggerCommand newScriptObjectSnapshotCommand(); static QScriptDebuggerCommand scriptObjectSnapshotCaptureCommand(int id, const QScriptDebuggerValue &object); diff --git a/src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp b/src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp index 4f21fa4..56ff912 100644 --- a/src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp +++ b/src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp @@ -101,12 +101,18 @@ QScriptDebuggerCommandExecutor::~QScriptDebuggerCommandExecutor() delete d_ptr; } +static bool isPrefixOf(const QString &prefix, const QString &what) +{ + return ((what.length() > prefix.length()) + && what.startsWith(prefix)); +} + /*! Applies the given \a command to the given \a backend. */ QScriptDebuggerResponse QScriptDebuggerCommandExecutor::execute( - QScriptDebuggerBackend *backend, - const QScriptDebuggerCommand &command) + QScriptDebuggerBackend *backend, + const QScriptDebuggerCommand &command) { QScriptDebuggerResponse response; switch (command.type()) { @@ -300,6 +306,104 @@ QScriptDebuggerResponse QScriptDebuggerCommandExecutor::execute( response.setResult(qVariantFromValue(backend->contextsCheckpoint())); } break; + case QScriptDebuggerCommand::GetPropertyExpressionValue: { + QScriptContext *ctx = backend->context(command.contextIndex()); + int lineNumber = command.lineNumber(); + QVariant attr = command.attribute(QScriptDebuggerCommand::UserAttribute); + QStringList path = attr.toStringList(); + if (!ctx || path.isEmpty()) + break; + QScriptContextInfo ctxInfo(ctx); + if (ctx->callee().isValid() + && ((lineNumber < ctxInfo.functionStartLineNumber()) + || (lineNumber > ctxInfo.functionEndLineNumber()))) { + break; + } + QScriptValueList objects; + int pathIndex = 0; + if (path.at(0) == QLatin1String("this")) { + objects.append(ctx->thisObject()); + ++pathIndex; + } else { + objects << ctx->scopeChain(); + } + for (int i = 0; i < objects.size(); ++i) { + QScriptValue val = objects.at(i); + for (int j = pathIndex; val.isValid() && (j < path.size()); ++j) { + val = val.property(path.at(j)); + } + if (val.isValid()) { + bool hadException = (ctx->state() == QScriptContext::ExceptionState); + QString str = val.toString(); + if (!hadException && backend->engine()->hasUncaughtException()) + backend->engine()->clearExceptions(); + response.setResult(str); + break; + } + } + } break; + + case QScriptDebuggerCommand::GetCompletions: { + QScriptContext *ctx = backend->context(command.contextIndex()); + QVariant attr = command.attribute(QScriptDebuggerCommand::UserAttribute); + QStringList path = attr.toStringList(); + if (!ctx || path.isEmpty()) + break; + QScriptValueList objects; + QString prefix = path.last(); + QSet<QString> matches; + if (path.size() > 1) { + const QString &topLevelIdent = path.at(0); + QScriptValue obj; + if (topLevelIdent == QLatin1String("this")) { + obj = ctx->thisObject(); + } else { + QScriptValueList scopeChain; + scopeChain = ctx->scopeChain(); + for (int i = 0; i < scopeChain.size(); ++i) { + QScriptValue oo = scopeChain.at(i).property(topLevelIdent); + if (oo.isObject()) { + obj = oo; + break; + } + } + } + for (int i = 1; obj.isObject() && (i < path.size()-1); ++i) + obj = obj.property(path.at(i)); + if (obj.isValid()) + objects.append(obj); + } else { + objects << ctx->scopeChain(); + QStringList keywords; + keywords.append(QString::fromLatin1("this")); + keywords.append(QString::fromLatin1("true")); + keywords.append(QString::fromLatin1("false")); + keywords.append(QString::fromLatin1("null")); + for (int i = 0; i < keywords.size(); ++i) { + const QString &kwd = keywords.at(i); + if (isPrefixOf(prefix, kwd)) + matches.insert(kwd); + } + } + + for (int i = 0; i < objects.size(); ++i) { + QScriptValue obj = objects.at(i); + while (obj.isObject()) { + QScriptValueIterator it(obj); + while (it.hasNext()) { + it.next(); + QString propertyName = it.name(); + if (isPrefixOf(prefix, propertyName)) + matches.insert(propertyName); + } + obj = obj.prototype(); + } + } + QStringList matchesList = matches.toList(); + qStableSort(matchesList); + response.setResult(matchesList); + } break; + case QScriptDebuggerCommand::NewScriptObjectSnapshot: { int id = backend->newScriptObjectSnapshot(); response.setResult(id); diff --git a/src/scripttools/debugging/qscriptdebuggercommandschedulerfrontend.cpp b/src/scripttools/debugging/qscriptdebuggercommandschedulerfrontend.cpp index 577977e..d108b6c 100644 --- a/src/scripttools/debugging/qscriptdebuggercommandschedulerfrontend.cpp +++ b/src/scripttools/debugging/qscriptdebuggercommandschedulerfrontend.cpp @@ -251,6 +251,17 @@ int QScriptDebuggerCommandSchedulerFrontend::scheduleContextsCheckpoint() return scheduleCommand(QScriptDebuggerCommand::contextsCheckpoint()); } +int QScriptDebuggerCommandSchedulerFrontend::scheduleGetPropertyExpressionValue( + int contextIndex, int lineNumber, const QStringList &path) +{ + return scheduleCommand(QScriptDebuggerCommand::getPropertyExpressionValue(contextIndex, lineNumber, path)); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleGetCompletions(int contextIndex, const QStringList &path) +{ + return scheduleCommand(QScriptDebuggerCommand::getCompletions(contextIndex, path)); +} + int QScriptDebuggerCommandSchedulerFrontend::scheduleEvaluate(int contextIndex, const QString &program, const QString &fileName, diff --git a/src/scripttools/debugging/qscriptdebuggercommandschedulerfrontend_p.h b/src/scripttools/debugging/qscriptdebuggercommandschedulerfrontend_p.h index 58c0708..dacff3a 100644 --- a/src/scripttools/debugging/qscriptdebuggercommandschedulerfrontend_p.h +++ b/src/scripttools/debugging/qscriptdebuggercommandschedulerfrontend_p.h @@ -109,6 +109,9 @@ public: int scheduleGetActivationObject(int contextIndex); int scheduleGetScopeChain(int contextIndex); int scheduleContextsCheckpoint(); + int scheduleGetPropertyExpressionValue(int contextIndex, int lineNumber, + const QStringList &path); + int scheduleGetCompletions(int contextIndex, const QStringList &path); // iteration int scheduleNewScriptValueIterator(const QScriptDebuggerValue &object); diff --git a/src/scripttools/debugging/qscriptdebuggerconsole.cpp b/src/scripttools/debugging/qscriptdebuggerconsole.cpp index 3288190..76f2819 100644 --- a/src/scripttools/debugging/qscriptdebuggerconsole.cpp +++ b/src/scripttools/debugging/qscriptdebuggerconsole.cpp @@ -163,10 +163,10 @@ QScriptDebuggerConsoleCommandJob *QScriptDebuggerConsolePrivate::createJob( .arg(name)); for (int j = 0; j < completions.size(); ++j) { if (j > 0) - msg.append(QString::fromLatin1(", ")); + msg.append(QLatin1String(", ")); msg.append(completions.at(j)); } - msg.append(QString::fromLatin1(".")); + msg.append(QLatin1Char('.')); messageHandler->message(QtWarningMsg, msg); return 0; } diff --git a/src/scripttools/debugging/qscriptdebuggerlocalsmodel.cpp b/src/scripttools/debugging/qscriptdebuggerlocalsmodel.cpp index 635cd13..402f45a 100644 --- a/src/scripttools/debugging/qscriptdebuggerlocalsmodel.cpp +++ b/src/scripttools/debugging/qscriptdebuggerlocalsmodel.cpp @@ -136,6 +136,7 @@ public: const QScriptDebuggerValuePropertyList &props); void deleteObjectSnapshots(const QList<qint64> &snapshotIds); + void deleteAllObjectSnapshots(); QScriptDebuggerJobSchedulerInterface *jobScheduler; QScriptDebuggerCommandSchedulerInterface *commandScheduler; @@ -240,6 +241,14 @@ void QScriptDebuggerLocalsModelPrivate::deleteObjectSnapshots(const QList<qint64 frontend.scheduleDeleteScriptObjectSnapshot(snapshotIds.at(i)); } +void QScriptDebuggerLocalsModelPrivate::deleteAllObjectSnapshots() +{ + QList<qint64> snapshotIds; + for (int i = 0; i < invisibleRootNode->children.count(); ++i) + snapshotIds += findSnapshotIdsRecursively(invisibleRootNode->children.at(i)); + deleteObjectSnapshots(snapshotIds); +} + QScriptDebuggerLocalsModelPrivate *QScriptDebuggerLocalsModelPrivate::get(QScriptDebuggerLocalsModel *q) { return q->d_func(); @@ -442,13 +451,6 @@ QScriptDebuggerLocalsModel::QScriptDebuggerLocalsModel( QScriptDebuggerLocalsModel::~QScriptDebuggerLocalsModel() { - Q_D(QScriptDebuggerLocalsModel); - QList<qint64> snapshotIds; - for (int i = 0; i < d->invisibleRootNode->children.count(); ++i) - snapshotIds += findSnapshotIdsRecursively(d->invisibleRootNode->children.at(i)); - QScriptDebuggerCommandSchedulerFrontend frontend(d->commandScheduler, 0); - for (int j = 0; j < snapshotIds.size(); ++j) - frontend.scheduleDeleteScriptObjectSnapshot(snapshotIds.at(j)); } QModelIndex QScriptDebuggerLocalsModelPrivate::addTopLevelObject(const QString &name, const QScriptDebuggerValue &object) @@ -807,7 +809,7 @@ QVariant QScriptDebuggerLocalsModel::data(const QModelIndex &index, int role) co QString str = node->property.valueAsString(); if (node->property.value().type() == QScriptDebuggerValue::StringValue) { // escape - str.replace(QLatin1String("\""), QLatin1String("\\\"")); + str.replace(QLatin1Char('\"'), QLatin1String("\\\"")); str.prepend(QLatin1Char('\"')); str.append(QLatin1Char('\"')); } diff --git a/src/scripttools/debugging/qscriptdebuggerobjectsnapshotdelta_p.h b/src/scripttools/debugging/qscriptdebuggerobjectsnapshotdelta_p.h index c1c2c0b..a44bd44 100644 --- a/src/scripttools/debugging/qscriptdebuggerobjectsnapshotdelta_p.h +++ b/src/scripttools/debugging/qscriptdebuggerobjectsnapshotdelta_p.h @@ -60,6 +60,8 @@ QT_BEGIN_NAMESPACE +class QDataStream; + class Q_AUTOTEST_EXPORT QScriptDebuggerObjectSnapshotDelta { public: @@ -68,6 +70,9 @@ public: QScriptDebuggerValuePropertyList addedProperties; }; +Q_AUTOTEST_EXPORT QDataStream &operator<<(QDataStream &, const QScriptDebuggerObjectSnapshotDelta &); +Q_AUTOTEST_EXPORT QDataStream &operator>>(QDataStream &, QScriptDebuggerObjectSnapshotDelta &); + QT_END_NAMESPACE #endif diff --git a/src/scripttools/debugging/qscriptdebuggerstandardwidgetfactory.cpp b/src/scripttools/debugging/qscriptdebuggerstandardwidgetfactory.cpp new file mode 100644 index 0000000..09d6f2f --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerstandardwidgetfactory.cpp @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggerstandardwidgetfactory_p.h" +#include "qscriptdebuggerconsolewidget_p.h" +#include "qscriptdebuggerstackwidget_p.h" +#include "qscriptdebuggerscriptswidget_p.h" +#include "qscriptdebuggerlocalswidget_p.h" +#include "qscriptdebuggercodewidget_p.h" +#include "qscriptdebuggercodefinderwidget_p.h" +#include "qscriptbreakpointswidget_p.h" +#include "qscriptdebugoutputwidget_p.h" +#include "qscripterrorlogwidget_p.h" + +QT_BEGIN_NAMESPACE + +QScriptDebuggerStandardWidgetFactory::QScriptDebuggerStandardWidgetFactory(QObject *parent) + : QObject(parent) +{ +} + +QScriptDebuggerStandardWidgetFactory::~QScriptDebuggerStandardWidgetFactory() +{ +} + +QScriptDebugOutputWidgetInterface *QScriptDebuggerStandardWidgetFactory::createDebugOutputWidget() +{ + return new QScriptDebugOutputWidget(); +} + +QScriptDebuggerConsoleWidgetInterface *QScriptDebuggerStandardWidgetFactory::createConsoleWidget() +{ + return new QScriptDebuggerConsoleWidget(); +} + +QScriptErrorLogWidgetInterface *QScriptDebuggerStandardWidgetFactory::createErrorLogWidget() +{ + return new QScriptErrorLogWidget(); +} + +QScriptDebuggerCodeFinderWidgetInterface *QScriptDebuggerStandardWidgetFactory::createCodeFinderWidget() +{ + return new QScriptDebuggerCodeFinderWidget(); +} + +QScriptDebuggerStackWidgetInterface *QScriptDebuggerStandardWidgetFactory::createStackWidget() +{ + return new QScriptDebuggerStackWidget(); +} + +QScriptDebuggerScriptsWidgetInterface *QScriptDebuggerStandardWidgetFactory::createScriptsWidget() +{ + return new QScriptDebuggerScriptsWidget(); +} + +QScriptDebuggerLocalsWidgetInterface *QScriptDebuggerStandardWidgetFactory::createLocalsWidget() +{ + return new QScriptDebuggerLocalsWidget(); +} + +QScriptDebuggerCodeWidgetInterface *QScriptDebuggerStandardWidgetFactory::createCodeWidget() +{ + return new QScriptDebuggerCodeWidget(); +} + +QScriptBreakpointsWidgetInterface *QScriptDebuggerStandardWidgetFactory::createBreakpointsWidget() +{ + return new QScriptBreakpointsWidget(); +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggerstandardwidgetfactory_p.h b/src/scripttools/debugging/qscriptdebuggerstandardwidgetfactory_p.h new file mode 100644 index 0000000..1d60007 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerstandardwidgetfactory_p.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERSTANDARDWIDGETFACTORY_P_H +#define QSCRIPTDEBUGGERSTANDARDWIDGETFACTORY_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobject.h> + +#include "qscriptdebuggerwidgetfactoryinterface_p.h" + +QT_BEGIN_NAMESPACE + +class Q_AUTOTEST_EXPORT QScriptDebuggerStandardWidgetFactory + : public QObject, public QScriptDebuggerWidgetFactoryInterface +{ +public: + QScriptDebuggerStandardWidgetFactory(QObject *parent = 0); + virtual ~QScriptDebuggerStandardWidgetFactory(); + + QScriptDebugOutputWidgetInterface *createDebugOutputWidget(); + QScriptDebuggerConsoleWidgetInterface *createConsoleWidget(); + QScriptErrorLogWidgetInterface *createErrorLogWidget(); + QScriptDebuggerCodeFinderWidgetInterface *createCodeFinderWidget(); + QScriptDebuggerStackWidgetInterface *createStackWidget(); + QScriptDebuggerScriptsWidgetInterface *createScriptsWidget(); + QScriptDebuggerLocalsWidgetInterface *createLocalsWidget(); + QScriptDebuggerCodeWidgetInterface *createCodeWidget(); + QScriptBreakpointsWidgetInterface *createBreakpointsWidget(); + +private: + Q_DISABLE_COPY(QScriptDebuggerStandardWidgetFactory) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggervalueproperty.cpp b/src/scripttools/debugging/qscriptdebuggervalueproperty.cpp index a6fb08c..79322fb 100644 --- a/src/scripttools/debugging/qscriptdebuggervalueproperty.cpp +++ b/src/scripttools/debugging/qscriptdebuggervalueproperty.cpp @@ -41,6 +41,7 @@ #include "qscriptdebuggervalueproperty_p.h" #include "qscriptdebuggervalue_p.h" +#include "qscriptdebuggerobjectsnapshotdelta_p.h" #include <QtCore/qatomic.h> #include <QtCore/qdatastream.h> @@ -225,4 +226,20 @@ QDataStream &operator>>(QDataStream &in, QScriptDebuggerValueProperty &property) return in; } +QDataStream &operator<<(QDataStream &out, const QScriptDebuggerObjectSnapshotDelta &delta) +{ + out << delta.removedProperties; + out << delta.changedProperties; + out << delta.addedProperties; + return out; +} + +QDataStream &operator>>(QDataStream &in, QScriptDebuggerObjectSnapshotDelta &delta) +{ + in >> delta.removedProperties; + in >> delta.changedProperties; + in >> delta.addedProperties; + return in; +} + QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggerwidgetfactoryinterface_p.h b/src/scripttools/debugging/qscriptdebuggerwidgetfactoryinterface_p.h index 66fadfb..0eda1ca 100644 --- a/src/scripttools/debugging/qscriptdebuggerwidgetfactoryinterface_p.h +++ b/src/scripttools/debugging/qscriptdebuggerwidgetfactoryinterface_p.h @@ -61,6 +61,11 @@ class QScriptDebugOutputWidgetInterface; class QScriptDebuggerConsoleWidgetInterface; class QScriptErrorLogWidgetInterface; class QScriptDebuggerCodeFinderWidgetInterface; +class QScriptDebuggerStackWidgetInterface; +class QScriptDebuggerScriptsWidgetInterface; +class QScriptDebuggerLocalsWidgetInterface; +class QScriptDebuggerCodeWidgetInterface; +class QScriptBreakpointsWidgetInterface; class Q_AUTOTEST_EXPORT QScriptDebuggerWidgetFactoryInterface { @@ -71,6 +76,11 @@ public: virtual QScriptDebuggerConsoleWidgetInterface *createConsoleWidget() = 0; virtual QScriptErrorLogWidgetInterface *createErrorLogWidget() = 0; virtual QScriptDebuggerCodeFinderWidgetInterface *createCodeFinderWidget() = 0; + virtual QScriptDebuggerStackWidgetInterface *createStackWidget() = 0; + virtual QScriptDebuggerScriptsWidgetInterface *createScriptsWidget() = 0; + virtual QScriptDebuggerLocalsWidgetInterface *createLocalsWidget() = 0; + virtual QScriptDebuggerCodeWidgetInterface *createCodeWidget() = 0; + virtual QScriptBreakpointsWidgetInterface *createBreakpointsWidget() = 0; }; QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptenginedebugger.cpp b/src/scripttools/debugging/qscriptenginedebugger.cpp index f04123e..948a01a 100644 --- a/src/scripttools/debugging/qscriptenginedebugger.cpp +++ b/src/scripttools/debugging/qscriptenginedebugger.cpp @@ -42,25 +42,14 @@ #include "qscriptenginedebugger.h" #include "qscriptdebugger_p.h" #include "qscriptenginedebuggerfrontend_p.h" -#include "qscriptdebuggerconsolewidget_p.h" -#include "qscriptdebuggerstackwidget_p.h" -#include "qscriptdebuggerscriptswidget_p.h" -#include "qscriptdebuggerlocalswidget_p.h" -#include "qscriptdebuggercodewidget_p.h" -#include "qscriptdebuggercodefinderwidget_p.h" -#include "qscriptbreakpointswidget_p.h" -#include "qscriptdebugoutputwidget_p.h" -#include "qscripterrorlogwidget_p.h" -#include "qscriptdebuggerwidgetfactoryinterface_p.h" +#include "qscriptdebuggerstandardwidgetfactory_p.h" #include <private/qobject_p.h> #include <QtCore/qsettings.h> #include <QtGui/qapplication.h> #include <QtGui/qdockwidget.h> #include <QtGui/qmainwindow.h> -#include <QtGui/qmenu.h> #include <QtGui/qmenubar.h> -#include <QtGui/qtoolbar.h> #include <QtGui/qboxlayout.h> // this has to be outside the namespace @@ -238,19 +227,13 @@ public: */ class QScriptEngineDebuggerPrivate - : public QObjectPrivate, - public QScriptDebuggerWidgetFactoryInterface + : public QObjectPrivate { Q_DECLARE_PUBLIC(QScriptEngineDebugger) public: QScriptEngineDebuggerPrivate(); ~QScriptEngineDebuggerPrivate(); - QScriptDebugOutputWidgetInterface *createDebugOutputWidget(); - QScriptDebuggerConsoleWidgetInterface *createConsoleWidget(); - QScriptErrorLogWidgetInterface *createErrorLogWidget(); - QScriptDebuggerCodeFinderWidgetInterface *createCodeFinderWidget(); - // private slots void _q_showStandardWindow(); @@ -320,26 +303,6 @@ QScriptEngineDebuggerPrivate::~QScriptEngineDebuggerPrivate() } } -QScriptDebugOutputWidgetInterface *QScriptEngineDebuggerPrivate::createDebugOutputWidget() -{ - return new QScriptDebugOutputWidget(); -} - -QScriptDebuggerConsoleWidgetInterface *QScriptEngineDebuggerPrivate::createConsoleWidget() -{ - return new QScriptDebuggerConsoleWidget(); -} - -QScriptErrorLogWidgetInterface *QScriptEngineDebuggerPrivate::createErrorLogWidget() -{ - return new QScriptErrorLogWidget(); -} - -QScriptDebuggerCodeFinderWidgetInterface *QScriptEngineDebuggerPrivate::createCodeFinderWidget() -{ - return new QScriptDebuggerCodeFinderWidget(); -} - void QScriptEngineDebuggerPrivate::_q_showStandardWindow() { Q_Q(QScriptEngineDebugger); @@ -352,7 +315,7 @@ void QScriptEngineDebuggerPrivate::createDebugger() Q_Q(QScriptEngineDebugger); if (!debugger) { debugger = new QScriptDebugger(); - debugger->setWidgetFactory(this); + debugger->setWidgetFactory(new QScriptDebuggerStandardWidgetFactory(q)); QObject::connect(debugger, SIGNAL(started()), q, SIGNAL(evaluationResumed())); QObject::connect(debugger, SIGNAL(stopped()), @@ -447,81 +410,7 @@ QWidget *QScriptEngineDebugger::widget(DebuggerWidget widget) const { Q_D(const QScriptEngineDebugger); const_cast<QScriptEngineDebuggerPrivate*>(d)->createDebugger(); - switch (widget) { - case ConsoleWidget: { - QScriptDebuggerConsoleWidgetInterface *w = d->debugger->consoleWidget(); - if (!w) { - w = new QScriptDebuggerConsoleWidget(); - d->debugger->setConsoleWidget(w); - } - return w; - } - case StackWidget: { - QScriptDebuggerStackWidgetInterface *w = d->debugger->stackWidget(); - if (!w) { - w = new QScriptDebuggerStackWidget(); - d->debugger->setStackWidget(w); - } - return w; - } - case ScriptsWidget: { - QScriptDebuggerScriptsWidgetInterface *w = d->debugger->scriptsWidget(); - if (!w) { - w = new QScriptDebuggerScriptsWidget(); - d->debugger->setScriptsWidget(w); - } - return w; - } - case LocalsWidget: { - QScriptDebuggerLocalsWidgetInterface *w = d->debugger->localsWidget(); - if (!w) { - w = new QScriptDebuggerLocalsWidget(); - d->debugger->setLocalsWidget(w); - } - return w; - } - case CodeWidget: { - QScriptDebuggerCodeWidgetInterface *w = d->debugger->codeWidget(); - if (!w) { - w = new QScriptDebuggerCodeWidget(); - d->debugger->setCodeWidget(w); - } - return w; - } - case CodeFinderWidget: { - QScriptDebuggerCodeFinderWidgetInterface *w = d->debugger->codeFinderWidget(); - if (!w) { - w = new QScriptDebuggerCodeFinderWidget(); - d->debugger->setCodeFinderWidget(w); - } - return w; - } - case BreakpointsWidget: { - QScriptBreakpointsWidgetInterface *w = d->debugger->breakpointsWidget(); - if (!w) { - w = new QScriptBreakpointsWidget(); - d->debugger->setBreakpointsWidget(w); - } - return w; - } - case DebugOutputWidget: { - QScriptDebugOutputWidgetInterface *w = d->debugger->debugOutputWidget(); - if (!w) { - w = new QScriptDebugOutputWidget(); - d->debugger->setDebugOutputWidget(w); - } - return w; - } - case ErrorLogWidget: { - QScriptErrorLogWidgetInterface *w = d->debugger->errorLogWidget(); - if (!w) { - w = new QScriptErrorLogWidget(); - d->debugger->setErrorLogWidget(w); - } - return w; - } - } - return 0; + return d->debugger->widget(static_cast<QScriptDebugger::DebuggerWidget>(static_cast<int>(widget))); } /*! @@ -545,39 +434,7 @@ QAction *QScriptEngineDebugger::action(DebuggerAction action) const Q_D(const QScriptEngineDebugger); QScriptEngineDebugger *that = const_cast<QScriptEngineDebugger*>(this); that->d_func()->createDebugger(); - switch (action) { - case InterruptAction: - return d->debugger->interruptAction(that); - case ContinueAction: - return d->debugger->continueAction(that); - case StepIntoAction: - return d->debugger->stepIntoAction(that); - case StepOverAction: - return d->debugger->stepOverAction(that); - case StepOutAction: - return d->debugger->stepOutAction(that); - case RunToCursorAction: - return d->debugger->runToCursorAction(that); - case RunToNewScriptAction: - return d->debugger->runToNewScriptAction(that); - case ToggleBreakpointAction: - return d->debugger->toggleBreakpointAction(that); - case ClearDebugOutputAction: - return d->debugger->clearDebugOutputAction(that); - case ClearErrorLogAction: - return d->debugger->clearErrorLogAction(that); - case ClearConsoleAction: - return d->debugger->clearConsoleAction(that); - case FindInScriptAction: - return d->debugger->findInScriptAction(that); - case FindNextInScriptAction: - return d->debugger->findNextInScriptAction(that); - case FindPreviousInScriptAction: - return d->debugger->findPreviousInScriptAction(that); - case GoToLineAction: - return d->debugger->goToLineAction(that); - } - return 0; + return d->debugger->action(static_cast<QScriptDebugger::DebuggerAction>(static_cast<int>(action)), that); } /*! @@ -730,25 +587,9 @@ QMainWindow *QScriptEngineDebugger::standardWindow() const */ QMenu *QScriptEngineDebugger::createStandardMenu(QWidget *parent) { - QMenu *menu = new QMenu(parent); - menu->setTitle(QObject::tr("Debug")); - menu->addAction(action(ContinueAction)); - menu->addAction(action(InterruptAction)); - menu->addAction(action(StepIntoAction)); - menu->addAction(action(StepOverAction)); - menu->addAction(action(StepOutAction)); - menu->addAction(action(RunToCursorAction)); - menu->addAction(action(RunToNewScriptAction)); - - menu->addSeparator(); - menu->addAction(action(ToggleBreakpointAction)); - - menu->addSeparator(); - menu->addAction(action(ClearDebugOutputAction)); - menu->addAction(action(ClearErrorLogAction)); - menu->addAction(action(ClearConsoleAction)); - - return menu; + Q_D(QScriptEngineDebugger); + d->createDebugger(); + return d->debugger->createStandardMenu(parent, this); } /*! @@ -759,18 +600,9 @@ QMenu *QScriptEngineDebugger::createStandardMenu(QWidget *parent) */ QToolBar *QScriptEngineDebugger::createStandardToolBar(QWidget *parent) { - QToolBar *tb = new QToolBar(parent); - tb->setObjectName(QLatin1String("qtscriptdebugger_standardToolBar")); - tb->addAction(action(ContinueAction)); - tb->addAction(action(InterruptAction)); - tb->addAction(action(StepIntoAction)); - tb->addAction(action(StepOverAction)); - tb->addAction(action(StepOutAction)); - tb->addAction(action(RunToCursorAction)); - tb->addAction(action(RunToNewScriptAction)); - tb->addSeparator(); - tb->addAction(action(FindInScriptAction)); - return tb; + Q_D(QScriptEngineDebugger); + d->createDebugger(); + return d->debugger->createStandardToolBar(parent, this); } /*! diff --git a/src/scripttools/debugging/qscripttooltipproviderinterface_p.h b/src/scripttools/debugging/qscripttooltipproviderinterface_p.h index 0622dcf..749795e 100644 --- a/src/scripttools/debugging/qscripttooltipproviderinterface_p.h +++ b/src/scripttools/debugging/qscripttooltipproviderinterface_p.h @@ -57,6 +57,7 @@ QT_BEGIN_NAMESPACE +class QPoint; class QStringList; class Q_AUTOTEST_EXPORT QScriptToolTipProviderInterface @@ -64,8 +65,8 @@ class Q_AUTOTEST_EXPORT QScriptToolTipProviderInterface public: virtual ~QScriptToolTipProviderInterface() {} - virtual QString toolTip(int frameIndex, int lineNumber, - const QStringList &path) = 0; + virtual void showToolTip(const QPoint &pos, int frameIndex, + int lineNumber, const QStringList &path) = 0; }; QT_END_NAMESPACE |