From acfa79cb4021c7afd4986ce061cacf550c9f803e Mon Sep 17 00:00:00 2001 From: Fabien Freling Date: Thu, 4 Feb 2010 10:35:35 +0100 Subject: Update QTestLib documentation with chart use case. --- doc/src/images/container_bench.png | Bin 0 -> 71461 bytes examples/qtestlib/tutorial5/containers.cpp | 269 +++++++++++++++++++++++++++++ 2 files changed, 269 insertions(+) create mode 100644 doc/src/images/container_bench.png create mode 100644 examples/qtestlib/tutorial5/containers.cpp diff --git a/doc/src/images/container_bench.png b/doc/src/images/container_bench.png new file mode 100644 index 0000000..a707b1a Binary files /dev/null and b/doc/src/images/container_bench.png differ diff --git a/examples/qtestlib/tutorial5/containers.cpp b/examples/qtestlib/tutorial5/containers.cpp new file mode 100644 index 0000000..fe68c85 --- /dev/null +++ b/examples/qtestlib/tutorial5/containers.cpp @@ -0,0 +1,269 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite 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 Technology Preview License Agreement accompanying +** this package. +** +** 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.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +// This file contains benchmarks for comparing QVector against std::vector + +#include +#include +#include + +#include + +template // T is the item type +class UseCases { +public: + virtual ~UseCases() {} + + // Use case: Insert \a size items into the vector. + virtual void insert(int size) = 0; + + // Use case: Lookup \a size items from the vector. + virtual void lookup(int size) = 0; +}; + +template +T * f(T *ts) // dummy function to prevent code from being optimized away by the compiler +{ + return ts; +} + +// This subclass implements the use cases using QVector as efficiently as possible. +template +class UseCases_QVector : public UseCases +{ + void insert(int size) + { + QVector v; + T t; + QBENCHMARK { + for (int i = 0; i < size; ++i) + v.append(t); + } + } + + void lookup(int size) + { + QVector v; + + T t; + for (int i = 0; i < size; ++i) + v.append(t); + + T *ts = new T[size]; + QBENCHMARK { + for (int i = 0; i < size; ++i) + ts[i] = v.value(i); + } + f(ts); + delete[] ts; + } +}; + +// This subclass implements the use cases using std::vector as efficiently as possible. +template +class UseCases_stdvector : public UseCases +{ + void insert(int size) + { + std::vector v; + T t; + QBENCHMARK { + for (int i = 0; i < size; ++i) + v.push_back(t); + } + } + + void lookup(int size) + { + std::vector v; + + T t; + for (int i = 0; i < size; ++i) + v.push_back(t); + + T *ts = new T[size]; + QBENCHMARK { + for (int i = 0; i < size; ++i) + ts[i] = v[i]; + } + f(ts); + delete[] ts; + } +}; + +struct Large { // A "large" item type + int x[1000]; +}; + +// Symbian devices typically have limited memory +#ifdef Q_OS_SYMBIAN +# define LARGE_MAX_SIZE 2000 +#else +# define LARGE_MAX_SIZE 20000 +#endif + +class tst_vector_vs_std : public QObject +{ + Q_OBJECT +public: + tst_vector_vs_std() + { + useCases_QVector_int = new UseCases_QVector; + useCases_stdvector_int = new UseCases_stdvector; + + useCases_QVector_Large = new UseCases_QVector; + useCases_stdvector_Large = new UseCases_stdvector; + } + +private: + UseCases *useCases_QVector_int; + UseCases *useCases_stdvector_int; + UseCases *useCases_QVector_Large; + UseCases *useCases_stdvector_Large; + +private slots: + void insert_int_data(); + void insert_int(); + void insert_Large_data(); + void insert_Large(); + void lookup_int_data(); + void lookup_int(); + void lookup_Large_data(); + void lookup_Large(); +}; + +void tst_vector_vs_std::insert_int_data() +{ + QTest::addColumn("useStd"); + QTest::addColumn("size"); + + for (int size = 10; size < 20000; size += 100) { + const QByteArray sizeString = QByteArray::number(size); + QTest::newRow(("std::vector-int--" + sizeString).constData()) << true << size; + QTest::newRow(("QVector-int--" + sizeString).constData()) << false << size; + } +} + +void tst_vector_vs_std::insert_int() +{ + QFETCH(bool, useStd); + QFETCH(int, size); + + if (useStd) + useCases_stdvector_int->insert(size); + else + useCases_QVector_int->insert(size); +} + +void tst_vector_vs_std::insert_Large_data() +{ + QTest::addColumn("useStd"); + QTest::addColumn("size"); + + for (int size = 10; size < LARGE_MAX_SIZE; size += 100) { + const QByteArray sizeString = QByteArray::number(size); + QTest::newRow(("std::vector-Large--" + sizeString).constData()) << true << size; + QTest::newRow(("QVector-Large--" + sizeString).constData()) << false << size; + } +} + +void tst_vector_vs_std::insert_Large() +{ + QFETCH(bool, useStd); + QFETCH(int, size); + + if (useStd) + useCases_stdvector_Large->insert(size); + else + useCases_QVector_Large->insert(size); +} + +//! [1] +void tst_vector_vs_std::lookup_int_data() +{ + QTest::addColumn("useStd"); + QTest::addColumn("size"); + + for (int size = 10; size < 20000; size += 100) { + const QByteArray sizeString = QByteArray::number(size); + QTest::newRow(("std::vector-int--" + sizeString).constData()) << true << size; + QTest::newRow(("QVector-int--" + sizeString).constData()) << false << size; + } +} +//! [1] + +//! [2] +void tst_vector_vs_std::lookup_int() +{ + QFETCH(bool, useStd); + QFETCH(int, size); + + if (useStd) + useCases_stdvector_int->lookup(size); // Create a std::vector and run the benchmark. + else + useCases_QVector_int->lookup(size); // Create a QVector and run the benchmark. +} +//! [2] + +void tst_vector_vs_std::lookup_Large_data() +{ + QTest::addColumn("useStd"); + QTest::addColumn("size"); + + for (int size = 10; size < LARGE_MAX_SIZE; size += 100) { + const QByteArray sizeString = QByteArray::number(size); + QTest::newRow(("std::vector-Large--" + sizeString).constData()) << true << size; + QTest::newRow(("QVector-Large--" + sizeString).constData()) << false << size; + } +} + +void tst_vector_vs_std::lookup_Large() +{ + QFETCH(bool, useStd); + QFETCH(int, size); + + if (useStd) + useCases_stdvector_Large->lookup(size); + else + useCases_QVector_Large->lookup(size); +} + +QTEST_MAIN(tst_vector_vs_std) +#include "main.moc" -- cgit v0.12 From 8ba14f6640a836a42a67363259da7055b33385b9 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 4 Feb 2010 11:46:13 +0100 Subject: qdoc3: Removed a debug output. --- tools/qdoc3/node.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/qdoc3/node.cpp b/tools/qdoc3/node.cpp index 4da916c..9357671 100644 --- a/tools/qdoc3/node.cpp +++ b/tools/qdoc3/node.cpp @@ -570,8 +570,6 @@ void InnerNode::addChild(Node *child) else { if (child->type() == Enum) enumChildren.append(child); - if (childMap.contains(child->name())) - qDebug() << "Duplicate child" << child->name(); childMap.insert(child->name(), child); } } -- cgit v0.12 From 818ef4e93f40f2c3c6cf9d2a0a1fc42150f0d0cd Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 4 Feb 2010 12:21:24 +0100 Subject: Cocoa: Tool Windows steal focus from the main window The example that shows this off is tools/inputpanel. This example is strangely written, and calls activateWindow on the main window in an activate callback to another window. So a bit recursion will happend, and this caused troubble for the cocoa port. In addition, in Qt several windows can be active at the same time, expecially tool windows. This means that we need to be careful when returning early from the becomeKeyWindow methods for NSWindow. This patch fixes up on this stuff. Task-number: QTBUG-6002 Reviewed-by: msorvig --- src/gui/kernel/qcocoasharedwindowmethods_mac_p.h | 3 ++- src/gui/kernel/qcocoawindowdelegate_mac.mm | 7 ------- src/gui/kernel/qwidget_mac.mm | 2 +- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h index 2117551..d8bbcd4 100644 --- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h +++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h @@ -95,7 +95,8 @@ QT_END_NAMESPACE bool isToolTip = (widget->windowType() == Qt::ToolTip); bool isPopup = (widget->windowType() == Qt::Popup); - return !(isPopup || isToolTip); + bool isTool = (widget->windowType() == Qt::Tool); + return !(isPopup || isToolTip || isTool); } - (void)orderWindow:(NSWindowOrderingMode)orderingMode relativeTo:(NSInteger)otherWindowNumber diff --git a/src/gui/kernel/qcocoawindowdelegate_mac.mm b/src/gui/kernel/qcocoawindowdelegate_mac.mm index db87491..24498f8 100644 --- a/src/gui/kernel/qcocoawindowdelegate_mac.mm +++ b/src/gui/kernel/qcocoawindowdelegate_mac.mm @@ -269,9 +269,6 @@ static void cleanupCocoaWindowDelegate() { QWidget *qwidget = m_windowHash->value([notification object]); Q_ASSERT(qwidget); - if (qwidget->isActiveWindow()) - return; // Widget is already active, no need to go through re-activation. - onApplicationWindowChangedActivation(qwidget, true); } @@ -288,10 +285,6 @@ static void cleanupCocoaWindowDelegate() { QWidget *qwidget = m_windowHash->value([notification object]); Q_ASSERT(qwidget); - if (qwidget->isActiveWindow()) - return; // Widget is already active, no need to go through re-activation - - onApplicationWindowChangedActivation(qwidget, true); } diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 43b945e..878b776 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -3233,10 +3233,10 @@ void QWidget::activateWindow() || windowActive) { #ifndef QT_MAC_USE_COCOA ActivateWindow(win, true); + qApp->setActiveWindow(tlw); #else [win makeKeyWindow]; #endif - qApp->setActiveWindow(tlw); } else if(!isMinimized()) { #ifndef QT_MAC_USE_COCOA SelectWindow(win); -- cgit v0.12 From 1ef9b16f76b3ec2e8e12911777387a723185e518 Mon Sep 17 00:00:00 2001 From: Jocelyn Turcotte Date: Thu, 4 Feb 2010 11:18:47 +0100 Subject: Add the QMAKE_FILE_EXT variable to extra compilers generation. This give the possibility to get the file name with the extension and without the path. Reviewed-by: Joao Reviewed-by: Marius Storm-Olsen --- qmake/generators/makefile.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 0f5bdcd..cb68e7c 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -1519,6 +1519,19 @@ MakefileGenerator::replaceExtraCompilerVariables(const QString &orig_var, const base = fi.fileName(); val += base; } + } else if(var == QLatin1String("QMAKE_FILE_EXT")) { + filePath = true; + for(int i = 0; i < in.size(); ++i) { + QFileInfo fi(fileInfo(Option::fixPathToLocalOS(in.at(i)))); + QString ext; + // Ensure complementarity with QMAKE_FILE_BASE + int baseLen = fi.completeBaseName().length(); + if(baseLen == 0) + ext = fi.fileName(); + else + ext = fi.fileName().remove(0, baseLen); + val += ext; + } } else if(var == QLatin1String("QMAKE_FILE_PATH") || var == QLatin1String("QMAKE_FILE_IN_PATH")) { filePath = true; for(int i = 0; i < in.size(); ++i) -- cgit v0.12 From 3d10c27c7674663028941d41af9ab845dbf31d86 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 4 Feb 2010 13:44:08 +0100 Subject: doc: Fixed some qdoc warnings. --- src/corelib/io/qdatastream.cpp | 1 + src/corelib/tools/qbytearray.cpp | 2 +- src/testlib/qbenchmarkmetric.cpp | 28 ++++++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp index 27f7632..7c1887e 100644 --- a/src/corelib/io/qdatastream.cpp +++ b/src/corelib/io/qdatastream.cpp @@ -571,6 +571,7 @@ void QDataStream::setByteOrder(ByteOrder bo) \value Qt_4_4 Version 10 (Qt 4.4) \value Qt_4_5 Version 11 (Qt 4.5) \value Qt_4_6 Version 12 (Qt 4.6) + \value Qt_4_7 Same as Qt_4_6. \sa setVersion(), version() */ diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 6c87a86..a27e488 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -1061,7 +1061,7 @@ QByteArray &QByteArray::operator=(const char *str) \internal */ -/*! \fn bool QByteArray::isSharedWith(const QByteArray &other) +/*! \fn bool QByteArray::isSharedWith(const QByteArray &other) const \internal */ diff --git a/src/testlib/qbenchmarkmetric.cpp b/src/testlib/qbenchmarkmetric.cpp index 75297c4..7356134 100644 --- a/src/testlib/qbenchmarkmetric.cpp +++ b/src/testlib/qbenchmarkmetric.cpp @@ -41,6 +41,29 @@ #include +/*! + \enum QTest::QBenchmarkMetric + \since 4.7 + + This enum lists all the things that can be benchmarked. + + \value FramesPerSecond Frames per second + \value BitsPerSecond Bits per second + \value BytesPerSecond Bytes per second + \value WalltimeMilliseconds Clock time in milliseconds + \value CPUTicks CPU time + \value InstructionReads Instruction reads + \value Events Event count + + \sa QTest::benchmarkMetricName(), QTest::benchmarkMetricUnit() + + */ + +/*! + \relates QTest + \since 4.7 + Returns the enum value \a metric as a character string. + */ const char * QTest::benchmarkMetricName(QBenchmarkMetric metric) { switch (metric) { @@ -63,6 +86,11 @@ const char * QTest::benchmarkMetricName(QBenchmarkMetric metric) } }; +/*! + \relates QTest + \since 4.7 + Retuns the units of measure for the specified \a metric. + */ const char * QTest::benchmarkMetricUnit(QBenchmarkMetric metric) { switch (metric) { -- cgit v0.12 From af7d2b2127dadbdf828c60c75255bb1b4f591651 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Thu, 4 Feb 2010 14:24:30 +0100 Subject: Always activate popup windows on show The problem was that popups that were opened from a system tray icon did not get activated and clicking outside would not close the popup as intended. Ensuring that all popups get activated on show should solve this problem in the general sense. Task-number: QTBUG-7386 Reviewed-by: denis --- src/gui/kernel/qwidget_win.cpp | 2 ++ src/gui/util/qsystemtrayicon_win.cpp | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp index a57aacc..6a36293 100644 --- a/src/gui/kernel/qwidget_win.cpp +++ b/src/gui/kernel/qwidget_win.cpp @@ -1156,6 +1156,8 @@ void QWidgetPrivate::show_sys() data.window_state |= Qt::WindowMinimized; if (IsZoomed(q->internalWinId())) data.window_state |= Qt::WindowMaximized; + if (q->windowType() == Qt::Popup) + q->activateWindow(); } winSetupGestures(); diff --git a/src/gui/util/qsystemtrayicon_win.cpp b/src/gui/util/qsystemtrayicon_win.cpp index 092909f..8e482e0 100644 --- a/src/gui/util/qsystemtrayicon_win.cpp +++ b/src/gui/util/qsystemtrayicon_win.cpp @@ -325,8 +325,6 @@ bool QSystemTrayIconSys::winEvent( MSG *m, long *result ) q->contextMenu()->move(gpos); } #endif - q->contextMenu()->activateWindow(); - //Must be activated for proper keyboardfocus and menu closing on windows: } emit q->activated(QSystemTrayIcon::Context); break; -- cgit v0.12 From e39feabbcdb10b47c7eaad14fe653e62280e6237 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 4 Feb 2010 15:00:37 +0100 Subject: doc: Fixed some qdoc warnings. --- src/corelib/kernel/qcoreevent.cpp | 1 - src/gui/image/qpixmap.cpp | 9 +++++---- src/network/access/qnetworkreply.cpp | 9 +++++++++ src/network/access/qnetworkrequest.cpp | 17 ++++++++++++++--- src/opengl/qgl.cpp | 14 ++++++++------ 5 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp index d177b26..16b8798 100644 --- a/src/corelib/kernel/qcoreevent.cpp +++ b/src/corelib/kernel/qcoreevent.cpp @@ -272,7 +272,6 @@ QT_BEGIN_NAMESPACE \omitvalue MacGLClearDrawable \omitvalue NetworkReplyUpdated \omitvalue FutureCallOut - \omitvalue CocoaRequestModal \omitvalue UpdateSoftKeys \omitvalue NativeGesture */ diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index fe03c93..e51d858 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -1379,10 +1379,11 @@ void QPixmap::deref() */ /*! - Replaces this pixmap's data with the given \a image using the specified - \a flags to control the conversion. The \a flags argument is a - bitwise-OR of the \l{Qt::ImageConversionFlags}. Passing 0 for \a - flags sets all the default options. + Replaces this pixmap's data with the given \a image using the + specified \a flags to control the conversion. The \a flags + argument is a bitwise-OR of the \l{Qt::ImageConversionFlags}. + Passing 0 for \a flags sets all the default options. Returns true + if the result is that this pixmap is not null. Note: this function was part of Qt 3 support in Qt 4.6 and earlier. It has been promoted to official API status in 4.7 to support updating diff --git a/src/network/access/qnetworkreply.cpp b/src/network/access/qnetworkreply.cpp index be4339c..15748fe 100644 --- a/src/network/access/qnetworkreply.cpp +++ b/src/network/access/qnetworkreply.cpp @@ -533,6 +533,15 @@ QByteArray QNetworkReply::rawHeader(const QByteArray &headerName) const return QByteArray(); } +/*! \typedef QNetworkReply::RawHeaderPair + + RawHeaderPair is a QPair where the first + QByteArray is the header name and the second is the header. + */ + +/*! + Returns a list of raw header pairs. + */ const QList& QNetworkReply::rawHeaderPairs() const { Q_D(const QNetworkReply); diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index 52b88a3..b8438a2 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -532,13 +532,24 @@ QNetworkRequest::Priority QNetworkRequest::priority() const return d->priority; } +/*! \enum QNetworkRequest::Priority + + \since 4.7 + + This enum lists the possible network request priorities. + + \value HighPriority High priority + \value NormalPriority Normal priority + \value LowPriority Low priority + */ + /*! \since 4.7 - Set the priority of this request. + Set the priority of this request to \a priority. - \note The priority is only a hint to the network access manager. - It can use it or not. Currently it is used for HTTP to + \note The \a priority is only a hint to the network access + manager. It can use it or not. Currently it is used for HTTP to decide which request should be sent first to a server. \sa priority() diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index bb76f1a..97b1c2f 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1085,8 +1085,9 @@ int QGLFormat::stencilBufferSize() const /*! \since 4.7 - Set the OpenGL version. If a context compatible with the requested OpenGL version - cannot be created, a context compatible with version 1.x is created instead. + Set the OpenGL version to the \a major and \a minor numbers. If a + context compatible with the requested OpenGL version cannot be + created, a context compatible with version 1.x is created instead. \sa majorVersion(), minorVersion() */ @@ -1129,8 +1130,9 @@ int QGLFormat::minorVersion() const \enum QGLFormat::OpenGLContextProfile \since 4.7 - This enum describes the OpenGL context profiles that can be specified for contexts implementing - OpenGL version 3.2 or higher. These profiles are different from OpenGL ES profiles. + This enum describes the OpenGL context profiles that can be + specified for contexts implementing OpenGL version 3.2 or + higher. These profiles are different from OpenGL ES profiles. \value NoProfile OpenGL version is lower than 3.2. \value CoreProfile Functionality deprecated in OpenGL version 3.0 is not available. @@ -1140,8 +1142,8 @@ int QGLFormat::minorVersion() const /*! \since 4.7 - Set the OpenGL context profile. The profile is ignored if the requested OpenGL - version is less than 3.2. + Set the OpenGL context profile to \a profile. The \a profile is + ignored if the requested OpenGL version is less than 3.2. \sa profile() */ -- cgit v0.12 From 17ba81e9587f3202363b42f6662a2866506e9247 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 4 Feb 2010 15:40:29 +0100 Subject: Fix QtScript debugger hang/crash issue with updating locals model Since the model is updated lazily, it's possible that a new model has been set on the view (and the old model deleted) before the old model has finished refreshing. This was discovered while holding down the F11 key (Step Into) when debugging plasma.js in the script/context2d example, which causes many events (and hence asynchronous model updates) to trigger rapidly. --- .../debugging/qscriptdebuggerlocalsmodel.cpp | 55 ++++++++++++++++------ .../debugging/qscriptdebuggerlocalswidget.cpp | 5 +- 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/src/scripttools/debugging/qscriptdebuggerlocalsmodel.cpp b/src/scripttools/debugging/qscriptdebuggerlocalsmodel.cpp index 068de42..ec6230b 100644 --- a/src/scripttools/debugging/qscriptdebuggerlocalsmodel.cpp +++ b/src/scripttools/debugging/qscriptdebuggerlocalsmodel.cpp @@ -54,6 +54,7 @@ #include #include +#include #include #include @@ -370,6 +371,7 @@ public: { if (!m_index.isValid()) { // nothing to do, the node has been removed + finish(); return; } QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); @@ -475,7 +477,7 @@ namespace { class InitModelJob : public QScriptDebuggerCommandSchedulerJob { public: - InitModelJob(QScriptDebuggerLocalsModelPrivate *model, + InitModelJob(QScriptDebuggerLocalsModel *model, int frameIndex, QScriptDebuggerCommandSchedulerInterface *scheduler) : QScriptDebuggerCommandSchedulerJob(scheduler), @@ -484,6 +486,11 @@ public: void start() { + if (!m_model) { + // Model has been deleted. + finish(); + return; + } QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); frontend.scheduleGetScopeChain(m_frameIndex); } @@ -491,7 +498,13 @@ public: void handleResponse(const QScriptDebuggerResponse &response, int) { + if (!m_model) { + // Model has been deleted. + finish(); + return; + } QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + QScriptDebuggerLocalsModelPrivate *model_d = QScriptDebuggerLocalsModelPrivate::get(m_model); switch (m_state) { case 0: { QScriptDebuggerValueList scopeChain = response.resultAsScriptValueList(); @@ -500,23 +513,23 @@ public: QString name = QString::fromLatin1("Scope"); if (i > 0) name.append(QString::fromLatin1(" (%0)").arg(i)); - QModelIndex index = m_model->addTopLevelObject(name, scopeObject); + QModelIndex index = model_d->addTopLevelObject(name, scopeObject); if (i == 0) - m_model->emitScopeObjectAvailable(index); + model_d->emitScopeObjectAvailable(index); } frontend.scheduleGetThisObject(m_frameIndex); ++m_state; } break; case 1: { QScriptDebuggerValue thisObject = response.resultAsScriptValue(); - m_model->addTopLevelObject(QLatin1String("this"), thisObject); + model_d->addTopLevelObject(QLatin1String("this"), thisObject); finish(); } break; } } private: - QScriptDebuggerLocalsModelPrivate *m_model; + QPointer m_model; int m_frameIndex; int m_state; }; @@ -527,7 +540,7 @@ void QScriptDebuggerLocalsModel::init(int frameIndex) { Q_D(QScriptDebuggerLocalsModel); d->frameIndex = frameIndex; - QScriptDebuggerJob *job = new InitModelJob(d, frameIndex, d->commandScheduler); + QScriptDebuggerJob *job = new InitModelJob(this, frameIndex, d->commandScheduler); d->jobScheduler->scheduleJob(job); } @@ -536,7 +549,7 @@ namespace { class SyncModelJob : public QScriptDebuggerCommandSchedulerJob { public: - SyncModelJob(QScriptDebuggerLocalsModelPrivate *model, + SyncModelJob(QScriptDebuggerLocalsModel *model, int frameIndex, QScriptDebuggerCommandSchedulerInterface *scheduler) : QScriptDebuggerCommandSchedulerJob(scheduler), @@ -545,6 +558,11 @@ public: void start() { + if (!m_model) { + // Model has been deleted. + finish(); + return; + } QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); frontend.scheduleGetScopeChain(m_frameIndex); } @@ -552,6 +570,11 @@ public: void handleResponse(const QScriptDebuggerResponse &response, int) { + if (!m_model) { + // Model has been deleted. + finish(); + return; + } QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); switch (m_state) { case 0: { @@ -561,18 +584,19 @@ public: ++m_state; } break; case 1: { + QScriptDebuggerLocalsModelPrivate *model_d = QScriptDebuggerLocalsModelPrivate::get(m_model); QScriptDebuggerValue thisObject = response.resultAsScriptValue(); m_topLevelObjects.append(thisObject); - bool equal = (m_topLevelObjects.size() == m_model->invisibleRootNode->children.size()); + bool equal = (m_topLevelObjects.size() == model_d->invisibleRootNode->children.size()); for (int i = 0; equal && (i < m_topLevelObjects.size()); ++i) { const QScriptDebuggerValue &object = m_topLevelObjects.at(i); - equal = (object == m_model->invisibleRootNode->children.at(i)->property.value()); + equal = (object == model_d->invisibleRootNode->children.at(i)->property.value()); } if (!equal) { // the scope chain and/or this-object changed, so invalidate the model. // we could try to be more clever, i.e. figure out // exactly which objects were popped/pushed - m_model->removeTopLevelNodes(); + model_d->removeTopLevelNodes(); for (int j = 0; j < m_topLevelObjects.size(); ++j) { const QScriptDebuggerValue &object = m_topLevelObjects.at(j); QString name; @@ -583,12 +607,12 @@ public: if (j > 0) name.append(QString::fromLatin1(" (%0)").arg(j)); } - QModelIndex index = m_model->addTopLevelObject(name, object); + QModelIndex index = model_d->addTopLevelObject(name, object); if (j == 0) - m_model->emitScopeObjectAvailable(index); + model_d->emitScopeObjectAvailable(index); } } else { - m_model->syncTopLevelNodes(); + model_d->syncTopLevelNodes(); } finish(); } break; @@ -596,7 +620,7 @@ public: } private: - QScriptDebuggerLocalsModelPrivate *m_model; + QPointer m_model; int m_frameIndex; int m_state; QScriptDebuggerValueList m_topLevelObjects; @@ -608,7 +632,7 @@ void QScriptDebuggerLocalsModel::sync(int frameIndex) { Q_D(QScriptDebuggerLocalsModel); d->frameIndex = frameIndex; - QScriptDebuggerJob *job = new SyncModelJob(d, frameIndex, d->commandScheduler); + QScriptDebuggerJob *job = new SyncModelJob(this, frameIndex, d->commandScheduler); d->jobScheduler->scheduleJob(job); } @@ -636,6 +660,7 @@ public: { if (!m_index.isValid()) { // nothing to do, the node has been removed + finish(); return; } QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); diff --git a/src/scripttools/debugging/qscriptdebuggerlocalswidget.cpp b/src/scripttools/debugging/qscriptdebuggerlocalswidget.cpp index 516a200..bbced5f 100644 --- a/src/scripttools/debugging/qscriptdebuggerlocalswidget.cpp +++ b/src/scripttools/debugging/qscriptdebuggerlocalswidget.cpp @@ -70,6 +70,8 @@ public: bool hasChildren(const QModelIndex &parent) const { + if (!sourceModel()) + return false; QModelIndex sourceParent = mapToSource(parent); if (parent.isValid() && !sourceParent.isValid()) return false; @@ -184,7 +186,8 @@ void QScriptDebuggerLocalsWidgetPrivate::_q_insertCompletion(const QString &text void QScriptDebuggerLocalsWidgetPrivate::_q_expandIndex(const QModelIndex &index) { - view->expand(proxy->mapFromSource(index)); + if (view->model() == index.model()) + view->expand(proxy->mapFromSource(index)); } class QScriptDebuggerLocalsItemDelegate -- cgit v0.12 From 5762a988fbcd95c9c44e58993c25f5cd1d53f897 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 4 Feb 2010 16:08:47 +0100 Subject: Use a shared QScriptEngine for debugger console command scripts A single engine was used for each script (i.e. command), which was just ridiculous. Use one engine with multiple global objects to isolate each script's state. Task-number: QTBUG-7227 --- .../debugging/qscriptdebuggerconsole.cpp | 221 ++++++++++++++++++- .../qscriptdebuggerscriptedconsolecommand.cpp | 237 +-------------------- .../qscriptdebuggerscriptedconsolecommand_p.h | 4 +- 3 files changed, 233 insertions(+), 229 deletions(-) diff --git a/src/scripttools/debugging/qscriptdebuggerconsole.cpp b/src/scripttools/debugging/qscriptdebuggerconsole.cpp index 7fd80f0..2f7a998 100644 --- a/src/scripttools/debugging/qscriptdebuggerconsole.cpp +++ b/src/scripttools/debugging/qscriptdebuggerconsole.cpp @@ -44,16 +44,216 @@ #include "qscriptdebuggerconsolecommandmanager_p.h" #include "qscriptdebuggerscriptedconsolecommand_p.h" #include "qscriptmessagehandlerinterface_p.h" +#include "qscriptbreakpointdata_p.h" +#include "qscriptdebuggerresponse_p.h" +#include "qscriptdebuggervalueproperty_p.h" +#include "qscriptscriptdata_p.h" #include #include #include #include #include +#include #include +Q_DECLARE_METATYPE(QScriptDebuggerResponse) +Q_DECLARE_METATYPE(QScriptBreakpointData) +Q_DECLARE_METATYPE(QScriptBreakpointMap) +Q_DECLARE_METATYPE(QScriptScriptData) +Q_DECLARE_METATYPE(QScriptScriptMap) +Q_DECLARE_METATYPE(QScriptContextInfo) +Q_DECLARE_METATYPE(QScriptDebuggerValue) +Q_DECLARE_METATYPE(QScriptDebuggerValueProperty) +Q_DECLARE_METATYPE(QScriptDebuggerValuePropertyList) +Q_DECLARE_METATYPE(QScriptDebuggerConsoleCommand*) +Q_DECLARE_METATYPE(QScriptDebuggerConsoleCommandList) +Q_DECLARE_METATYPE(QScriptDebuggerConsoleCommandGroupData) +Q_DECLARE_METATYPE(QScriptDebuggerConsoleCommandGroupMap) + QT_BEGIN_NAMESPACE +static QScriptValue debuggerResponseToScriptValue(QScriptEngine *eng, const QScriptDebuggerResponse &in) +{ + QScriptValue out = eng->newObject(); + out.setProperty(QString::fromLatin1("result"), qScriptValueFromValue(eng, in.result())); + out.setProperty(QString::fromLatin1("error"), QScriptValue(eng, in.error())); + out.setProperty(QString::fromLatin1("async"), QScriptValue(eng, in.async())); + return out; +} + +static void debuggerResponseFromScriptValue(const QScriptValue &, QScriptDebuggerResponse &) +{ + Q_ASSERT(0); +} + +static QScriptValue breakpointDataToScriptValue(QScriptEngine *eng, const QScriptBreakpointData &in) +{ + QScriptValue out = eng->newObject(); + out.setProperty(QString::fromLatin1("scriptId"), QScriptValue(eng, qsreal(in.scriptId()))); + out.setProperty(QString::fromLatin1("fileName"), QScriptValue(eng, in.fileName())); + out.setProperty(QString::fromLatin1("lineNumber"), QScriptValue(eng, in.lineNumber())); + out.setProperty(QString::fromLatin1("enabled"), QScriptValue(eng, in.isEnabled())); + out.setProperty(QString::fromLatin1("singleShot"), QScriptValue(eng, in.isSingleShot())); + out.setProperty(QString::fromLatin1("ignoreCount"), QScriptValue(eng, in.ignoreCount())); + out.setProperty(QString::fromLatin1("condition"), QScriptValue(eng, in.condition())); + return out; +} + +static void breakpointDataFromScriptValue(const QScriptValue &in, QScriptBreakpointData &out) +{ + QScriptValue scriptId = in.property(QString::fromLatin1("scriptId")); + if (scriptId.isValid()) + out.setScriptId((qint64)scriptId.toNumber()); + out.setFileName(in.property(QString::fromLatin1("fileName")).toString()); + out.setLineNumber(in.property(QString::fromLatin1("lineNumber")).toInt32()); + QScriptValue enabled = in.property(QString::fromLatin1("enabled")); + if (enabled.isValid()) + out.setEnabled(enabled.toBoolean()); + QScriptValue singleShot = in.property(QString::fromLatin1("singleShot")); + if (singleShot.isValid()) + out.setSingleShot(singleShot.toBoolean()); + out.setIgnoreCount(in.property(QString::fromLatin1("ignoreCount")).toInt32()); + out.setCondition(in.property(QString::fromLatin1("condition")).toString()); +} + +static QScriptValue breakpointMapToScriptValue(QScriptEngine *eng, const QScriptBreakpointMap &in) +{ + QScriptValue out = eng->newObject(); + QScriptBreakpointMap::const_iterator it; + for (it = in.constBegin(); it != in.constEnd(); ++it) { + out.setProperty(QString::number(it.key()), qScriptValueFromValue(eng, it.value())); + } + return out; +} + +static void breakpointMapFromScriptValue(const QScriptValue &, QScriptBreakpointMap &) +{ + Q_ASSERT(0); +} + +static QScriptValue scriptDataToScriptValue(QScriptEngine *eng, const QScriptScriptData &in) +{ + QScriptValue out = eng->newObject(); + out.setProperty(QString::fromLatin1("contents"), QScriptValue(eng, in.contents())); + out.setProperty(QString::fromLatin1("fileName"), QScriptValue(eng, in.fileName())); + out.setProperty(QString::fromLatin1("baseLineNumber"), QScriptValue(eng, in.baseLineNumber())); + return out; +} + +static void scriptDataFromScriptValue(const QScriptValue &in, QScriptScriptData &out) +{ + QString contents = in.property(QString::fromLatin1("contents")).toString(); + QString fileName = in.property(QString::fromLatin1("fileName")).toString(); + int baseLineNumber = in.property(QString::fromLatin1("baseLineNumber")).toInt32(); + QScriptScriptData tmp(contents, fileName, baseLineNumber); + out = tmp; +} + +static QScriptValue scriptMapToScriptValue(QScriptEngine *eng, const QScriptScriptMap &in) +{ + QScriptValue out = eng->newObject(); + QScriptScriptMap::const_iterator it; + for (it = in.constBegin(); it != in.constEnd(); ++it) { + out.setProperty(QString::number(it.key()), qScriptValueFromValue(eng, it.value())); + } + return out; +} + +static void scriptMapFromScriptValue(const QScriptValue &, QScriptScriptMap &) +{ + Q_ASSERT(0); +} + +static QScriptValue consoleCommandToScriptValue( + QScriptEngine *eng, QScriptDebuggerConsoleCommand* const &in) +{ + if (!in) + return eng->undefinedValue(); + QScriptValue out = eng->newObject(); + out.setProperty(QString::fromLatin1("name"), QScriptValue(eng, in->name())); + out.setProperty(QString::fromLatin1("group"), QScriptValue(eng, in->group())); + out.setProperty(QString::fromLatin1("shortDescription"), QScriptValue(eng, in->shortDescription())); + out.setProperty(QString::fromLatin1("longDescription"), QScriptValue(eng, in->longDescription())); + out.setProperty(QString::fromLatin1("aliases"), qScriptValueFromValue(eng, in->aliases())); + out.setProperty(QString::fromLatin1("seeAlso"), qScriptValueFromValue(eng, in->seeAlso())); + return out; +} + +static void consoleCommandFromScriptValue( + const QScriptValue &, QScriptDebuggerConsoleCommand* &) +{ + Q_ASSERT(0); +} + +static QScriptValue consoleCommandGroupDataToScriptValue( + QScriptEngine *eng, const QScriptDebuggerConsoleCommandGroupData &in) +{ + QScriptValue out = eng->newObject(); + out.setProperty(QString::fromLatin1("longDescription"), QScriptValue(eng, in.longDescription())); + out.setProperty(QString::fromLatin1("shortDescription"), QScriptValue(eng, in.shortDescription())); + return out; +} + +static void consoleCommandGroupDataFromScriptValue( + const QScriptValue &, QScriptDebuggerConsoleCommandGroupData &) +{ + Q_ASSERT(0); +} + +static QScriptValue consoleCommandGroupMapToScriptValue( + QScriptEngine *eng, const QScriptDebuggerConsoleCommandGroupMap &in) +{ + QScriptValue out = eng->newObject(); + QScriptDebuggerConsoleCommandGroupMap::const_iterator it; + for (it = in.constBegin(); it != in.constEnd(); ++it) { + out.setProperty(it.key(), qScriptValueFromValue(eng, it.value())); + } + return out; +} + +static void consoleCommandGroupMapFromScriptValue( + const QScriptValue &, QScriptDebuggerConsoleCommandGroupMap &) +{ + Q_ASSERT(0); +} + +static QScriptValue contextInfoToScriptValue(QScriptEngine *eng, const QScriptContextInfo &in) +{ + QScriptValue out = eng->newObject(); + out.setProperty(QString::fromLatin1("scriptId"), QScriptValue(eng, qsreal(in.scriptId()))); + out.setProperty(QString::fromLatin1("fileName"), QScriptValue(eng, in.fileName())); + out.setProperty(QString::fromLatin1("lineNumber"), QScriptValue(eng, in.lineNumber())); + out.setProperty(QString::fromLatin1("columnNumber"), QScriptValue(eng, in.columnNumber())); + out.setProperty(QString::fromLatin1("functionName"), QScriptValue(eng, in.functionName())); + return out; +} + +static void contextInfoFromScriptValue(const QScriptValue &, QScriptContextInfo &) +{ + Q_ASSERT(0); +} + +static QScriptValue debuggerScriptValuePropertyToScriptValue(QScriptEngine *eng, const QScriptDebuggerValueProperty &in) +{ + QScriptValue out = eng->newObject(); + out.setProperty(QString::fromLatin1("name"), QScriptValue(eng, in.name())); + out.setProperty(QString::fromLatin1("value"), qScriptValueFromValue(eng, in.value())); + out.setProperty(QString::fromLatin1("valueAsString"), QScriptValue(eng, in.valueAsString())); + out.setProperty(QString::fromLatin1("flags"), QScriptValue(eng, static_cast(in.flags()))); + return out; +} + +static void debuggerScriptValuePropertyFromScriptValue(const QScriptValue &in, QScriptDebuggerValueProperty &out) +{ + QString name = in.property(QString::fromLatin1("name")).toString(); + QScriptDebuggerValue value = qscriptvalue_cast(in.property(QString::fromLatin1("value"))); + QString valueAsString = in.property(QString::fromLatin1("valueAsString")).toString(); + int flags = in.property(QString::fromLatin1("flags")).toInt32(); + QScriptDebuggerValueProperty tmp(name, value, valueAsString, QScriptValue::PropertyFlags(flags)); + out = tmp; +} + /*! \since 4.5 \class QScriptDebuggerConsole @@ -76,6 +276,7 @@ public: QScriptMessageHandlerInterface *messageHandler, QScriptDebuggerCommandSchedulerInterface *commandScheduler); + QScriptEngine *commandEngine; QScriptDebuggerConsoleCommandManager *commandManager; QString commandPrefix; QString input; @@ -99,11 +300,29 @@ QScriptDebuggerConsolePrivate::QScriptDebuggerConsolePrivate(QScriptDebuggerCons evaluateAction = 0; commandPrefix = QLatin1String("."); commandManager = new QScriptDebuggerConsoleCommandManager(); + + commandEngine = new QScriptEngine; + qScriptRegisterMetaType(commandEngine, breakpointDataToScriptValue, breakpointDataFromScriptValue); + qScriptRegisterMetaType(commandEngine, breakpointMapToScriptValue, breakpointMapFromScriptValue); + qScriptRegisterMetaType(commandEngine, scriptDataToScriptValue, scriptDataFromScriptValue); + qScriptRegisterMetaType(commandEngine, scriptMapToScriptValue, scriptMapFromScriptValue); + qScriptRegisterMetaType(commandEngine, contextInfoToScriptValue, contextInfoFromScriptValue); + qScriptRegisterMetaType(commandEngine, debuggerScriptValuePropertyToScriptValue, debuggerScriptValuePropertyFromScriptValue); + qScriptRegisterSequenceMetaType(commandEngine); + qScriptRegisterMetaType(commandEngine, debuggerResponseToScriptValue, debuggerResponseFromScriptValue); + qScriptRegisterMetaType(commandEngine, consoleCommandToScriptValue, consoleCommandFromScriptValue); + qScriptRegisterSequenceMetaType(commandEngine); + qScriptRegisterMetaType(commandEngine, consoleCommandGroupDataToScriptValue, consoleCommandGroupDataFromScriptValue); + qScriptRegisterMetaType(commandEngine, consoleCommandGroupMapToScriptValue, consoleCommandGroupMapFromScriptValue); +// ### can't do this, if it's an object ID the conversion will be incorrect since +// ### the object ID refers to an object in a different engine! +// qScriptRegisterMetaType(commandEngine, debuggerScriptValueToScriptValue, debuggerScriptValueFromScriptValue); } QScriptDebuggerConsolePrivate::~QScriptDebuggerConsolePrivate() { delete commandManager; + delete commandEngine; } /*! @@ -126,7 +345,7 @@ void QScriptDebuggerConsolePrivate::loadScriptedCommands( QString program = stream.readAll(); QScriptDebuggerScriptedConsoleCommand *command; command = QScriptDebuggerScriptedConsoleCommand::parse( - program, fileName, messageHandler); + program, fileName, commandEngine, messageHandler); if (!command) continue; commandManager->addCommand(command); diff --git a/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand.cpp b/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand.cpp index 8d6a579..117c2d6 100644 --- a/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand.cpp +++ b/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand.cpp @@ -46,8 +46,6 @@ #include "qscriptmessagehandlerinterface_p.h" #include "qscriptdebuggerconsoleglobalobject_p.h" #include "qscriptdebuggerresponse_p.h" -#include "qscriptdebuggervalue_p.h" -#include "qscriptdebuggervalueproperty_p.h" #include "qscriptdebuggercommandschedulerinterface_p.h" #include @@ -59,202 +57,9 @@ #include Q_DECLARE_METATYPE(QScriptDebuggerResponse) -Q_DECLARE_METATYPE(QScriptBreakpointData) -Q_DECLARE_METATYPE(QScriptBreakpointMap) -Q_DECLARE_METATYPE(QScriptScriptData) -Q_DECLARE_METATYPE(QScriptScriptMap) -Q_DECLARE_METATYPE(QScriptContextInfo) -Q_DECLARE_METATYPE(QScriptDebuggerValue) -Q_DECLARE_METATYPE(QScriptDebuggerValueProperty) -Q_DECLARE_METATYPE(QScriptDebuggerValuePropertyList) -Q_DECLARE_METATYPE(QScriptDebuggerConsoleCommand*) -Q_DECLARE_METATYPE(QScriptDebuggerConsoleCommandList) -Q_DECLARE_METATYPE(QScriptDebuggerConsoleCommandGroupData) -Q_DECLARE_METATYPE(QScriptDebuggerConsoleCommandGroupMap) QT_BEGIN_NAMESPACE -static QScriptValue debuggerResponseToScriptValue(QScriptEngine *eng, const QScriptDebuggerResponse &in) -{ - QScriptValue out = eng->newObject(); - out.setProperty(QString::fromLatin1("result"), qScriptValueFromValue(eng, in.result())); - out.setProperty(QString::fromLatin1("error"), QScriptValue(eng, in.error())); - out.setProperty(QString::fromLatin1("async"), QScriptValue(eng, in.async())); - return out; -} - -static void debuggerResponseFromScriptValue(const QScriptValue &, QScriptDebuggerResponse &) -{ - Q_ASSERT(0); -} - -static QScriptValue breakpointDataToScriptValue(QScriptEngine *eng, const QScriptBreakpointData &in) -{ - QScriptValue out = eng->newObject(); - out.setProperty(QString::fromLatin1("scriptId"), QScriptValue(eng, qsreal(in.scriptId()))); - out.setProperty(QString::fromLatin1("fileName"), QScriptValue(eng, in.fileName())); - out.setProperty(QString::fromLatin1("lineNumber"), QScriptValue(eng, in.lineNumber())); - out.setProperty(QString::fromLatin1("enabled"), QScriptValue(eng, in.isEnabled())); - out.setProperty(QString::fromLatin1("singleShot"), QScriptValue(eng, in.isSingleShot())); - out.setProperty(QString::fromLatin1("ignoreCount"), QScriptValue(eng, in.ignoreCount())); - out.setProperty(QString::fromLatin1("condition"), QScriptValue(eng, in.condition())); - return out; -} - -static void breakpointDataFromScriptValue(const QScriptValue &in, QScriptBreakpointData &out) -{ - QScriptValue scriptId = in.property(QString::fromLatin1("scriptId")); - if (scriptId.isValid()) - out.setScriptId((qint64)scriptId.toNumber()); - out.setFileName(in.property(QString::fromLatin1("fileName")).toString()); - out.setLineNumber(in.property(QString::fromLatin1("lineNumber")).toInt32()); - QScriptValue enabled = in.property(QString::fromLatin1("enabled")); - if (enabled.isValid()) - out.setEnabled(enabled.toBoolean()); - QScriptValue singleShot = in.property(QString::fromLatin1("singleShot")); - if (singleShot.isValid()) - out.setSingleShot(singleShot.toBoolean()); - out.setIgnoreCount(in.property(QString::fromLatin1("ignoreCount")).toInt32()); - out.setCondition(in.property(QString::fromLatin1("condition")).toString()); -} - -static QScriptValue breakpointMapToScriptValue(QScriptEngine *eng, const QScriptBreakpointMap &in) -{ - QScriptValue out = eng->newObject(); - QScriptBreakpointMap::const_iterator it; - for (it = in.constBegin(); it != in.constEnd(); ++it) { - out.setProperty(QString::number(it.key()), qScriptValueFromValue(eng, it.value())); - } - return out; -} - -static void breakpointMapFromScriptValue(const QScriptValue &, QScriptBreakpointMap &) -{ - Q_ASSERT(0); -} - -static QScriptValue scriptDataToScriptValue(QScriptEngine *eng, const QScriptScriptData &in) -{ - QScriptValue out = eng->newObject(); - out.setProperty(QString::fromLatin1("contents"), QScriptValue(eng, in.contents())); - out.setProperty(QString::fromLatin1("fileName"), QScriptValue(eng, in.fileName())); - out.setProperty(QString::fromLatin1("baseLineNumber"), QScriptValue(eng, in.baseLineNumber())); - return out; -} - -static void scriptDataFromScriptValue(const QScriptValue &in, QScriptScriptData &out) -{ - QString contents = in.property(QString::fromLatin1("contents")).toString(); - QString fileName = in.property(QString::fromLatin1("fileName")).toString(); - int baseLineNumber = in.property(QString::fromLatin1("baseLineNumber")).toInt32(); - QScriptScriptData tmp(contents, fileName, baseLineNumber); - out = tmp; -} - -static QScriptValue scriptMapToScriptValue(QScriptEngine *eng, const QScriptScriptMap &in) -{ - QScriptValue out = eng->newObject(); - QScriptScriptMap::const_iterator it; - for (it = in.constBegin(); it != in.constEnd(); ++it) { - out.setProperty(QString::number(it.key()), qScriptValueFromValue(eng, it.value())); - } - return out; -} - -static void scriptMapFromScriptValue(const QScriptValue &, QScriptScriptMap &) -{ - Q_ASSERT(0); -} - -static QScriptValue consoleCommandToScriptValue( - QScriptEngine *eng, QScriptDebuggerConsoleCommand* const &in) -{ - if (!in) - return eng->undefinedValue(); - QScriptValue out = eng->newObject(); - out.setProperty(QString::fromLatin1("name"), QScriptValue(eng, in->name())); - out.setProperty(QString::fromLatin1("group"), QScriptValue(eng, in->group())); - out.setProperty(QString::fromLatin1("shortDescription"), QScriptValue(eng, in->shortDescription())); - out.setProperty(QString::fromLatin1("longDescription"), QScriptValue(eng, in->longDescription())); - out.setProperty(QString::fromLatin1("aliases"), qScriptValueFromValue(eng, in->aliases())); - out.setProperty(QString::fromLatin1("seeAlso"), qScriptValueFromValue(eng, in->seeAlso())); - return out; -} - -static void consoleCommandFromScriptValue( - const QScriptValue &, QScriptDebuggerConsoleCommand* &) -{ - Q_ASSERT(0); -} - -static QScriptValue consoleCommandGroupDataToScriptValue( - QScriptEngine *eng, const QScriptDebuggerConsoleCommandGroupData &in) -{ - QScriptValue out = eng->newObject(); - out.setProperty(QString::fromLatin1("longDescription"), QScriptValue(eng, in.longDescription())); - out.setProperty(QString::fromLatin1("shortDescription"), QScriptValue(eng, in.shortDescription())); - return out; -} - -static void consoleCommandGroupDataFromScriptValue( - const QScriptValue &, QScriptDebuggerConsoleCommandGroupData &) -{ - Q_ASSERT(0); -} - -static QScriptValue consoleCommandGroupMapToScriptValue( - QScriptEngine *eng, const QScriptDebuggerConsoleCommandGroupMap &in) -{ - QScriptValue out = eng->newObject(); - QScriptDebuggerConsoleCommandGroupMap::const_iterator it; - for (it = in.constBegin(); it != in.constEnd(); ++it) { - out.setProperty(it.key(), qScriptValueFromValue(eng, it.value())); - } - return out; -} - -static void consoleCommandGroupMapFromScriptValue( - const QScriptValue &, QScriptDebuggerConsoleCommandGroupMap &) -{ - Q_ASSERT(0); -} - -static QScriptValue contextInfoToScriptValue(QScriptEngine *eng, const QScriptContextInfo &in) -{ - QScriptValue out = eng->newObject(); - out.setProperty(QString::fromLatin1("scriptId"), QScriptValue(eng, qsreal(in.scriptId()))); - out.setProperty(QString::fromLatin1("fileName"), QScriptValue(eng, in.fileName())); - out.setProperty(QString::fromLatin1("lineNumber"), QScriptValue(eng, in.lineNumber())); - out.setProperty(QString::fromLatin1("columnNumber"), QScriptValue(eng, in.columnNumber())); - out.setProperty(QString::fromLatin1("functionName"), QScriptValue(eng, in.functionName())); - return out; -} - -static void contextInfoFromScriptValue(const QScriptValue &, QScriptContextInfo &) -{ - Q_ASSERT(0); -} - -static QScriptValue debuggerScriptValuePropertyToScriptValue(QScriptEngine *eng, const QScriptDebuggerValueProperty &in) -{ - QScriptValue out = eng->newObject(); - out.setProperty(QString::fromLatin1("name"), QScriptValue(eng, in.name())); - out.setProperty(QString::fromLatin1("value"), qScriptValueFromValue(eng, in.value())); - out.setProperty(QString::fromLatin1("valueAsString"), QScriptValue(eng, in.valueAsString())); - out.setProperty(QString::fromLatin1("flags"), QScriptValue(eng, static_cast(in.flags()))); - return out; -} - -static void debuggerScriptValuePropertyFromScriptValue(const QScriptValue &in, QScriptDebuggerValueProperty &out) -{ - QString name = in.property(QString::fromLatin1("name")).toString(); - QScriptDebuggerValue value = qscriptvalue_cast(in.property(QString::fromLatin1("value"))); - QString valueAsString = in.property(QString::fromLatin1("valueAsString")).toString(); - int flags = in.property(QString::fromLatin1("flags")).toInt32(); - QScriptDebuggerValueProperty tmp(name, value, valueAsString, QScriptValue::PropertyFlags(flags)); - out = tmp; -} - /*! \since 4.5 \class QScriptDebuggerScriptedConsoleCommand @@ -279,19 +84,17 @@ public: QStringList seeAlso; QStringList argumentTypes; QStringList subCommands; - QScriptEngine *engine; + QScriptValue globalObject; QScriptValue execFunction; QScriptValue responseFunction; }; QScriptDebuggerScriptedConsoleCommandPrivate::QScriptDebuggerScriptedConsoleCommandPrivate() { - engine = 0; } QScriptDebuggerScriptedConsoleCommandPrivate::~QScriptDebuggerScriptedConsoleCommandPrivate() { - delete engine; } QScriptDebuggerScriptedConsoleCommand::QScriptDebuggerScriptedConsoleCommand( @@ -299,6 +102,7 @@ QScriptDebuggerScriptedConsoleCommand::QScriptDebuggerScriptedConsoleCommand( const QString &shortDescription, const QString &longDescription, const QStringList &aliases, const QStringList &seeAlso, const QStringList &argumentTypes, const QStringList &subCommands, + const QScriptValue &globalObject, const QScriptValue &execFunction, const QScriptValue &responseFunction) : QScriptDebuggerConsoleCommand(*new QScriptDebuggerScriptedConsoleCommandPrivate) { @@ -311,25 +115,9 @@ QScriptDebuggerScriptedConsoleCommand::QScriptDebuggerScriptedConsoleCommand( d->seeAlso = seeAlso; d->argumentTypes = argumentTypes; d->subCommands = subCommands; + d->globalObject = globalObject; d->execFunction = execFunction; d->responseFunction = responseFunction; - d->engine = execFunction.engine(); - - qScriptRegisterMetaType(d->engine, breakpointDataToScriptValue, breakpointDataFromScriptValue); - qScriptRegisterMetaType(d->engine, breakpointMapToScriptValue, breakpointMapFromScriptValue); - qScriptRegisterMetaType(d->engine, scriptDataToScriptValue, scriptDataFromScriptValue); - qScriptRegisterMetaType(d->engine, scriptMapToScriptValue, scriptMapFromScriptValue); - qScriptRegisterMetaType(d->engine, contextInfoToScriptValue, contextInfoFromScriptValue); - qScriptRegisterMetaType(d->engine, debuggerScriptValuePropertyToScriptValue, debuggerScriptValuePropertyFromScriptValue); - qScriptRegisterSequenceMetaType(d->engine); - qScriptRegisterMetaType(d->engine, debuggerResponseToScriptValue, debuggerResponseFromScriptValue); - qScriptRegisterMetaType(d->engine, consoleCommandToScriptValue, consoleCommandFromScriptValue); - qScriptRegisterSequenceMetaType(d->engine); - qScriptRegisterMetaType(d->engine, consoleCommandGroupDataToScriptValue, consoleCommandGroupDataFromScriptValue); - qScriptRegisterMetaType(d->engine, consoleCommandGroupMapToScriptValue, consoleCommandGroupMapFromScriptValue); -// ### can't do this, if it's an object ID the conversion will be incorrect since -// ### the object ID refers to an object in a different engine! -// qScriptRegisterMetaType(d->engine, debuggerScriptValueToScriptValue, debuggerScriptValueFromScriptValue); } QScriptDebuggerScriptedConsoleCommand::~QScriptDebuggerScriptedConsoleCommand() @@ -405,7 +193,8 @@ int QScriptDebuggerScriptedConsoleCommandJob::scheduleCommand( void QScriptDebuggerScriptedConsoleCommandJob::start() { Q_D(QScriptDebuggerScriptedConsoleCommandJob); - QScriptEngine *engine = d->command->engine; + QScriptEngine *engine = d->command->globalObject.engine(); + engine->setGlobalObject(d->command->globalObject); QScriptValueList args; for (int i = 0; i < d->arguments.size(); ++i) args.append(QScriptValue(engine, d->arguments.at(i))); @@ -435,12 +224,13 @@ void QScriptDebuggerScriptedConsoleCommandJob::handleResponse( { Q_D(QScriptDebuggerScriptedConsoleCommandJob); // ### generalize - QScriptEngine *engine = d->command->engine; + QScriptEngine *engine = d->command->globalObject.engine(); + engine->setGlobalObject(d->command->globalObject); QScriptValueList args; args.append(qScriptValueFromValue(engine, response)); args.append(QScriptValue(engine, commandId)); QScriptDebuggerConsoleGlobalObject *global; - global = qobject_cast(engine->globalObject().toQObject()); + global = qobject_cast(d->command->globalObject.toQObject()); Q_ASSERT(global != 0); global->setScheduler(this); global->setResponseHandler(this); @@ -551,9 +341,8 @@ QScriptDebuggerConsoleCommandJob *QScriptDebuggerScriptedConsoleCommand::createJ */ QScriptDebuggerScriptedConsoleCommand *QScriptDebuggerScriptedConsoleCommand::parse( const QString &program, const QString &fileName, - QScriptMessageHandlerInterface *messageHandler) + QScriptEngine *engine, QScriptMessageHandlerInterface *messageHandler) { - QScriptEngine *engine = new QScriptEngine(); // create a custom global object QScriptDebuggerConsoleGlobalObject *cppGlobal = new QScriptDebuggerConsoleGlobalObject(); QScriptValue global = engine->newQObject(cppGlobal, @@ -574,14 +363,12 @@ QScriptDebuggerScriptedConsoleCommand *QScriptDebuggerScriptedConsoleCommand::pa if (engine->hasUncaughtException()) { messageHandler->message(QtCriticalMsg, ret.toString(), fileName, engine->uncaughtExceptionLineNumber()); - delete engine; return 0; } QScriptValue name = global.property(QLatin1String("name")); if (!name.isString()) { messageHandler->message(QtCriticalMsg, QLatin1String("command definition lacks a name"), fileName); - delete engine; return 0; } QString nameStr = name.toString(); @@ -590,7 +377,6 @@ QScriptDebuggerScriptedConsoleCommand *QScriptDebuggerScriptedConsoleCommand::pa if (!group.isString()) { messageHandler->message(QtCriticalMsg, QString::fromLatin1("definition of command \"%0\" lacks a group name") .arg(nameStr), fileName); - delete engine; return 0; } QString groupStr = group.toString(); @@ -599,7 +385,6 @@ QScriptDebuggerScriptedConsoleCommand *QScriptDebuggerScriptedConsoleCommand::pa if (!shortDesc.isString()) { messageHandler->message(QtCriticalMsg, QString::fromLatin1("definition of command \"%0\" lacks shortDescription") .arg(nameStr), fileName); - delete engine; return 0; } QString shortDescStr = shortDesc.toString(); @@ -608,7 +393,6 @@ QScriptDebuggerScriptedConsoleCommand *QScriptDebuggerScriptedConsoleCommand::pa if (!longDesc.isString()) { messageHandler->message(QtCriticalMsg, QString::fromLatin1("definition of command \"%0\" lacks longDescription") .arg(nameStr), fileName); - delete engine; return 0; } QString longDescStr = longDesc.toString(); @@ -629,7 +413,6 @@ QScriptDebuggerScriptedConsoleCommand *QScriptDebuggerScriptedConsoleCommand::pa if (!execFunction.isFunction()) { messageHandler->message(QtCriticalMsg, QString::fromLatin1("definition of command \"%0\" lacks execute() function") .arg(nameStr), fileName); - delete engine; return 0; } @@ -640,7 +423,7 @@ QScriptDebuggerScriptedConsoleCommand *QScriptDebuggerScriptedConsoleCommand::pa shortDescStr, longDescStr, aliases, seeAlso, argTypes, subCommands, - execFunction, responseFunction); + global, execFunction, responseFunction); return result; } diff --git a/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand_p.h b/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand_p.h index 1536de2..2b2b3f8 100644 --- a/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand_p.h +++ b/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand_p.h @@ -57,6 +57,7 @@ QT_BEGIN_NAMESPACE +class QScriptEngine; class QScriptValue; class QScriptDebuggerScriptedConsoleCommandPrivate; @@ -72,6 +73,7 @@ protected: const QStringList &seeAlso, const QStringList &argumentTypes, const QStringList &subCommands, + const QScriptValue &globalObject, const QScriptValue &execFunction, const QScriptValue &responseFunction); public: @@ -79,7 +81,7 @@ public: static QScriptDebuggerScriptedConsoleCommand *parse( const QString &program, const QString &fileName, - QScriptMessageHandlerInterface *messageHandler); + QScriptEngine *engine, QScriptMessageHandlerInterface *messageHandler); QString name() const; QString group() const; -- cgit v0.12