diff options
author | Liang Qi <liang.qi@theqtcompany.com> | 2015-09-06 10:39:42 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@theqtcompany.com> | 2015-09-06 10:39:51 +0200 |
commit | 68607aeeeb6ba84b843a0e3d848a5438a36f55a7 (patch) | |
tree | f7ff7ef369e079599d8be73f909498aeb6e75201 | |
parent | a719e348d22b1ce158a7b2be878965ac3a258914 (diff) | |
parent | 42f58e557034bb95005db465f078212cfc1b693a (diff) |
Merge remote-tracking branch 'origin/5.6' into dev
Change-Id: Id27c36e55fcc68cc1140b0d9bec00b8ae6b52ed0
54 files changed, 326 insertions, 118 deletions
diff --git a/examples/quick/demos/photosurface/photosurface.qml b/examples/quick/demos/photosurface/photosurface.qml index e5cfd827dc..22cef62157 100644 --- a/examples/quick/demos/photosurface/photosurface.qml +++ b/examples/quick/demos/photosurface/photosurface.qml @@ -37,7 +37,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -import QtQuick 2.5 +import QtQuick 2.6 import QtQuick.Dialogs 1.0 import QtQuick.Window 2.1 import Qt.labs.folderlistmodel 1.0 @@ -172,7 +172,7 @@ Window { height: flick.height * (flick.height / flick.contentHeight) - (width - anchors.margins) * 2 y: flick.contentY * (flick.height / flick.contentHeight) NumberAnimation on opacity { id: vfade; to: 0; duration: 500 } - onYChanged: { opacity = 1.0; fadeTimer.restart() } + onYChanged: { opacity = 1.0; scrollFadeTimer.restart() } } Rectangle { @@ -188,10 +188,10 @@ Window { width: flick.width * (flick.width / flick.contentWidth) - (height - anchors.margins) * 2 x: flick.contentX * (flick.width / flick.contentWidth) NumberAnimation on opacity { id: hfade; to: 0; duration: 500 } - onXChanged: { opacity = 1.0; fadeTimer.restart() } + onXChanged: { opacity = 1.0; scrollFadeTimer.restart() } } - Timer { id: fadeTimer; interval: 1000; onTriggered: { hfade.start(); vfade.start() } } + Timer { id: scrollFadeTimer; interval: 1000; onTriggered: { hfade.start(); vfade.start() } } Image { anchors.top: parent.top @@ -202,6 +202,42 @@ Window { anchors.fill: parent anchors.margins: -10 onClicked: fileDialog.open() + hoverEnabled: true + onPositionChanged: { + tooltip.visible = false + hoverTimer.start() + } + onExited: { + tooltip.visible = false + hoverTimer.stop() + } + Timer { + id: hoverTimer + interval: 1000 + onTriggered: { + tooltip.x = parent.mouseX + tooltip.y = parent.mouseY + tooltip.visible = true + } + } + Rectangle { + id: tooltip + border.color: "black" + color: "beige" + width: tooltipText.implicitWidth + 8 + height: tooltipText.implicitHeight + 8 + visible: false + Text { + id: tooltipText + anchors.centerIn: parent + text: "Open an image directory (" + openShortcut.sequenceString + ")" + } + } + } + Shortcut { + id: openShortcut + sequence: StandardKey.Open + onActivated: fileDialog.open() } } @@ -217,5 +253,7 @@ Window { "With a mouse: drag normally, use the vertical wheel to zoom, horizontal wheel to rotate, or hold Ctrl while using the vertical wheel to rotate" } + Shortcut { sequence: StandardKey.Quit; onActivated: Qt.quit() } + Component.onCompleted: fileDialog.open() } diff --git a/examples/quick/demos/samegame/samegame.pro b/examples/quick/demos/samegame/samegame.pro index 51e6f00321..e041dd61dd 100644 --- a/examples/quick/demos/samegame/samegame.pro +++ b/examples/quick/demos/samegame/samegame.pro @@ -7,4 +7,4 @@ RESOURCES += samegame.qrc target.path = $$[QT_INSTALL_EXAMPLES]/quick/demos/samegame INSTALLS += target -QTPLUGIN += qsqlite +!contains(sql-drivers, sqlite): QTPLUGIN += qsqlite diff --git a/examples/quick/touchinteraction/doc/src/touchinteraction.qdoc b/examples/quick/touchinteraction/doc/src/touchinteraction.qdoc index 760e14adca..e66d5c5654 100644 --- a/examples/quick/touchinteraction/doc/src/touchinteraction.qdoc +++ b/examples/quick/touchinteraction/doc/src/touchinteraction.qdoc @@ -36,7 +36,7 @@ \include examples-run.qdocinc - \section1 Multipoint Flames + \section1 Multipoint Flames Example \e{Multipoint Flames} demonstrates distinguishing different fingers in a \l MultiPointTouchArea, by assigning a different colored flame to each touch @@ -49,7 +49,7 @@ whether it is currently pressed, as follows: \snippet touchinteraction/multipointtouch/multiflame.qml 1 - \section1 Bear-Whack + \section1 Bear-Whack Example \e{Bear-Whack} demonstrates using \l MultiPointTouchArea to add multiple finger support to a simple game. The interaction with the game @@ -58,19 +58,19 @@ embedded into it: \snippet touchinteraction/multipointtouch/content/AugmentedTouchPoint.qml 0 - \section1 Flick Resize + \section1 Flick Resize Example \e{Flick Resize} uses a \l PinchArea to implement a \e{pinch-to-resize} behavior. This is easily achieved by listening to the PinchArea signals and responding to user input. \snippet touchinteraction/pincharea/flickresize.qml 0 - \section1 Flickable + \section1 Flickable Example \e Flickable is a simple example demonstrating the \l Flickable type. \snippet touchinteraction/flickable/basic-flickable.qml 0 - \section1 Corkboards + \section1 Corkboards Example \e Corkboards shows another use for \l Flickable, with QML types within the flickable object that respond to mouse and keyboard interaction. This diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp index 349c181d13..245900abae 100644 --- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp +++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp @@ -81,7 +81,7 @@ static void qQmlProfilerDataToByteArrays(const QQmlProfilerData *d, QList<QByteA ds << QQmlProfilerDefinitions::QmlBinding; break; case QQmlProfilerDefinitions::RangeData: - ds << d->detailString; + ds << (d->detailString.isEmpty() ? d->detailUrl.toString() : d->detailString); break; case QQmlProfilerDefinitions::RangeLocation: ds << (d->detailUrl.isEmpty() ? d->detailString : d->detailUrl.toString()) << d->x diff --git a/src/qml/debugger/qqmlprofiler_p.h b/src/qml/debugger/qqmlprofiler_p.h index 3c8337c969..7e29c3ede6 100644 --- a/src/qml/debugger/qqmlprofiler_p.h +++ b/src/qml/debugger/qqmlprofiler_p.h @@ -99,8 +99,9 @@ struct Q_AUTOTEST_EXPORT QQmlProfilerData int messageType; //bit field of QQmlProfilerService::Message int detailType; + // RangeData prefers detailString; RangeLocation prefers detailUrl. QString detailString; //used by RangeData and possibly by RangeLocation - QUrl detailUrl; //used by RangeLocation, overrides detailString + QUrl detailUrl; //used by RangeLocation and possibly by RangeData int x; //used by RangeLocation int y; //used by RangeLocation @@ -120,11 +121,11 @@ public: // Have toByteArrays() construct another RangeData event from the same QString later. // This is somewhat pointless but important for backwards compatibility. - void startCompiling(const QString &name) + void startCompiling(const QUrl &url) { m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(), (1 << RangeStart | 1 << RangeLocation | 1 << RangeData), - 1 << Compiling, name, 1, 1)); + 1 << Compiling, url, 1, 1)); } void startHandlingSignal(const QQmlSourceLocation &location) @@ -217,10 +218,10 @@ struct QQmlHandlingSignalProfiler : public QQmlProfilerHelper { }; struct QQmlCompilingProfiler : public QQmlProfilerHelper { - QQmlCompilingProfiler(QQmlProfiler *profiler, const QString &name) : + QQmlCompilingProfiler(QQmlProfiler *profiler, const QUrl &url) : QQmlProfilerHelper(profiler) { - Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCompiling, profiler, startCompiling(name)); + Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCompiling, profiler, startCompiling(url)); } ~QQmlCompilingProfiler() diff --git a/src/qml/doc/src/cppintegration/exposecppattributes.qdoc b/src/qml/doc/src/cppintegration/exposecppattributes.qdoc index e1db5c9d57..f4f688520a 100644 --- a/src/qml/doc/src/cppintegration/exposecppattributes.qdoc +++ b/src/qml/doc/src/cppintegration/exposecppattributes.qdoc @@ -328,11 +328,11 @@ public: : QObject(parent), m_author(new MessageAuthor(this)) { } - Message *author() const { + MessageAuthor *author() const { return m_author; } private: - Message *m_author; + MessageAuthor *m_author; }; \endcode diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp index 6d0c7cfdda..a49b98c921 100644 --- a/src/qml/jsapi/qjsvalue.cpp +++ b/src/qml/jsapi/qjsvalue.cpp @@ -212,6 +212,18 @@ QJSValue::QJSValue(const QJSValue& other) } /*! + \fn QJSValue::QJSValue(QJSValue && other) + + Move constructor. Moves from \a other into this QJSValue object. +*/ + +/*! + \fn QJSValue &operator=(QJSValue && other) + + Move-assigns \a other to this QJSValue object. +*/ + +/*! Destroys this QJSValue. */ QJSValue::~QJSValue() diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp index 39dce8efe0..2f6cf40beb 100644 --- a/src/qml/jsruntime/qv4argumentsobject.cpp +++ b/src/qml/jsruntime/qv4argumentsobject.cpp @@ -77,8 +77,8 @@ void ArgumentsObject::fullyCreate() if (fullyCreated()) return; - uint numAccessors = qMin((int)context()->function->formalParameterCount(), context()->callData->argc); uint argCount = context()->callData->argc; + uint numAccessors = qMin(context()->function->formalParameterCount(), argCount); ArrayData::realloc(this, Heap::ArrayData::Sparse, argCount, true); context()->engine->requireArgumentsAccessors(numAccessors); @@ -86,7 +86,7 @@ void ArgumentsObject::fullyCreate() Scoped<MemberData> md(scope, d()->mappedArguments); if (!md || md->size() < numAccessors) d()->mappedArguments = md->reallocate(engine(), d()->mappedArguments, numAccessors); - for (uint i = 0; i < (uint)numAccessors; ++i) { + for (uint i = 0; i < numAccessors; ++i) { mappedArguments()->data[i] = context()->callData->args[i]; arraySet(i, context()->engine->argumentsAccessors + i, Attr_Accessor); } diff --git a/src/qml/jsruntime/qv4memberdata.cpp b/src/qml/jsruntime/qv4memberdata.cpp index 5ec5cb1f58..20f8d9ec0f 100644 --- a/src/qml/jsruntime/qv4memberdata.cpp +++ b/src/qml/jsruntime/qv4memberdata.cpp @@ -46,20 +46,30 @@ void MemberData::markObjects(Heap::Base *that, ExecutionEngine *e) m->data[i].mark(e); } -Heap::MemberData *MemberData::reallocate(ExecutionEngine *e, Heap::MemberData *old, uint idx) +static Heap::MemberData *reallocateHelper(ExecutionEngine *e, Heap::MemberData *old, uint n) { - uint s = old ? old->size : 0; - if (idx < s) - return old; - - int newAlloc = qMax((uint)4, 2*idx); - uint alloc = sizeof(Heap::MemberData) + (newAlloc)*sizeof(Value); + uint alloc = sizeof(Heap::MemberData) + (n)*sizeof(Value); Scope scope(e); Scoped<MemberData> newMemberData(scope, e->memoryManager->allocManaged<MemberData>(alloc)); if (old) - memcpy(newMemberData->d(), old, sizeof(Heap::MemberData) + s*sizeof(Value)); + memcpy(newMemberData->d(), old, sizeof(Heap::MemberData) + old->size * sizeof(Value)); else new (newMemberData->d()) Heap::MemberData; - newMemberData->d()->size = newAlloc; + newMemberData->d()->size = n; return newMemberData->d(); } + +Heap::MemberData *MemberData::allocate(ExecutionEngine *e, uint n) +{ + return reallocateHelper(e, 0, n); +} + +Heap::MemberData *MemberData::reallocate(ExecutionEngine *e, Heap::MemberData *old, uint n) +{ + uint s = old ? old->size : 0; + if (n < s) + return old; + + // n is multiplied by two to leave room for growth + return reallocateHelper(e, old, qMax((uint)4, 2*n)); +} diff --git a/src/qml/jsruntime/qv4memberdata_p.h b/src/qml/jsruntime/qv4memberdata_p.h index 4c7cfa47cb..50b8ddb3d1 100644 --- a/src/qml/jsruntime/qv4memberdata_p.h +++ b/src/qml/jsruntime/qv4memberdata_p.h @@ -61,7 +61,8 @@ struct MemberData : Managed Value *data() { return d()->data; } inline uint size() const { return d()->size; } - static Heap::MemberData *reallocate(QV4::ExecutionEngine *e, Heap::MemberData *old, uint idx); + static Heap::MemberData *allocate(QV4::ExecutionEngine *e, uint n); + static Heap::MemberData *reallocate(QV4::ExecutionEngine *e, Heap::MemberData *old, uint n); static void markObjects(Heap::Base *that, ExecutionEngine *e); }; diff --git a/src/qml/jsruntime/qv4profiling.cpp b/src/qml/jsruntime/qv4profiling.cpp index 9b77599904..b62f367601 100644 --- a/src/qml/jsruntime/qv4profiling.cpp +++ b/src/qml/jsruntime/qv4profiling.cpp @@ -37,8 +37,8 @@ QT_BEGIN_NAMESPACE -using namespace QV4; -using namespace QV4::Profiling; +namespace QV4 { +namespace Profiling { FunctionCallProperties FunctionCall::resolve() const { @@ -63,26 +63,28 @@ Profiler::Profiler(QV4::ExecutionEngine *engine) : featuresEnabled(0), m_engine( m_timer.start(); } -struct FunctionCallComparator { - bool operator()(const FunctionCallProperties &p1, const FunctionCallProperties &p2) - { return p1.start < p2.start; } -}; - void Profiler::stopProfiling() { featuresEnabled = 0; reportData(); } +bool operator<(const FunctionCall &call1, const FunctionCall &call2) +{ + return call1.m_start < call2.m_start || + (call1.m_start == call2.m_start && (call1.m_end < call2.m_end || + (call1.m_end == call2.m_end && call1.m_function < call2.m_function))); +} + void Profiler::reportData() { + std::sort(m_data.begin(), m_data.end()); QVector<FunctionCallProperties> resolved; resolved.reserve(m_data.size()); - FunctionCallComparator comp; - foreach (const FunctionCall &call, m_data) { - FunctionCallProperties props = call.resolve(); - resolved.insert(std::upper_bound(resolved.begin(), resolved.end(), props, comp), props); - } + + foreach (const FunctionCall &call, m_data) + resolved.append(call.resolve()); + emit dataReady(resolved, m_memory_data); m_data.clear(); m_memory_data.clear(); @@ -111,4 +113,7 @@ void Profiler::startProfiling(quint64 features) } } +} // namespace Profiling +} // namespace QV4 + QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4profiling_p.h b/src/qml/jsruntime/qv4profiling_p.h index cc00af0193..505d393a3d 100644 --- a/src/qml/jsruntime/qv4profiling_p.h +++ b/src/qml/jsruntime/qv4profiling_p.h @@ -104,6 +104,7 @@ public: FunctionCallProperties resolve() const; private: + friend bool operator<(const FunctionCall &call1, const FunctionCall &call2); Function *m_function; qint64 m_start; diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 14b8b878bd..7067d10e22 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -104,18 +104,6 @@ Heap::QmlBindingWrapper::QmlBindingWrapper(QV4::ExecutionContext *scope, Functio internalClass->engine->popContext(); } -Heap::QmlBindingWrapper::QmlBindingWrapper(QV4::ExecutionContext *scope, QV4::QmlContextWrapper *qml) - : Heap::FunctionObject(scope, scope->d()->engine->id_eval(), /*createProto = */ false) -{ - Q_ASSERT(scope->inUse()); - - Scope s(scope); - Scoped<QV4::QmlBindingWrapper> protectThis(s, this); - - this->scope = scope->newQmlContext(qml); - internalClass->engine->popContext(); -} - ReturnedValue QmlBindingWrapper::call(const Managed *that, CallData *callData) { const QmlBindingWrapper *This = static_cast<const QmlBindingWrapper *>(that); @@ -152,8 +140,8 @@ Heap::FunctionObject *QmlBindingWrapper::createQmlCallableForFunction(QQmlContex QV4::Scope valueScope(engine); QV4::Scoped<QmlContextWrapper> qmlScopeObject(valueScope, QV4::QmlContextWrapper::qmlScope(engine, qmlContext, scopeObject)); ScopedContext global(valueScope, valueScope.engine->rootContext()); - QV4::Scoped<QV4::QmlBindingWrapper> wrapper(valueScope, engine->memoryManager->alloc<QV4::QmlBindingWrapper>(global, qmlScopeObject)); - QV4::Scoped<QmlContext> wrapperContext(valueScope, wrapper->context()); + QV4::Scoped<QmlContext> wrapperContext(valueScope, global->newQmlContext(qmlScopeObject)); + engine->popContext(); if (!signalParameters.isEmpty()) { if (error) diff --git a/src/qml/jsruntime/qv4script_p.h b/src/qml/jsruntime/qv4script_p.h index 22714496f8..fad011f88a 100644 --- a/src/qml/jsruntime/qv4script_p.h +++ b/src/qml/jsruntime/qv4script_p.h @@ -88,8 +88,6 @@ struct ContextStateSaver { namespace Heap { struct QmlBindingWrapper : Heap::FunctionObject { QmlBindingWrapper(QV4::ExecutionContext *scope, Function *f, QV4::QmlContextWrapper *qml); - // Constructor for QML functions and signal handlers, resulting binding wrapper is not callable! - QmlBindingWrapper(QV4::ExecutionContext *scope, QV4::QmlContextWrapper *qml); }; } @@ -99,8 +97,6 @@ struct Q_QML_EXPORT QmlBindingWrapper : FunctionObject { static ReturnedValue call(const Managed *that, CallData *callData); - Heap::QmlContext *context() const { return static_cast<Heap::QmlContext *>(d()->scope.ptr); } - static Heap::FunctionObject *createQmlCallableForFunction(QQmlContextData *qmlContext, QObject *scopeObject, QV4::Function *runtimeFunction, const QList<QByteArray> &signalParameters = QList<QByteArray>(), QString *error = 0); }; diff --git a/src/qml/qml/qqmlabstracturlinterceptor.cpp b/src/qml/qml/qqmlabstracturlinterceptor.cpp index cb57bc2146..dce41b0caa 100644 --- a/src/qml/qml/qqmlabstracturlinterceptor.cpp +++ b/src/qml/qml/qqmlabstracturlinterceptor.cpp @@ -82,3 +82,13 @@ Your implementation of this function must be thread-safe, as it can be called from multiple threads at the same time. */ +/*! + \fn QQmlAbstractUrlInterceptor::QQmlAbstractUrlInterceptor() + + Constructor for QQmlAbstractUrlInterceptor. +*/ +/*! + \fn QQmlAbstractUrlInterceptor::~QQmlAbstractUrlInterceptor() + + Destructor for QQmlAbstractUrlInterceptor. +*/ diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp index 1007029416..99a5fe56ce 100644 --- a/src/qml/qml/qqmlcontextwrapper.cpp +++ b/src/qml/qml/qqmlcontextwrapper.cpp @@ -100,23 +100,14 @@ ReturnedValue QmlContextWrapper::get(const Managed *m, String *name, bool *hasPr QV4::ExecutionEngine *v4 = resource->engine(); QV4::Scope scope(v4); - // In V8 the JS global object would come _before_ the QML global object, - // so simulate that here. - bool hasProp; - QV4::ScopedValue result(scope, v4->globalObject->get(name, &hasProp)); - if (hasProp) { - if (hasProperty) - *hasProperty = hasProp; - return result->asReturnedValue(); - } - if (resource->d()->isNullWrapper) return Object::get(m, name, hasProperty); if (v4->callingQmlContext() != resource->d()->context) return Object::get(m, name, hasProperty); - result = Object::get(m, name, &hasProp); + bool hasProp; + QV4::ScopedValue result(scope, Object::get(m, name, &hasProp)); if (hasProp) { if (hasProperty) *hasProperty = hasProp; diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 0b977f2551..b55973cdc8 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -120,7 +120,7 @@ void QQmlObjectCreator::init(QQmlContextData *providedParentContext) _ddata = 0; _propertyCache = 0; _vmeMetaObject = 0; - _qmlBindingWrapper = 0; + _qmlContext = 0; } QQmlObjectCreator::~QQmlObjectCreator() @@ -236,9 +236,9 @@ bool QQmlObjectCreator::populateDeferredProperties(QObject *instance) Q_ASSERT(!sharedState->allJavaScriptObjects); sharedState->allJavaScriptObjects = valueScope.alloc(compiledData->totalObjectCount); - QV4::Value *qmlBindingWrapper = valueScope.alloc(1); + QV4::QmlContext *qmlContext = static_cast<QV4::QmlContext *>(valueScope.alloc(1)); - qSwap(_qmlBindingWrapper, qmlBindingWrapper); + qSwap(_qmlContext, qmlContext); qSwap(_propertyCache, cache); qSwap(_qobject, instance); @@ -267,7 +267,7 @@ bool QQmlObjectCreator::populateDeferredProperties(QObject *instance) qSwap(_qobject, instance); qSwap(_propertyCache, cache); - qSwap(_qmlBindingWrapper, qmlBindingWrapper); + qSwap(_qmlContext, qmlContext); qSwap(_scopeObject, scopeObject); phase = ObjectsCreated; @@ -985,15 +985,16 @@ void QQmlObjectCreator::registerObjectWithContextById(int objectIndex, QObject * context->setIdProperty(idEntry.value(), instance); } -QV4::Heap::ExecutionContext *QQmlObjectCreator::currentQmlContext() +QV4::Heap::QmlContext *QQmlObjectCreator::currentQmlContext() { - if (!_qmlBindingWrapper->objectValue()) { + if (!_qmlContext->objectValue()) { QV4::Scope valueScope(v4); QV4::Scoped<QV4::QmlContextWrapper> qmlScope(valueScope, QV4::QmlContextWrapper::qmlScope(v4, context, _scopeObject)); QV4::ScopedContext global(valueScope, v4->rootContext()); - *_qmlBindingWrapper = v4->memoryManager->alloc<QV4::QmlBindingWrapper>(global, qmlScope); + _qmlContext->setM(global->newQmlContext(qmlScope)); + v4->popContext(); } - return static_cast<QV4::QmlBindingWrapper*>(_qmlBindingWrapper->objectValue())->context(); + return _qmlContext->d(); } QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isContextObject) @@ -1140,13 +1141,13 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo ++sharedState->allJavaScriptObjects; QV4::Scope valueScope(v4); - QV4::Value *qmlBindingWrapper = valueScope.alloc(1); + QV4::QmlContext *qmlContext = static_cast<QV4::QmlContext *>(valueScope.alloc(1)); - qSwap(_qmlBindingWrapper, qmlBindingWrapper); + qSwap(_qmlContext, qmlContext); bool result = populateInstance(index, instance, /*binding target*/instance, /*value type property*/0, bindingsToSkip); - qSwap(_qmlBindingWrapper, qmlBindingWrapper); + qSwap(_qmlContext, qmlContext); qSwap(_scopeObject, scopeObject); return result ? instance : 0; diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h index c88c15b525..433bbf5bf2 100644 --- a/src/qml/qml/qqmlobjectcreator_p.h +++ b/src/qml/qml/qqmlobjectcreator_p.h @@ -107,7 +107,7 @@ private: void registerObjectWithContextById(int objectIndex, QObject *instance) const; - QV4::Heap::ExecutionContext *currentQmlContext(); + QV4::Heap::QmlContext *currentQmlContext(); enum Phase { Startup, @@ -143,7 +143,7 @@ private: QQmlRefPointer<QQmlPropertyCache> _propertyCache; QQmlVMEMetaObject *_vmeMetaObject; QQmlListProperty<void> _currentList; - QV4::Value *_qmlBindingWrapper; + QV4::QmlContext *_qmlContext; friend struct QQmlObjectCreatorRecursionWatcher; }; diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 408f17ffde..eb65f732dd 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -647,6 +647,8 @@ void QQmlDataBlob::notifyComplete(QQmlDataBlob *blob) { Q_ASSERT(m_waitingFor.contains(blob)); Q_ASSERT(blob->status() == Error || blob->status() == Complete); + QQmlCompilingProfiler prof(QQmlEnginePrivate::get(typeLoader()->engine())->profiler, + blob->url()); m_inCallback = true; @@ -1194,6 +1196,8 @@ void QQmlTypeLoader::setData(QQmlDataBlob *blob, QQmlFile *file) void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QQmlDataBlob::Data &d) { QML_MEMORY_SCOPE_URL(blob->url()); + QQmlCompilingProfiler prof(QQmlEnginePrivate::get(engine())->profiler, blob->url()); + blob->m_inCallback = true; blob->dataReceived(d); @@ -1212,6 +1216,8 @@ void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QQmlDataBlob::Data &d) void QQmlTypeLoader::setCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit) { QML_MEMORY_SCOPE_URL(blob->url()); + QQmlCompilingProfiler prof(QQmlEnginePrivate::get(engine())->profiler, blob->url()); + blob->m_inCallback = true; blob->initializeFromCachedUnit(unit); @@ -2253,8 +2259,6 @@ void QQmlTypeData::compile() m_compiledData = new QQmlCompiledData(typeLoader()->engine()); - QQmlCompilingProfiler prof(QQmlEnginePrivate::get(typeLoader()->engine())->profiler, finalUrlString()); - QQmlTypeCompiler compiler(QQmlEnginePrivate::get(typeLoader()->engine()), m_compiledData, this, m_document.data()); if (!compiler.compile()) { setError(compiler.compilationErrors()); diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp index 6a71a07e9b..53b1ffccb5 100644 --- a/src/qml/qml/qqmlvaluetype.cpp +++ b/src/qml/qml/qqmlvaluetype.cpp @@ -82,7 +82,8 @@ bool QQmlValueTypeFactoryImpl::isValueType(int idx) && idx != QVariant::StringList && idx != QMetaType::QObjectStar && idx != QMetaType::VoidStar - && idx != QMetaType::QVariant) { + && idx != QMetaType::QVariant + && idx != QMetaType::QLocale) { return true; } diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 0ffeddbabc..4b19d1af04 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -1086,7 +1086,7 @@ void QQmlVMEMetaObject::allocateProperties() { Q_ASSERT(cache && cache->engine); QV4::ExecutionEngine *v4 = cache->engine; - QV4::Heap::MemberData *data = QV4::MemberData::reallocate(v4, 0, metaData->propertyCount); + QV4::Heap::MemberData *data = QV4::MemberData::allocate(v4, metaData->propertyCount); properties.set(v4, data); for (uint i = 0; i < data->size; ++i) data->data[i] = QV4::Encode::undefined(); diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index 0870e2b2c5..de7741675b 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -1358,7 +1358,11 @@ void QQmlXMLHttpRequest::error(QNetworkReply::NetworkError error) error == QNetworkReply::AuthenticationRequiredError || error == QNetworkReply::ContentReSendError || error == QNetworkReply::UnknownContentError || - error == QNetworkReply::ProtocolInvalidOperationError) { + error == QNetworkReply::ProtocolInvalidOperationError || + error == QNetworkReply::InternalServerError || + error == QNetworkReply::OperationNotImplementedError || + error == QNetworkReply::ServiceUnavailableError || + error == QNetworkReply::UnknownServerError) { m_state = Loading; dispatchCallback(); } else { diff --git a/src/qml/types/qqmlobjectmodel.cpp b/src/qml/types/qqmlobjectmodel.cpp index 0076c26950..4b64f24806 100644 --- a/src/qml/types/qqmlobjectmodel.cpp +++ b/src/qml/types/qqmlobjectmodel.cpp @@ -210,7 +210,7 @@ public: \inqmlmodule QtQuick \brief Defines a set of objects to be used as a model - The VisualItemModel type encapsulates contains the objects to be used + The VisualItemModel type contains the objects to be used as a model. This element is now primarily available as ObjectModel in the QtQml.Models module. diff --git a/src/quick/doc/src/dynamicview-tutorial.qdoc b/src/quick/doc/src/dynamicview-tutorial.qdoc index f87f94f264..2b5bb6e0c1 100644 --- a/src/quick/doc/src/dynamicview-tutorial.qdoc +++ b/src/quick/doc/src/dynamicview-tutorial.qdoc @@ -208,8 +208,8 @@ item and then transfer the item to the items group before moving it to the pre-d repeat until the unsorted group is empty. To find the insert position for an item we request a handle for the item from the unsorted group -with the \l {DelegateModel::}{get} function. Through the model property on this -handle we can access the same model data that is available in a delegate instance of that item and +with the \l {DelegateModelGroup::}{get()} function. Through the model property on this handle we can +access the same model data that is available in a delegate instance of that item and compare against other items to determine relative position. \snippet tutorials/dynamicview/dynamicview4/dynamicview.qml 3 diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index 0a09ee42de..e44ba2116e 100644 --- a/src/quick/items/context2d/qquickcontext2d.cpp +++ b/src/quick/items/context2d/qquickcontext2d.cpp @@ -189,7 +189,7 @@ QColor qt_color_from_string(const QV4::Value &name) if (isRgb) return QColor::fromRgba(qRgba(qClamp(rh, 0, 255), qClamp(gs, 0, 255), qClamp(bl, 0, 255), qClamp(alpha, 0, 255))); else if (isHsl) - return QColor::fromHsl(qClamp(rh, 0, 255), qClamp(gs, 0, 255), qClamp(bl, 0, 255), qClamp(alpha, 0, 255)); + return QColor::fromHsl(qClamp(rh, 0, 359), qClamp(gs, 0, 255), qClamp(bl, 0, 255), qClamp(alpha, 0, 255)); } return QColor(); } diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index d4c8c3f8ee..b618daf64b 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -1699,7 +1699,8 @@ void QQuickItemViewPrivate::updateCurrent(int modelIndex) updateHighlight(); if (oldCurrentIndex != currentIndex) emit q->currentIndexChanged(); - if (oldCurrentItem != currentItem) + if (oldCurrentItem != currentItem + && (!oldCurrentItem || !currentItem || oldCurrentItem->item != currentItem->item)) emit q->currentItemChanged(); releaseItem(oldCurrentItem); } diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp index dc4e301a36..0a26f0119f 100644 --- a/src/quick/items/qquicktextedit.cpp +++ b/src/quick/items/qquicktextedit.cpp @@ -2115,6 +2115,7 @@ QQuickTextEditPrivate::ExtraData::ExtraData() , explicitLeftPadding(false) , explicitRightPadding(false) , explicitBottomPadding(false) + , explicitImplicitSize(false) { } @@ -2345,7 +2346,8 @@ void QQuickTextEdit::updateSize() const bool wasInLayout = d->inLayout; d->inLayout = true; - setImplicitWidth(naturalWidth + leftPadding() + rightPadding()); + if (!d->extra.isAllocated() || !d->extra->explicitImplicitSize) + setImplicitWidth(naturalWidth + leftPadding() + rightPadding()); d->inLayout = wasInLayout; if (d->inLayout) // probably the result of a binding loop, but by letting it return; // get this far we'll get a warning to that effect. @@ -2364,11 +2366,13 @@ void QQuickTextEdit::updateSize() QFontMetricsF fm(d->font); qreal newHeight = d->document->isEmpty() ? qCeil(fm.height()) : d->document->size().height(); - // ### Setting the implicitWidth triggers another updateSize(), and unless there are bindings nothing has changed. - if (!widthValid() && !d->requireImplicitWidth) - setImplicitSize(newWidth + leftPadding() + rightPadding(), newHeight + topPadding() + bottomPadding()); - else - setImplicitHeight(newHeight + topPadding() + bottomPadding()); + if (!d->extra.isAllocated() || !d->extra->explicitImplicitSize) { + // ### Setting the implicitWidth triggers another updateSize(), and unless there are bindings nothing has changed. + if (!widthValid() && !d->requireImplicitWidth) + setImplicitSize(newWidth + leftPadding() + rightPadding(), newHeight + topPadding() + bottomPadding()); + else + setImplicitHeight(newHeight + topPadding() + bottomPadding()); + } d->xoff = leftPadding() + qMax(qreal(0), QQuickTextUtil::alignedX(d->document->size().width(), width() - leftPadding() - rightPadding(), effectiveHAlign())); d->yoff = topPadding() + QQuickTextUtil::alignedY(d->document->size().height(), height() - topPadding() - bottomPadding(), d->vAlign); diff --git a/src/quick/items/qquicktextedit_p_p.h b/src/quick/items/qquicktextedit_p_p.h index a763f9e56e..90ed7f071e 100644 --- a/src/quick/items/qquicktextedit_p_p.h +++ b/src/quick/items/qquicktextedit_p_p.h @@ -94,6 +94,7 @@ public: bool explicitLeftPadding : 1; bool explicitRightPadding : 1; bool explicitBottomPadding : 1; + bool explicitImplicitSize : 1; }; QLazilyAllocated<ExtraData> extra; diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index c29acf3c83..041baa4199 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -2518,6 +2518,7 @@ QQuickTextInputPrivate::ExtraData::ExtraData() , explicitLeftPadding(false) , explicitRightPadding(false) , explicitBottomPadding(false) + , explicitImplicitSize(false) { } @@ -2820,7 +2821,8 @@ void QQuickTextInputPrivate::updateLayout() line.setLineWidth(INT_MAX); const bool wasInLayout = inLayout; inLayout = true; - q->setImplicitWidth(qCeil(line.naturalTextWidth()) + q->leftPadding() + q->rightPadding()); + if (!extra.isAllocated() || !extra->explicitImplicitSize) + q->setImplicitWidth(qCeil(line.naturalTextWidth()) + q->leftPadding() + q->rightPadding()); inLayout = wasInLayout; if (inLayout) // probably the result of a binding loop, but by letting it return; // get this far we'll get a warning to that effect. @@ -2851,10 +2853,12 @@ void QQuickTextInputPrivate::updateLayout() q->polish(); q->update(); - if (!requireImplicitWidth && !q->widthValid()) - q->setImplicitSize(width + q->leftPadding() + q->rightPadding(), height + q->topPadding() + q->bottomPadding()); - else - q->setImplicitHeight(height + q->topPadding() + q->bottomPadding()); + if (!extra.isAllocated() || !extra->explicitImplicitSize) { + if (!requireImplicitWidth && !q->widthValid()) + q->setImplicitSize(width + q->leftPadding() + q->rightPadding(), height + q->topPadding() + q->bottomPadding()); + else + q->setImplicitHeight(height + q->topPadding() + q->bottomPadding()); + } updateBaselineOffset(); diff --git a/src/quick/items/qquicktextinput_p_p.h b/src/quick/items/qquicktextinput_p_p.h index cf0a6f5273..4946adc7e7 100644 --- a/src/quick/items/qquicktextinput_p_p.h +++ b/src/quick/items/qquicktextinput_p_p.h @@ -84,6 +84,7 @@ public: bool explicitLeftPadding : 1; bool explicitRightPadding : 1; bool explicitBottomPadding : 1; + bool explicitImplicitSize : 1; }; QLazilyAllocated<ExtraData> extra; diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp index 0b3cfa17b5..b0b24ca69a 100644 --- a/src/quick/items/qquickview.cpp +++ b/src/quick/items/qquickview.cpp @@ -370,7 +370,7 @@ QList<QQmlError> QQuickView::errors() const QQmlError error; error.setDescription(QLatin1String("QQuickView: invalid qml engine.")); errs << error; - } else if (d->component->status() == QQmlComponent::Ready && !d->root) { + } else if (d->component && d->component->status() == QQmlComponent::Ready && !d->root) { QQmlError error; error.setDescription(QLatin1String("QQuickView: invalid root object.")); errs << error; diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp index 391e0b7347..25dd09c01f 100644 --- a/src/quick/util/qquickglobal.cpp +++ b/src/quick/util/qquickglobal.cpp @@ -374,7 +374,7 @@ public: return QMatrix4x4(matVals); } - const QMetaObject *getMetaObjectForMetaType(int type) + const QMetaObject *getMetaObjectForMetaType(int type) Q_DECL_OVERRIDE { switch (type) { case QMetaType::QColor: diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp index a77bfd17d3..0b7b5ce9a8 100644 --- a/src/quick/util/qquickpixmapcache.cpp +++ b/src/quick/util/qquickpixmapcache.cpp @@ -137,6 +137,7 @@ public: class Event : public QEvent { public: Event(ReadError, const QString &, const QSize &, AutoTransform, QQuickTextureFactory *factory); + ~Event(); ReadError error; QString errorString; @@ -331,6 +332,11 @@ QQuickPixmapReply::Event::Event(ReadError e, const QString &s, const QSize &iSiz { } +QQuickPixmapReply::Event::~Event() +{ + delete textureFactory; +} + QNetworkAccessManager *QQuickPixmapReader::networkAccessManager() { if (!accessManager) { @@ -1021,6 +1027,7 @@ bool QQuickPixmapReply::event(QEvent *event) data->pixmapStatus = (de->error == NoError) ? QQuickPixmap::Ready : QQuickPixmap::Error; if (data->pixmapStatus == QQuickPixmap::Ready) { data->textureFactory = de->textureFactory; + de->textureFactory = 0; data->implicitSize = de->implicitSize; data->appliedTransform = de->autoTransform; PIXMAP_PROFILE(pixmapLoadingFinished(data->url, diff --git a/src/quick/util/qquickshortcut.cpp b/src/quick/util/qquickshortcut.cpp index 36c6933af4..9f32b6c180 100644 --- a/src/quick/util/qquickshortcut.cpp +++ b/src/quick/util/qquickshortcut.cpp @@ -134,6 +134,20 @@ void QQuickShortcut::setSequence(const QVariant &sequence) } /*! + \qmlproperty string QtQuick::Shortcut::sequenceString + \since 5.6 + + This property provides the shortcut's key sequence as a string, + for display purposes (tooltips, for example). + + \sa sequence +*/ +QString QQuickShortcut::sequenceString() const +{ + return m_shortcut.toString(QKeySequence::NativeText); +} + +/*! \qmlproperty bool QtQuick::Shortcut::enabled This property holds whether the shortcut is enabled. diff --git a/src/quick/util/qquickshortcut_p.h b/src/quick/util/qquickshortcut_p.h index e16ac9df20..db02f8afae 100644 --- a/src/quick/util/qquickshortcut_p.h +++ b/src/quick/util/qquickshortcut_p.h @@ -57,6 +57,7 @@ class QQuickShortcut : public QObject, public QQmlParserStatus Q_OBJECT Q_INTERFACES(QQmlParserStatus) Q_PROPERTY(QVariant sequence READ sequence WRITE setSequence NOTIFY sequenceChanged FINAL) + Q_PROPERTY(QString sequenceString READ sequenceString NOTIFY sequenceChanged FINAL REVISION 1) Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged FINAL) Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat NOTIFY autoRepeatChanged FINAL) Q_PROPERTY(Qt::ShortcutContext context READ context WRITE setContext NOTIFY contextChanged FINAL) @@ -68,6 +69,8 @@ public: QVariant sequence() const; void setSequence(const QVariant &sequence); + Q_REVISION(1) QString sequenceString() const; + bool isEnabled() const; void setEnabled(bool enabled); diff --git a/src/quick/util/qquickutilmodule.cpp b/src/quick/util/qquickutilmodule.cpp index 4f6e49fa7a..0af2343504 100644 --- a/src/quick/util/qquickutilmodule.cpp +++ b/src/quick/util/qquickutilmodule.cpp @@ -114,4 +114,6 @@ void QQuickUtilModule::defineModule() qmlRegisterType<QQuickTextMetrics>("QtQuick", 2, 4, "TextMetrics"); qmlRegisterType<QQuickShortcut>("QtQuick", 2, 5, "Shortcut"); + + qmlRegisterType<QQuickShortcut,1>("QtQuick", 2, 6, "Shortcut"); } diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp index 5755271fe1..70c9309ab0 100644 --- a/src/quickwidgets/qquickwidget.cpp +++ b/src/quickwidgets/qquickwidget.cpp @@ -566,7 +566,7 @@ QList<QQmlError> QQuickWidget::errors() const QQmlError error; error.setDescription(QLatin1String("QQuickWidget: invalid qml engine.")); errs << error; - } else if (d->component->status() == QQmlComponent::Ready && !d->root) { + } else if (d->component && d->component->status() == QQmlComponent::Ready && !d->root) { QQmlError error; error.setDescription(QLatin1String("QQuickWidget: invalid root object.")); errs << error; diff --git a/tests/auto/qml/qqmllanguage/BLACKLIST b/tests/auto/qml/qqmllanguage/BLACKLIST new file mode 100644 index 0000000000..c1c7e56df9 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/BLACKLIST @@ -0,0 +1,2 @@ +[importsPath] +windows diff --git a/tests/auto/qml/qqmlvaluetypes/data/locale_read.qml b/tests/auto/qml/qqmlvaluetypes/data/locale_read.qml new file mode 100644 index 0000000000..5ae6b41259 --- /dev/null +++ b/tests/auto/qml/qqmlvaluetypes/data/locale_read.qml @@ -0,0 +1,22 @@ +import QtQuick 2.0 + +Item { + property string amText: Qt.inputMethod.locale.amText + property string decimalPoint: Qt.inputMethod.locale.decimalPoint + property string exponential: Qt.inputMethod.locale.exponential + property int firstDayOfWeek: Qt.inputMethod.locale.firstDayOfWeek + property string groupSeparator: Qt.inputMethod.locale.groupSeparator + property int measurementSystem: Qt.inputMethod.locale.measurementSystem + property string name: Qt.inputMethod.locale.name + property string nativeCountryName: Qt.inputMethod.locale.nativeCountryName + property string nativeLanguageName: Qt.inputMethod.locale.nativeLanguageName + property string negativeSign: Qt.inputMethod.locale.negativeSign + property string percent: Qt.inputMethod.locale.percent + property string pmText: Qt.inputMethod.locale.pmText + property string positiveSign: Qt.inputMethod.locale.positiveSign + property int textDirection: Qt.inputMethod.locale.textDirection + property var uiLanguages: Qt.inputMethod.locale.uiLanguages + property var weekDays: Qt.inputMethod.locale.weekDays + property string zeroDigit: Qt.inputMethod.locale.zeroDigit +} + diff --git a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp index 52f744578a..c8107e58bf 100644 --- a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp +++ b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp @@ -36,6 +36,7 @@ #include <QQmlComponent> #include <QDebug> #include <private/qquickvaluetypes_p.h> +#include <private/qqmlglobal_p.h> #include "../../shared/util.h" #include "testtypes.h" @@ -67,6 +68,7 @@ private slots: void font(); void color(); void variant(); + void locale(); void bindingAssignment(); void bindingRead(); @@ -316,6 +318,42 @@ void tst_qqmlvaluetypes::variant() } } +void tst_qqmlvaluetypes::locale() +{ + { + QQmlComponent component(&engine, testFileUrl("locale_read.qml")); + QScopedPointer<QObject> object(component.create()); + QVERIFY(!object.isNull()); + + QVERIFY(QQml_guiProvider()->inputMethod()); + QInputMethod *inputMethod = qobject_cast<QInputMethod*>(QQml_guiProvider()->inputMethod()); + QLocale locale = inputMethod->locale(); + + QCOMPARE(object->property("amText").toString(), locale.amText()); + QCOMPARE(object->property("decimalPoint").toString().at(0), locale.decimalPoint()); + QCOMPARE(object->property("exponential").toString().at(0), locale.exponential()); + // Sunday is 0 in JavaScript. + QCOMPARE(object->property("firstDayOfWeek").toInt(), int(locale.firstDayOfWeek() == Qt::Sunday ? 0 : locale.firstDayOfWeek())); + QCOMPARE(object->property("groupSeparator").toString().at(0), locale.groupSeparator()); + QCOMPARE(object->property("measurementSystem").toInt(), int(locale.measurementSystem())); + QCOMPARE(object->property("name").toString(), locale.name()); + QCOMPARE(object->property("nativeCountryName").toString(), locale.nativeCountryName()); + QCOMPARE(object->property("nativeLanguageName").toString(), locale.nativeLanguageName()); + QCOMPARE(object->property("negativeSign").toString().at(0), locale.negativeSign()); + QCOMPARE(object->property("percent").toString().at(0), locale.percent()); + QCOMPARE(object->property("pmText").toString(), locale.pmText()); + QCOMPARE(object->property("positiveSign").toString().at(0), locale.positiveSign()); + QCOMPARE(object->property("textDirection").toInt(), int(locale.textDirection())); + QCOMPARE(object->property("uiLanguages").toStringList(), locale.uiLanguages()); + QList<Qt::DayOfWeek> weekDays; + foreach (const QVariant &weekDay, object->property("weekDays").toList()) { + weekDays.append(Qt::DayOfWeek(weekDay.toInt())); + } + QCOMPARE(weekDays, locale.weekdays()); + QCOMPARE(object->property("zeroDigit").toString().at(0), locale.zeroDigit()); + } +} + void tst_qqmlvaluetypes::sizereadonly() { { diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/status.500.reply b/tests/auto/qml/qqmlxmlhttprequest/data/status.500.reply new file mode 100644 index 0000000000..cbe2424f34 --- /dev/null +++ b/tests/auto/qml/qqmlxmlhttprequest/data/status.500.reply @@ -0,0 +1,3 @@ +HTTP/1.0 500 Internal Server Error +Connection: close +Content-type: text/html; charset=UTF-8 diff --git a/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp b/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp index ae0350278a..47bf151a37 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp +++ b/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp @@ -989,6 +989,7 @@ void tst_qqmlxmlhttprequest::responseText_data() QTest::newRow("empty body") << testFileUrl("status.200.reply") << QUrl() << ""; QTest::newRow("Not Found") << testFileUrl("status.404.reply") << testFileUrl("testdocument.html") << "QML Rocks!\n"; QTest::newRow("Bad Request") << testFileUrl("status.400.reply") << testFileUrl("testdocument.html") << "QML Rocks!\n"; + QTest::newRow("Internal server error") << testFileUrl("status.500.reply") << testFileUrl("testdocument.html") << "QML Rocks!\n"; } void tst_qqmlxmlhttprequest::nonUtf8() diff --git a/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp b/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp index f4765d0e8d..8ad2b6ba2b 100644 --- a/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp +++ b/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp @@ -338,19 +338,17 @@ void tst_QQuickWorkerScript::script_global() delete worker; } + qquickworkerscript_lastWarning = QString(); + { + QtMessageHandler previousMsgHandler = qInstallMessageHandler(qquickworkerscript_warningsHandler); + QQmlComponent component(&m_engine, testFileUrl("worker_global2.qml")); QQuickWorkerScript *worker = qobject_cast<QQuickWorkerScript*>(component.create()); QVERIFY(worker != 0); - QString value("Hello"); - - QtMessageHandler previousMsgHandler = qInstallMessageHandler(qquickworkerscript_warningsHandler); - - QVERIFY(QMetaObject::invokeMethod(worker, "testSend", Q_ARG(QVariant, value))); - QTRY_COMPARE(qquickworkerscript_lastWarning, - testFileUrl("script_global.js").toString() + QLatin1String(":2: Invalid write to global property \"world\"")); + testFileUrl("script_global2.js").toString() + QLatin1String(":1: Invalid write to global property \"world\"")); qInstallMessageHandler(previousMsgHandler); diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_context.qml b/tests/auto/quick/qquickcanvasitem/data/tst_context.qml index f266c16d76..566ad9d3d5 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_context.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_context.qml @@ -182,4 +182,22 @@ Canvas { } } } + + TestCase { + name: "Colors" + when: canvas.available + + function test_colors() { + wait(100); + compare(contextSpy.count, 1); + + var ctx = canvas.getContext("2d"); + // QTBUG-47894 + ctx.strokeStyle = 'hsl(255, 100%, 50%)'; + var c1 = ctx.strokeStyle.toString(); + ctx.strokeStyle = 'hsl(320, 100%, 50%)'; + var c2 = ctx.strokeStyle.toString(); + verify(c1 !== c2); + } + } } diff --git a/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp b/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp index 49535783c1..1104ce1d98 100644 --- a/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp +++ b/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp @@ -394,7 +394,8 @@ void tst_qquickdesignersupport::statesPropertyChanges() //Create new PropertyChanges QQuickPropertyChanges *newPropertyChange = new QQuickPropertyChanges(); newPropertyChange->setParent(state01); - QQuickStatePrivate::operations_append(&state01->changes(), newPropertyChange); + QQmlListProperty<QQuickStateOperation> changes = state01->changes(); + QQuickStatePrivate::operations_append(&changes, newPropertyChange); newPropertyChange->setObject(rootItem); diff --git a/tests/auto/quick/qquickgridview/data/gridview-initCurrent.qml b/tests/auto/quick/qquickgridview/data/gridview-initCurrent.qml index af35d2fa1b..0a6184c9de 100644 --- a/tests/auto/quick/qquickgridview/data/gridview-initCurrent.qml +++ b/tests/auto/quick/qquickgridview/data/gridview-initCurrent.qml @@ -6,6 +6,7 @@ Rectangle { property int current: grid.currentIndex property bool showHeader: false property bool showFooter: false + property int currentItemChangedCount: 0 width: 240 height: 320 @@ -63,5 +64,7 @@ Rectangle { model: testModel header: root.showHeader ? headerFooter : null footer: root.showFooter ? headerFooter : null + + onCurrentItemChanged: { root.currentItemChangedCount++ } } } diff --git a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp index 87042ca7ba..3699bef56d 100644 --- a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp +++ b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp @@ -1886,9 +1886,12 @@ void tst_QQuickGridView::currentIndex() QTRY_COMPARE(gridview->highlightItem()->y(), hlPosY); // insert item before currentIndex + window->rootObject()->setProperty("currentItemChangedCount", QVariant(0)); gridview->setCurrentIndex(28); + QTRY_COMPARE(window->rootObject()->property("currentItemChangedCount").toInt(), 1); model.insertItem(0, "Foo", "1111"); QTRY_COMPARE(window->rootObject()->property("current").toInt(), 29); + QCOMPARE(window->rootObject()->property("currentItemChangedCount").toInt(), 1); // check removing highlight by setting currentIndex to -1; gridview->setCurrentIndex(-1); diff --git a/tests/auto/quick/qquicklistview/data/listview-initCurrent.qml b/tests/auto/quick/qquicklistview/data/listview-initCurrent.qml index a02b66b8af..8aff649a67 100644 --- a/tests/auto/quick/qquicklistview/data/listview-initCurrent.qml +++ b/tests/auto/quick/qquicklistview/data/listview-initCurrent.qml @@ -6,6 +6,7 @@ Rectangle { property int current: list.currentIndex property bool showHeader: false property bool showFooter: false + property int currentItemChangedCount: 0 width: 240 height: 320 @@ -60,5 +61,7 @@ Rectangle { model: testModel header: root.showHeader ? headerFooter : null footer: root.showFooter ? headerFooter : null + + onCurrentItemChanged: { root.currentItemChangedCount++ } } } diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index 472ffdc4b6..8e7f93849c 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -2718,9 +2718,12 @@ void tst_QQuickListView::currentIndex() QTRY_COMPARE(listview->highlightItem()->y(), hlPos); // insert item before currentIndex + window->rootObject()->setProperty("currentItemChangedCount", QVariant(0)); listview->setCurrentIndex(28); + QTRY_COMPARE(window->rootObject()->property("currentItemChangedCount").toInt(), 1); model.insertItem(0, "Foo", "1111"); QTRY_COMPARE(window->rootObject()->property("current").toInt(), 29); + QCOMPARE(window->rootObject()->property("currentItemChangedCount").toInt(), 1); // check removing highlight by setting currentIndex to -1; listview->setCurrentIndex(-1); diff --git a/tests/auto/quick/qquickview/tst_qquickview.cpp b/tests/auto/quick/qquickview/tst_qquickview.cpp index 2f054e278a..69e27984c7 100644 --- a/tests/auto/quick/qquickview/tst_qquickview.cpp +++ b/tests/auto/quick/qquickview/tst_qquickview.cpp @@ -182,6 +182,10 @@ void tst_QQuickView::errors() { { QQuickView view; + QVERIFY(view.errors().isEmpty()); // don't crash + } + { + QQuickView view; QQmlTestMessageHandler messageHandler; view.setSource(testFileUrl("error1.qml")); QCOMPARE(view.status(), QQuickView::Error); diff --git a/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp index 11696e288f..7cc5dfa7c6 100644 --- a/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp +++ b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp @@ -223,6 +223,7 @@ void tst_qquickwidget::errors() { QQuickWidget *view = new QQuickWidget; QScopedPointer<QQuickWidget> cleanupView(view); + QVERIFY(view->errors().isEmpty()); // don't crash QQmlTestMessageHandler messageHandler; view->setSource(testFileUrl("error1.qml")); diff --git a/tests/manual/v4/test262 b/tests/manual/v4/test262 -Subproject 0b5af3dcec772bb06b4d685a20b2859cda59d18 +Subproject 9741ac4655808ac46c127e3d1d8ba3d27ada618 diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp index c2718de240..90d2a940a3 100644 --- a/tools/qml/main.cpp +++ b/tools/qml/main.cpp @@ -238,7 +238,7 @@ void LoadWatcher::checkForWindow(QObject *o) } #else Q_UNUSED(o) -#endif // QT_GUI_LIB +#endif // QT_GUI_LIB && !QT_NO_OPENGL } #if defined(QT_GUI_LIB) && !defined(QT_NO_OPENGL) @@ -257,7 +257,7 @@ void LoadWatcher::onOpenGlContextCreated(QOpenGLContext *context) puts(output.constData()); context->doneCurrent(); } -#endif // QT_GUI_LIB +#endif // QT_GUI_LIB && !QT_NO_OPENGL void quietMessageHandler(QtMsgType type, const QMessageLogContext &ctxt, const QString &msg) { diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp index c7539ac874..911328c12a 100644 --- a/tools/qmlplugindump/main.cpp +++ b/tools/qmlplugindump/main.cpp @@ -461,6 +461,12 @@ public: void dumpComposite(QQmlEngine *engine, const QQmlType *compositeType, QSet<QByteArray> &defaultReachableNames) { QQmlComponent e(engine, compositeType->sourceUrl()); + if (!e.isReady()) { + std::cerr << "WARNING: skipping module " << compositeType->elementName().toStdString() + << std::endl << e.errorString().toStdString() << std::endl; + return; + } + QObject *object = e.create(); if (!object) @@ -901,6 +907,7 @@ void printDebugMessage(QtMsgType, const QMessageLogContext &, const QString &msg // In case of QtFatalMsg the calling code will abort() when appropriate. } + int main(int argc, char *argv[]) { #if defined(Q_OS_WIN) && !defined(Q_CC_MINGW) @@ -1041,6 +1048,7 @@ int main(int argc, char *argv[]) if (calculateDependencies) getDependencies(engine, pluginImportUri, pluginImportVersion, &dependencies); compactDependencies(&dependencies); + // load the QtQml 2.2 builtins and the dependencies { QByteArray code("import QtQml 2.2"); |