diff options
77 files changed, 485 insertions, 212 deletions
diff --git a/dist/changes-5.1.0 b/dist/changes-5.1.0 index 8633d22eef..eaf6d05094 100644 --- a/dist/changes-5.1.0 +++ b/dist/changes-5.1.0 @@ -46,6 +46,13 @@ Third party components - tryCompare now correctly fails when it only gets two parameters + - If a QObject has a property and a slot (or invokable method) with the same + name, in QML the previous behavior was to let the property obscure the + method; from Qt 5.1 things work in the opposite way, that is a property can + never obscure a method having the same name. This is especially important + for objects having dynamic properties, such as QQmlPropertyMap. This change + was a consequence of the fix for QTBUG-29836. + **************************************************************************** * Library * **************************************************************************** diff --git a/examples/quick/customitems/painteditem/painteditem.pro b/examples/quick/customitems/painteditem/painteditem.pro index 77e4d146e1..3ec6420abf 100644 --- a/examples/quick/customitems/painteditem/painteditem.pro +++ b/examples/quick/customitems/painteditem/painteditem.pro @@ -18,3 +18,6 @@ qmldir.files = TextBalloonPlugin/qmldir qmldir.path = $$[QT_INSTALL_EXAMPLES]/quick/customitems/painteditem/TextBalloonPlugin INSTALLS += qmldir target + +OTHER_FILES += \ + textballoons.qml diff --git a/examples/quick/dialogs/colorandfiledialogs/ColorDialogs.qml b/examples/quick/dialogs/ColorDialogs.qml index 6a0af7f730..6a0af7f730 100644 --- a/examples/quick/dialogs/colorandfiledialogs/ColorDialogs.qml +++ b/examples/quick/dialogs/ColorDialogs.qml diff --git a/examples/quick/dialogs/colorandfiledialogs/FileDialogs.qml b/examples/quick/dialogs/FileDialogs.qml index d1278609f9..d1278609f9 100644 --- a/examples/quick/dialogs/colorandfiledialogs/FileDialogs.qml +++ b/examples/quick/dialogs/FileDialogs.qml diff --git a/examples/quick/dialogs/colorandfiledialogs/colorandfiledialogs.pro b/examples/quick/dialogs/colorandfiledialogs/colorandfiledialogs.pro deleted file mode 100644 index 3a7b25c91a..0000000000 --- a/examples/quick/dialogs/colorandfiledialogs/colorandfiledialogs.pro +++ /dev/null @@ -1,17 +0,0 @@ -TEMPLATE = app - -QT += quick qml -SOURCES += main.cpp -RESOURCES += colorandfiledialogs.qrc ../../shared/shared.qrc - -OTHER_FILES += \ - dialogs.qml \ - FileDialogs.qml \ - ColorDialogs.qml - -EXAMPLE_FILES = \ - FileDialogs.qml \ - ColorDialogs.qml - -target.path = $$[QT_INSTALL_EXAMPLES]/quick/dialogs -INSTALLS += target diff --git a/examples/quick/dialogs/dialogs.pro b/examples/quick/dialogs/dialogs.pro index 275e36470f..b76f396e9d 100644 --- a/examples/quick/dialogs/dialogs.pro +++ b/examples/quick/dialogs/dialogs.pro @@ -1,4 +1,17 @@ -TEMPLATE = subdirs +TEMPLATE = app -SUBDIRS = \ - colorandfiledialogs +QT += quick qml +SOURCES += main.cpp +RESOURCES += dialogs.qrc ../shared/shared.qrc + +OTHER_FILES += \ + dialogs.qml \ + FileDialogs.qml \ + ColorDialogs.qml + +EXAMPLE_FILES = \ + FileDialogs.qml \ + ColorDialogs.qml + +target.path = $$[QT_INSTALL_EXAMPLES]/quick/dialogs +INSTALLS += target diff --git a/examples/quick/dialogs/colorandfiledialogs/dialogs.qml b/examples/quick/dialogs/dialogs.qml index b5f9841a3f..b5f9841a3f 100644 --- a/examples/quick/dialogs/colorandfiledialogs/dialogs.qml +++ b/examples/quick/dialogs/dialogs.qml diff --git a/examples/quick/dialogs/colorandfiledialogs/colorandfiledialogs.qrc b/examples/quick/dialogs/dialogs.qrc index efebfe4845..efebfe4845 100644 --- a/examples/quick/dialogs/colorandfiledialogs/colorandfiledialogs.qrc +++ b/examples/quick/dialogs/dialogs.qrc diff --git a/examples/quick/dialogs/colorandfiledialogs/doc/images/qml-colorandfiledialogs-example.jpg b/examples/quick/dialogs/doc/images/dialogs-example.jpg Binary files differindex 4517a39308..4517a39308 100644 --- a/examples/quick/dialogs/colorandfiledialogs/doc/images/qml-colorandfiledialogs-example.jpg +++ b/examples/quick/dialogs/doc/images/dialogs-example.jpg diff --git a/examples/quick/dialogs/colorandfiledialogs/doc/src/colorandfiledialogs.qdoc b/examples/quick/dialogs/doc/src/dialogs.qdoc index 68804649a9..daac914c60 100644 --- a/examples/quick/dialogs/colorandfiledialogs/doc/src/colorandfiledialogs.qdoc +++ b/examples/quick/dialogs/doc/src/dialogs.qdoc @@ -25,20 +25,20 @@ ** ****************************************************************************/ /*! - \title Qt Quick ColorDialog and FileDialog Examples - \example colorandfiledialogs - \brief This example demonstrates the color and file dialog types in QML - \image qml-colorandfiledialogs-example.jpg + \title Qt Quick Dialog Examples + \example dialogs + \brief This example demonstrates the dialog types in QML + \image dialogs-example.jpg \ingroup qtquickdialog_examples - This example demonstrates the color and file system dialogs in the \l{Qt Quick Dialogs} + This example demonstrates the system dialogs in the \l{Qt Quick Dialogs} module. The appearance and behavior is platform-dependent. A \l FileDialog is used to choose a single file, multiple files or a single directory, depending on how it is configured. - \snippet colorandfiledialogs/FileDialogs.qml filedialog + \snippet dialogs/FileDialogs.qml filedialog A \l ColorDialog is used to choose a color, with or without alpha (transparency) depending on how it is configured. - \snippet colorandfiledialogs/ColorDialogs.qml colordialog + \snippet dialogs/ColorDialogs.qml colordialog */ diff --git a/examples/quick/dialogs/colorandfiledialogs/main.cpp b/examples/quick/dialogs/main.cpp index e8c2ae6aaa..bbf0c48104 100644 --- a/examples/quick/dialogs/colorandfiledialogs/main.cpp +++ b/examples/quick/dialogs/main.cpp @@ -37,5 +37,5 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "../../shared/shared.h" +#include "../shared/shared.h" DECLARATIVE_EXAMPLE_MAIN(dialogs/dialogs) diff --git a/src/imports/dialogs/doc/qtquickdialogs.qdocconf b/src/imports/dialogs/doc/qtquickdialogs.qdocconf index 5caa1c0588..34f19b5ff3 100644 --- a/src/imports/dialogs/doc/qtquickdialogs.qdocconf +++ b/src/imports/dialogs/doc/qtquickdialogs.qdocconf @@ -19,10 +19,9 @@ qhp.QtQuickDialogs.customFilters.Qt.filterAttributes = qtquickdialogs $QT_VERSIO qhp.QtQuickDialogs.subprojects = qtquickdialogsqmltypes qhp.QtQuickDialogs.subprojects.qtquickdialogsqmltypes.title = QML Types -qhp.QtQuickDialogs.subprojects.qtquickdialogsqmltypes.indexTitle = Qt Quick Dialogs +qhp.QtQuickDialogs.subprojects.qtquickdialogsqmltypes.indexTitle = Qt Quick Dialogs QML Types qhp.QtQuickDialogs.subprojects.qtquickdialogsqmltypes.selectors = fake:qmlclass qhp.QtQuickDialogs.subprojects.qtquickdialogsqmltypes.sortPages = true -qhp.QtQuickDialogs.subprojects.qtquickdialogsqmltypes.type = manual depends = qtqml qtquick qtgui qtwidgets qtdoc diff --git a/src/imports/imports.pro b/src/imports/imports.pro index 733c7c47bd..7a922a832e 100644 --- a/src/imports/imports.pro +++ b/src/imports/imports.pro @@ -16,4 +16,4 @@ qtHaveModule(quick) { qtHaveModule(xmlpatterns) : SUBDIRS += xmllistmodel -qtHaveModule(widgets) : SUBDIRS += widgets +qtHaveModule(quick):qtHaveModule(widgets): SUBDIRS += widgets diff --git a/src/imports/models/models.pro b/src/imports/models/models.pro index e96d4b9a44..98b0bd617a 100644 --- a/src/imports/models/models.pro +++ b/src/imports/models/models.pro @@ -6,6 +6,6 @@ IMPORT_VERSION = 2.1 SOURCES += \ plugin.cpp -QT += qml-private +QT = qml-private load(qml_plugin) diff --git a/src/imports/models/plugin.cpp b/src/imports/models/plugin.cpp index 2181562098..90e8a56399 100644 --- a/src/imports/models/plugin.cpp +++ b/src/imports/models/plugin.cpp @@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE /*! \qmlmodule QtQml.Models 2 - \title Qt QML Model QML Types + \title Qt QML Models QML Types \ingroup qmlmodules \brief Provides QML types for data models \since 5.1 @@ -60,7 +60,8 @@ QT_BEGIN_NAMESPACE import QtQml.Models 2.1 \endcode - Note that QtQml.Models module started at version 2.1 to match the version of the parent module. + Note that QtQml.Models module started at version 2.1 to match the version + of the parent module, \l{Qt QML}. */ diff --git a/src/qml/doc/qtqml.qdocconf b/src/qml/doc/qtqml.qdocconf index 84cf64eddd..2198428a38 100644 --- a/src/qml/doc/qtqml.qdocconf +++ b/src/qml/doc/qtqml.qdocconf @@ -18,7 +18,7 @@ qhp.QtQml.indexRoot = qhp.QtQml.filterAttributes = qtqml $QT_VERSION qtrefdoc qhp.QtQml.customFilters.Qt.name = QtQml $QT_VERSION qhp.QtQml.customFilters.Qt.filterAttributes = qtqml $QT_VERSION -qhp.QtQml.subprojects = classes examples +qhp.QtQml.subprojects = qmltypes classes examples qhp.QtQml.subprojects.classes.title = C++ Classes qhp.QtQml.subprojects.classes.indexTitle = Qt QML C++ Classes qhp.QtQml.subprojects.classes.selectors = class fake:headerfile @@ -26,15 +26,21 @@ qhp.QtQml.subprojects.classes.sortPages = true qhp.QtQml.subprojects.examples.title = Examples qhp.QtQml.subprojects.examples.indexTitle = Qt Quick Code Samples qhp.QtQml.subprojects.examples.selectors = fake:example +qhp.QtQml.subprojects.qmltypes.title = QML Types +qhp.QtQml.subprojects.qmltypes.indexTitle = Qt QML QML Types +qhp.QtQml.subprojects.qmltypes.selectors = fake:qmlclass +qhp.QtQml.subprojects.qmltypes.sortPages = true tagfile = ../../../doc/qtqml/qtqml.tags depends += qtcore qtxmlpatterns qtgui qtquick qtdoc -headerdirs += .. +headerdirs += .. \ + ../../imports/models -sourcedirs += .. +sourcedirs += .. \ + ../../imports/models exampledirs += ../../../examples/qml \ ../ \ diff --git a/src/qml/doc/src/javascript/hostenvironment.qdoc b/src/qml/doc/src/javascript/hostenvironment.qdoc index a63ef617c0..3bd64ac115 100644 --- a/src/qml/doc/src/javascript/hostenvironment.qdoc +++ b/src/qml/doc/src/javascript/hostenvironment.qdoc @@ -166,6 +166,15 @@ Item { } \endqml +\li The \c with statement is deprecated. Using the \c with statement will issue a warning +at loading time and we plan on removing support for it in Qt 5.2. It is generally considered +a language feature that is not recommended for use due reducing the readability of code and disabling +many optimizations in the engine. It is also forbidden in ECMAScript 5 strict mode. + +\li JavaScript binding expressions are executed in non-strict mode. However we +plan on changing the default for bindings in Qt 5.2 to execute always in +ECMAScript 5 strict mode. + \endlist diff --git a/src/qml/doc/src/qmltypereference.qdoc b/src/qml/doc/src/qmltypereference.qdoc index f0aadbaf32..3def3209cc 100644 --- a/src/qml/doc/src/qmltypereference.qdoc +++ b/src/qml/doc/src/qmltypereference.qdoc @@ -58,8 +58,13 @@ follows: import QtQuick 2.0 \endqml -See the \l{Qt Quick} module documentation for more information about the -\c QtQuick namespace and what it provides to QML application developers. +See the \l{Qt Quick} module documentation for more information about the \c +QtQuick namespace and what it provides to QML application developers. + +The QML types for creating lists and models, such as \l ListModel and \l +ListElement, are moved to a submodule, \c QtQml.Models. The \l{Qt QML Models QML +Types}{Qt QML Models} page has more information. + The documentation for the types below applies equally to the types of the same name provided by the \l{Qt Quick} module, as they are in fact identical. diff --git a/src/qml/doc/src/qtqml.qdoc b/src/qml/doc/src/qtqml.qdoc index 2c6bc640ff..26e4867bbc 100644 --- a/src/qml/doc/src/qtqml.qdoc +++ b/src/qml/doc/src/qtqml.qdoc @@ -84,6 +84,19 @@ various QML object types: \li \l Timer \endlist +\section2 Lists and Models + +New in Qt 5.1, the model types are moved to a submodule, \c QtQml.Models. The +\l{Qt QML Models QML Types}{Qt QML Models} page has more information. + +\list +\li \l DelegateModel +\li \l DelegateModelGroup +\li \l ListElement +\li \l ListModel +\li \l ObjectModel +\endlist + \section1 JavaScript Environment for QML Applications JavaScript expressions allow QML code to contain application logic. Qt QML diff --git a/src/qml/doc/src/whatsnew.qdoc b/src/qml/doc/src/whatsnew.qdoc index 38713a1976..eece3bcaab 100644 --- a/src/qml/doc/src/whatsnew.qdoc +++ b/src/qml/doc/src/whatsnew.qdoc @@ -39,13 +39,14 @@ a summary of the new changes: \li New properties for \l Qt.application: arguments, name, and version. \endlist -\section2 New Submodules +\section2 New Submodule -The Qt QML Models is a new submodule in Qt 5.1 and provides several QML types -for handling data with models and lists. +The \l{Qt QML Models QML Types}{Qt QML Models} is a new submodule in Qt 5.1 and +provides several QML types for handling data with models and lists. These types +replace types such as \l VisualItem, \l VisualDataModel, and \l VisualDataGroup. \list -\li \l{QtQml.Models}{Models} +\li \l{Qt QML Models QML Types}{Models} \endlist The \l{What's New in Qt 5.1} has more information about the Qt 5.1 release. diff --git a/src/qml/qml/parser/qqmljs.g b/src/qml/qml/parser/qqmljs.g index ff4f54374b..5d279ef1a2 100644 --- a/src/qml/qml/parser/qqmljs.g +++ b/src/qml/qml/parser/qqmljs.g @@ -2615,6 +2615,10 @@ case $rule_number: { node->lparenToken = loc(2); node->rparenToken = loc(4); sym(1).Node = node; + if (lexer->qmlMode()) { + const QString msg = qApp->translate("QQmlParser", "Deprecated JavaScript `with' statement detected in QML expression. Support for this will be removed in Qt 5.2!"); + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Warning, node->withToken, msg)); + } } break; ./ diff --git a/src/qml/qml/parser/qqmljsparser.cpp b/src/qml/qml/parser/qqmljsparser.cpp index a0fa7a4711..46b5c041d4 100644 --- a/src/qml/qml/parser/qqmljsparser.cpp +++ b/src/qml/qml/parser/qqmljsparser.cpp @@ -1515,6 +1515,10 @@ case 311: { node->lparenToken = loc(2); node->rparenToken = loc(4); sym(1).Node = node; + if (lexer->qmlMode()) { + const QString msg = qApp->translate("QQmlParser", "Deprecated JavaScript `with' statement detected in QML expression. Support for this will be removed in Qt 5.2!"); + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Warning, node->withToken, msg)); + } } break; case 312: { diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp index 25095a465e..9181dad519 100644 --- a/src/qml/qml/qqmlapplicationengine.cpp +++ b/src/qml/qml/qqmlapplicationengine.cpp @@ -72,6 +72,7 @@ void QQmlApplicationEnginePrivate::init() QCoreApplication::installTranslator(qtTranslator); translators << qtTranslator; #endif + QCoreApplication::instance()->setProperty("__qml_using_qqmlapplicationengine", QVariant(true)); } void QQmlApplicationEnginePrivate::loadTranslations(const QUrl &rootFile) @@ -166,9 +167,14 @@ void QQmlApplicationEnginePrivate::_q_finishLoad(QObject *o) \list \li Connecting Qt.quit() to QCoreApplication::quit() \li Automatically loads translation files from an i18n directory adjacent to the main QML file. + \li Automatically sets an incubuation controller if the scene contains a QQuickWindow. \endlist The engine behavior can be further tweaked by using the inherited methods from QQmlEngine. + + \note In the future QQmlApplicationEngine may automatically apply file selectors. + To ensure forwards compatibility, do not use folder names containing a '+' character in your QML file + structure. */ /*! diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index ccef0a6bb6..1fa1c2382f 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -767,6 +767,11 @@ QQmlComponent::QQmlComponent(QQmlComponentPrivate &dd, QObject *parent) If \a context is 0 (the default), it will create the instance in the engine' s \l {QQmlEngine::rootContext()}{root context}. + + The ownership of the returned object instance is determined by the QQmlEngine. + By default the caller has to take care that the object is eventually deleted. + + \sa QQmlEngine::ObjectOwnership */ QObject *QQmlComponent::create(QQmlContext *context) { @@ -805,7 +810,10 @@ QObject *QQmlComponent::create(QQmlContext *context) communicate information to an instantiated component, as it allows their initial values to be configured before property bindings take effect. - \sa completeCreate() + The ownership of the returned object instance is determined by the QQmlEngine. + By default the caller has to take care that the object is eventually deleted. + + \sa completeCreate(), QQmlEngine::ObjectOwnership */ QObject *QQmlComponent::beginCreate(QQmlContext *publicContext) { diff --git a/src/qml/qml/qqmlcustomparser_p.h b/src/qml/qml/qqmlcustomparser_p.h index 7a3fd47b46..3eaf99191d 100644 --- a/src/qml/qml/qqmlcustomparser_p.h +++ b/src/qml/qml/qqmlcustomparser_p.h @@ -149,7 +149,7 @@ private: Flags m_flags; friend class QQmlCompiler; }; -Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlCustomParser::Flags); +Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlCustomParser::Flags) #if 0 #define QML_REGISTER_CUSTOM_TYPE(URI, VERSION_MAJ, VERSION_MIN, NAME, TYPE, CUSTOMTYPE) \ diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h index 19139ce920..114c076c60 100644 --- a/src/qml/qml/qqmlglobal_p.h +++ b/src/qml/qml/qqmlglobal_p.h @@ -344,8 +344,8 @@ protected: QQmlApplication(QQmlApplicationPrivate &dd, QObject* parent=0); private: - Q_DISABLE_COPY(QQmlApplication); - Q_DECLARE_PRIVATE(QQmlApplication); + Q_DISABLE_COPY(QQmlApplication) + Q_DECLARE_PRIVATE(QQmlApplication) }; class QQmlApplicationPrivate : public QObjectPrivate diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp index b1ffc9a2d5..4712fbd614 100644 --- a/src/qml/qml/qqmlpropertycache.cpp +++ b/src/qml/qml/qqmlpropertycache.cpp @@ -1317,25 +1317,10 @@ QQmlPropertyData qQmlPropertyCacheCreate(const QMetaObject *metaObject, const QS Q_ASSERT(metaObject); QQmlPropertyData rv; - { - const QMetaObject *cmo = metaObject; - const QByteArray propertyName = property.toUtf8(); - while (cmo) { - int idx = cmo->indexOfProperty(propertyName); - if (idx != -1) { - QMetaProperty p = cmo->property(idx); - if (p.isScriptable()) { - rv.load(p); - return rv; - } else { - while (cmo && cmo->propertyOffset() >= idx) - cmo = cmo->superClass(); - } - } else { - cmo = 0; - } - } - } + + /* It's important to check the method list before checking for properties; + * otherwise, if the meta object is dynamic, a property will be created even + * if not found and it might obscure a method having the same name. */ //Used to block access to QObject::destroyed() and QObject::deleteLater() from QML static const int destroyedIdx1 = QObject::staticMetaObject.indexOfSignal("destroyed(QObject*)"); @@ -1357,6 +1342,31 @@ QQmlPropertyData qQmlPropertyCacheCreate(const QMetaObject *metaObject, const QS } } + { + const QMetaObject *cmo = metaObject; + const QByteArray propertyName = property.toUtf8(); + while (cmo) { + int idx = cmo->indexOfProperty(propertyName); + if (idx != -1) { + QMetaProperty p = cmo->property(idx); + if (p.isScriptable()) { + rv.load(p); + return rv; + } else { + bool changed = false; + while (cmo && cmo->propertyOffset() >= idx) { + cmo = cmo->superClass(); + changed = true; + } + /* If the "cmo" variable didn't change, set it to 0 to + * avoid running into an infinite loop */ + if (!changed) cmo = 0; + } + } else { + cmo = 0; + } + } + } return rv; } @@ -1395,7 +1405,8 @@ qQmlPropertyCacheProperty(QQmlEngine *engine, QObject *obj, const T &name, if (cache) { rv = cache->property(name, obj, context); - } else { + } + if (!rv) { local = qQmlPropertyCacheCreate(obj->metaObject(), qQmlPropertyCacheToString(name)); if (local.isValid()) rv = &local; diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h index 63b8b79fd2..e9fc584a53 100644 --- a/src/qml/qml/qqmlpropertycache_p.h +++ b/src/qml/qml/qqmlpropertycache_p.h @@ -213,7 +213,7 @@ private: friend class QQmlPropertyCache; quint32 flags; }; -Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlPropertyRawData::Flags); +Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlPropertyRawData::Flags) class QQmlPropertyData : public QQmlPropertyRawData { diff --git a/src/qml/qml/qqmlscript.cpp b/src/qml/qml/qqmlscript.cpp index 613ff24f20..ba2882f3e7 100644 --- a/src/qml/qml/qqmlscript.cpp +++ b/src/qml/qml/qqmlscript.cpp @@ -1318,13 +1318,15 @@ bool QQmlScript::Parser::parse(const QString &qmlcode, const QByteArray & /* pre QQmlJS::Parser parser(&data->engine); - if (! parser.parse() || !_errors.isEmpty()) { + if (! parser.parse() || !parser.diagnosticMessages().isEmpty()) { // Extract errors from the parser foreach (const DiagnosticMessage &m, parser.diagnosticMessages()) { - if (m.isWarning()) + if (m.isWarning()) { + qWarning("%s:%d : %s", qPrintable(_scriptFile), m.loc.startLine, qPrintable(m.message)); continue; + } QQmlError error; error.setUrl(url); diff --git a/src/qml/qml/qqmlscript_p.h b/src/qml/qml/qqmlscript_p.h index 54e7a67b65..250c71d6ac 100644 --- a/src/qml/qml/qqmlscript_p.h +++ b/src/qml/qml/qqmlscript_p.h @@ -512,7 +512,7 @@ public: } -Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlScript::Object::ScriptBlock::Pragmas); +Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlScript::Object::ScriptBlock::Pragmas) QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index 8af1ca77c8..be0c70c80a 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -330,7 +330,7 @@ public: class QQmlDOMNodeResource : public QV8ObjectResource, public Node { - V8_RESOURCE_TYPE(DOMNodeType); + V8_RESOURCE_TYPE(DOMNodeType) public: QQmlDOMNodeResource(QV8Engine *e); diff --git a/src/qml/qml/v8/qscriptisolate_p.h b/src/qml/qml/v8/qscriptisolate_p.h index d6326bf915..da35069e33 100644 --- a/src/qml/qml/v8/qscriptisolate_p.h +++ b/src/qml/qml/v8/qscriptisolate_p.h @@ -78,7 +78,7 @@ public: } private: - Q_DISABLE_COPY(QScriptIsolate); + Q_DISABLE_COPY(QScriptIsolate) const QV8Engine *m_engine; const OperationMode m_mode; }; diff --git a/src/qml/qml/v8/qv8contextwrapper.cpp b/src/qml/qml/v8/qv8contextwrapper.cpp index 9c37d87a48..630a3e5a7c 100644 --- a/src/qml/qml/v8/qv8contextwrapper.cpp +++ b/src/qml/qml/v8/qv8contextwrapper.cpp @@ -52,7 +52,7 @@ static QString internal(QLatin1String("You've stumbled onto an internal implemen class QV8ContextResource : public QV8ObjectResource { - V8_RESOURCE_TYPE(ContextType); + V8_RESOURCE_TYPE(ContextType) public: QV8ContextResource(QV8Engine *engine, QQmlContextData *context, QObject *scopeObject, bool ownsContext = false); diff --git a/src/qml/qml/v8/qv8listwrapper.cpp b/src/qml/qml/v8/qv8listwrapper.cpp index 58635c7c78..d3ce9f8fc2 100644 --- a/src/qml/qml/v8/qv8listwrapper.cpp +++ b/src/qml/qml/v8/qv8listwrapper.cpp @@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE class QV8ListResource : public QV8ObjectResource { - V8_RESOURCE_TYPE(ListType); + V8_RESOURCE_TYPE(ListType) public: QV8ListResource(QV8Engine *engine) : QV8ObjectResource(engine) {} diff --git a/src/qml/qml/v8/qv8qobjectwrapper.cpp b/src/qml/qml/v8/qv8qobjectwrapper.cpp index 0336457027..53f70ad132 100644 --- a/src/qml/qml/v8/qv8qobjectwrapper.cpp +++ b/src/qml/qml/v8/qv8qobjectwrapper.cpp @@ -524,7 +524,7 @@ v8::Handle<v8::Value> QV8QObjectWrapper::GetProperty(QV8Engine *engine, QObject QQmlData *ddata = QQmlData::get(object, false); if (ddata && ddata->propertyCache) result = ddata->propertyCache->property(property, object, context); - else + if (!result) result = QQmlPropertyCache::property(engine->engine(), object, property, context, local); } diff --git a/src/qml/qml/v8/qv8qobjectwrapper_p.h b/src/qml/qml/v8/qv8qobjectwrapper_p.h index d89a3c518f..cbd6505846 100644 --- a/src/qml/qml/v8/qv8qobjectwrapper_p.h +++ b/src/qml/qml/v8/qv8qobjectwrapper_p.h @@ -76,7 +76,7 @@ class QQmlPropertyCache; class QV8QObjectResource : public QV8ObjectResource { - V8_RESOURCE_TYPE(QObjectType); + V8_RESOURCE_TYPE(QObjectType) public: QV8QObjectResource(QV8Engine *engine, QObject *object); diff --git a/src/qml/qml/v8/qv8sequencewrapper_p_p.h b/src/qml/qml/v8/qv8sequencewrapper_p_p.h index 41bfb4b76a..ff9df7d4a0 100644 --- a/src/qml/qml/v8/qv8sequencewrapper_p_p.h +++ b/src/qml/qml/v8/qv8sequencewrapper_p_p.h @@ -71,7 +71,7 @@ QT_BEGIN_NAMESPACE */ class QV8SequenceResource : public QV8ObjectResource { - V8_RESOURCE_TYPE(SequenceType); + V8_RESOURCE_TYPE(SequenceType) public: virtual ~QV8SequenceResource() {} diff --git a/src/qml/qml/v8/qv8typewrapper.cpp b/src/qml/qml/v8/qv8typewrapper.cpp index e45ebacb90..820f0b3ee6 100644 --- a/src/qml/qml/v8/qv8typewrapper.cpp +++ b/src/qml/qml/v8/qv8typewrapper.cpp @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE class QV8TypeResource : public QV8ObjectResource { - V8_RESOURCE_TYPE(TypeType); + V8_RESOURCE_TYPE(TypeType) public: QV8TypeResource(QV8Engine *engine); diff --git a/src/qml/qml/v8/qv8valuetypewrapper.cpp b/src/qml/qml/v8/qv8valuetypewrapper.cpp index 99ee938e0c..d5d977d9c4 100644 --- a/src/qml/qml/v8/qv8valuetypewrapper.cpp +++ b/src/qml/qml/v8/qv8valuetypewrapper.cpp @@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE class QV8ValueTypeResource : public QV8ObjectResource { - V8_RESOURCE_TYPE(ValueTypeType); + V8_RESOURCE_TYPE(ValueTypeType) public: enum ObjectType { Reference, Copy }; diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp index 53b8a3c79d..747c9391e9 100644 --- a/src/qml/types/qqmldelegatemodel.cpp +++ b/src/qml/types/qqmldelegatemodel.cpp @@ -121,15 +121,16 @@ QQmlDelegateModelParts::QQmlDelegateModelParts(QQmlDelegateModel *parent) /*! \qmltype VisualDataModel \instantiates QQmlDelegateModel - \inqmlmodule QtQml 2 + \inqmlmodule QtQuick 2 \ingroup qtquick-models \brief Encapsulates a model and delegate The VisualDataModel type encapsulates a model and the delegate that will be instantiated for items in a model. - This type is provided by \c {QtQuick 2} for compatibility reasons. The same implementation - is now primarily available as DelegateModel in the QtQml.Models module. + This type is provided by the \l{Qt QML} module due to compatibility reasons. + The same implementation is now primarily available as DelegateModel in the + \l{Qt QML Models QML Types}{Qt QML Models} module. \sa {QtQml.Models2::DelegateModel} */ @@ -142,12 +143,6 @@ QQmlDelegateModelParts::QQmlDelegateModelParts(QQmlDelegateModel *parent) The DelegateModel type encapsulates a model and the delegate that will be instantiated for items in the model. - This element is also available as DelegateModel in the \c QtQuick module. For full details, - see the \l DelegateModel documentation. - - The DelegateModel type encapsulates a model and the delegate that will - be instantiated for items in the model. - It is usually not necessary to create a DelegateModel. However, it can be useful for manipulating and accessing the \l modelIndex when a QAbstractItemModel subclass is used as the @@ -158,6 +153,9 @@ QQmlDelegateModelParts::QQmlDelegateModelParts(QQmlDelegateModel *parent) The example below illustrates using a DelegateModel with a ListView. \snippet delegatemodel/visualdatamodel.qml 0 + + \note This type is also available as \l VisualDataModel in the \l{Qt QML} + module due to compatibility reasons. */ QQmlDelegateModelPrivate::QQmlDelegateModelPrivate(QQmlContext *ctxt) @@ -856,7 +854,8 @@ void QQmlDelegateModelPrivate::incubatorStatusChanged(QQDMIncubationTask *incuba delete cacheItem->object; cacheItem->object = 0; cacheItem->scriptRef -= 1; - cacheItem->contextData->destroy(); + if (cacheItem->contextData) + cacheItem->contextData->destroy(); cacheItem->contextData = 0; if (!cacheItem->isReferenced()) { @@ -2169,14 +2168,31 @@ void QQmlDelegateModelGroupPrivate::destroyingPackage(QQuickPackage *package) } /*! + \qmltype VisualDataGroup + \instantiates QQmlDelegateModelGroup + \inqmlmodule QtQuick 2 + \ingroup qtquick-models + \brief Encapsulates a filtered set of visual data items + + The VisualDataGroup type provides a means to address the model data of a + model's delegate items, as well as sort and filter these delegate items. + + This type is provided by the \l{Qt QML} module due to compatibility reasons. + The same implementation is now primarily available as \l DelegateModelGroup + in the \l{Qt QML Models QML Types}{Qt QML Models} module. + + \sa {QtQml.Models2::DelegateModelGroup} +*/ +/*! \qmltype DelegateModelGroup \instantiates QQmlDelegateModelGroup - \inqmlmodule QtQml 2 + \inqmlmodule QtQml.Models 2 \ingroup qtquick-models \brief Encapsulates a filtered set of visual data items - The DelegateModelGroup type provides a means to address the model data of a DelegateModel's - delegate items, as well as sort and filter these delegate items. + The DelegateModelGroup type provides a means to address the model data of a + DelegateModel's delegate items, as well as sort and filter these delegate + items. The initial set of instantiable delegate items in a DelegateModel is represented by its \l {QtQml.Models2::DelegateModel::items}{items} group, which normally directly reflects @@ -2200,24 +2216,11 @@ void QQmlDelegateModelGroupPrivate::destroyingPackage(QQuickPackage *package) type or to cherry-pick specific items that should be instantiated irregardless of whether they're currently within a view's visible area. - \sa {QML Dynamic View Ordering Tutorial} -*/ -/*! - \qmltype DelegateModelGroup - \instantiates QQmlDelegateModelGroup - \inqmlmodule QtQml.Models 2 - \brief Encapsulates a filtered set of visual data items - - The DelegateModelGroup type provides a means to address the model data of a DelegateModel's - delegate items, as well as sort and filter these delegate items. - - This element is also available as DelegateModelGroup in the \c QtQuick module. For full details, - see the \l DelegateModelGroup documentation. + \note This type is also available as \l VisualDataGroup in the \l{Qt QML} + module due to compatibility reasons. - \sa {QtQuick::DelegateModelGroup} + \sa {QML Dynamic View Ordering Tutorial} */ - - QQmlDelegateModelGroup::QQmlDelegateModelGroup(QObject *parent) : QObject(*new QQmlDelegateModelGroupPrivate, parent) { diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp index 5ddc0f52bd..0cfd9c6ccb 100644 --- a/src/qml/types/qqmllistmodel.cpp +++ b/src/qml/types/qqmllistmodel.cpp @@ -1426,24 +1426,12 @@ QQmlListModelParser::ListInstruction *QQmlListModelParser::ListModelData::instru \qmltype ListModel \instantiates QQmlListModel \inqmlmodule QtQml.Models 2 - \brief Defines a free-form list data source - - The ListModel is a simple container of ListElement definitions, each containing data roles. - The contents can be defined dynamically, or explicitly in QML. - - This type is also available in the \c {QtQuick 2} import. - - \sa {QtQml2::ListModel}{Full documentation for ListModel} -*/ -/*! - \qmltype ListModel - \instantiates QQmlListModel - \inqmlmodule QtQml 2 - \brief Defines a free-form list data source \ingroup qtquick-models + \brief Defines a free-form list data source - The ListModel is a simple container of ListElement definitions, each containing data roles. - The contents can be defined dynamically, or explicitly in QML. + The ListModel is a simple container of ListElement definitions, each + containing data roles. The contents can be defined dynamically, or + explicitly in QML. The number of elements in the model can be obtained from its \l count property. A number of familiar methods are also provided to manipulate the contents of the @@ -1803,7 +1791,7 @@ QHash<int, QByteArray> QQmlListModel::roleNames() const } /*! - \qmlproperty bool QtQml2::ListModel::dynamicRoles + \qmlproperty bool ListModel::dynamicRoles By default, the type of a role is fixed the first time the role is used. For example, if you create a role called @@ -1849,7 +1837,7 @@ void QQmlListModel::setDynamicRoles(bool enableDynamicRoles) } /*! - \qmlproperty int QtQml2::ListModel::count + \qmlproperty int ListModel::count The number of data entries in the model. */ int QQmlListModel::count() const @@ -2539,18 +2527,6 @@ bool QQmlListModelParser::definesEmptyList(const QString &s) \instantiates QQmlListElement \inqmlmodule QtQml.Models 2 \brief Defines a data item in a ListModel - - List elements are defined inside ListModel definitions, and represent items in a list. - - This type is also available in the \c {QtQuick 2} import. - - \sa {QtQml2::ListElement}{Full documentation for ListElement} -*/ -/*! - \qmltype ListElement - \instantiates QQmlListElement - \inqmlmodule QtQml 2 - \brief Defines a data item in a ListModel \ingroup qtquick-models List elements are defined inside ListModel definitions, and represent items in a diff --git a/src/qml/types/qqmllistmodel_p_p.h b/src/qml/types/qqmllistmodel_p_p.h index 0190081320..44c349fbe6 100644 --- a/src/qml/types/qqmllistmodel_p_p.h +++ b/src/qml/types/qqmllistmodel_p_p.h @@ -229,6 +229,9 @@ private: QStringHash<Role *> roleHash; }; +/*! +\internal +*/ class ListElement { public: @@ -292,6 +295,9 @@ private: friend class ListModel; }; +/*! +\internal +*/ class ListModel { public: @@ -375,4 +381,3 @@ QT_END_NAMESPACE Q_DECLARE_METATYPE(ListModel *); #endif // QQUICKLISTMODEL_P_P_H - diff --git a/src/qml/types/qqmlobjectmodel.cpp b/src/qml/types/qqmlobjectmodel.cpp index 3e8a67a7d2..f2a7477c1b 100644 --- a/src/qml/types/qqmlobjectmodel.cpp +++ b/src/qml/types/qqmlobjectmodel.cpp @@ -169,7 +169,7 @@ public: /*! \qmltype VisualItemModel \instantiates QQmlObjectModel - \inqmlmodule QtQml 2 + \inqmlmodule QtQuick 2 \brief Defines a set of objects to be used as a model The VisualItemModel type encapsulates contains the objects to be used diff --git a/src/qmldevtools/qmldevtools.pro b/src/qmldevtools/qmldevtools.pro index a65ef94da9..10e1ce0275 100644 --- a/src/qmldevtools/qmldevtools.pro +++ b/src/qmldevtools/qmldevtools.pro @@ -3,9 +3,10 @@ TARGET = QtQmlDevTools QT = core CONFIG += static no_module_headers internal_module -MODULE_PRIVATE_INCLUDES = \ +MODULE_INCLUDES = \ \$\$QT_MODULE_INCLUDE_BASE \ - \$\$QT_MODULE_INCLUDE_BASE/QtQml \ + \$\$QT_MODULE_INCLUDE_BASE/QtQml +MODULE_PRIVATE_INCLUDES = \ \$\$QT_MODULE_INCLUDE_BASE/QtQml/$$QT.qml.VERSION \ \$\$QT_MODULE_INCLUDE_BASE/QtQml/$$QT.qml.VERSION/QtQml diff --git a/src/quick/designer/designerwindowmanager_p.h b/src/quick/designer/designerwindowmanager_p.h index 02aacf06bd..3bbd0c2825 100644 --- a/src/quick/designer/designerwindowmanager_p.h +++ b/src/quick/designer/designerwindowmanager_p.h @@ -67,7 +67,7 @@ class QSGContext; class QAnimationDriver; class QOpenGLContext; -class DesignerWindowManager : public QObject, public QSGRenderLoop +class DesignerWindowManager : public QSGRenderLoop { Q_OBJECT public: diff --git a/src/quick/doc/qtquick.qdocconf b/src/quick/doc/qtquick.qdocconf index a27b0f82f7..30861d9b2e 100644 --- a/src/quick/doc/qtquick.qdocconf +++ b/src/quick/doc/qtquick.qdocconf @@ -60,4 +60,6 @@ headerdirs += ../../plugins sourcedirs += ../../plugins #exclude certain directories -excludedirs = ../../imports/dialogs +excludedirs += ../../imports/dialogs \ + ../../imports/models \ + ../../../examples/quick/dialogs diff --git a/src/quick/doc/src/qmltypereference.qdoc b/src/quick/doc/src/qmltypereference.qdoc index bb488ac2f2..6863758455 100644 --- a/src/quick/doc/src/qmltypereference.qdoc +++ b/src/quick/doc/src/qmltypereference.qdoc @@ -56,19 +56,19 @@ information about the concepts which are central to \c QtQuick. Qt Quick includes several submodules which contain additional types. \list - \li \l{QtQuick.XmlListModel 2}{XML List Model} - contains types + \li \l{Qt Quick XmlListModel QML Types}{XML List Model} - contains types for creating models from XML data - \li \l{QtQuick.LocalStorage 2}{Local Storage} - a submodule + \li \l{Qt Quick Local Storage QML Types}{Local Storage} - a submodule containing a JavaScript interface for an SQLite database - \li \l{QtQuick.Particles 2}{Particles} - provides a particle + \li \l{Qt Quick Particles QML Types}{Particles} - provides a particle system for QML applications - \li \l{QtQuick.Window 2}{Window} - contains types for creating + \li \l{Qt Quick Window QML Types}{Window} - contains types for creating top-level windows and accessing screen information - \li \l{QtQuick.Dialogs 1}{Dialogs} - contains types for creating and + \li \l{Qt Quick Dialogs QML Types}{Dialogs} - contains types for creating and interacting with system dialogs - \li \l{QtQuick.Controls 1.0}{Controls} - provides a set of reusable + \li \l{Qt Quick Controls QML Types}{Controls} - provides a set of reusable UI components - \li \l{QtQuick.Layouts 1.0}{Layouts} - contains types that are used + \li \l{Qt Quick Layouts QML Types}{Layouts} - contains types that are used to arrange items in the user interface \endlist @@ -234,13 +234,26 @@ Animation paths \section2 Model/View Types And Data Storage And Access -Models And Model Data +QML Lists and Models + +The \l{Qt QML Models QML Types}{Qt QML Models} submodule provides the types for +structuring data with models and lists. +\list +\li \l ListModel - Defines a list of data +\li \l ListElement - Defines a data item in a \l ListModel +\endlist + +These QML types are part of Qt Quick for backwards compatibility, but for +newer applications, \l{Qt QML Models QML Types}{Qt QML Models} provides +the same functionality. \list -\li \l {QtQml2::ListModel}{ListModel} - Defines a list of data -\li \l {QtQml2::ListElement}{ListElement} - Defines a data item in a \l {QtQml2::ListModel}{ListModel} \li \l {VisualItemModel} - Contains items that already defines its own visual delegate \li \l {VisualDataModel} - Encapsulates a model and a delegate \li \l {VisualDataGroup} - Encapsulates a filtered set of visual data items +\endlist + +XML Lists +\list \li \l {XmlListModel} - Specifies a model using XPath expressions \li \l {XmlRole} - Specifies a role for an \l {XmlListModel} \endlist diff --git a/src/quick/doc/src/qtquick.qdoc b/src/quick/doc/src/qtquick.qdoc index 0a4d276cb8..deb6aa164c 100644 --- a/src/quick/doc/src/qtquick.qdoc +++ b/src/quick/doc/src/qtquick.qdoc @@ -43,7 +43,7 @@ QML types for creating user interfaces with the QML language, and a \l{Qt Quick C++ Classes}{C++ API} for extending QML applications with C++ code. \note From Qt 5.1, a set of Qt Quick based UI controls is available to -create classic desktop-style user interfaces. Please see \l{Qt Quick Controls} +create user interfaces. Please see \l{Qt Quick Controls} for more information. For those new to QML and Qt Quick, please see diff --git a/src/quick/doc/src/whatsnew.qdoc b/src/quick/doc/src/whatsnew.qdoc index 2b865073d3..973d41dca2 100644 --- a/src/quick/doc/src/whatsnew.qdoc +++ b/src/quick/doc/src/whatsnew.qdoc @@ -44,6 +44,15 @@ features introduced by the new import and new classes in Qt 5.1: \li New \l TextEdit properties: selectByKeyboard and textDocument \li A \l Window declared inside another Window or \l Item will automatically be transient for (centered upon) the outer window. +\li These types are now part of \l{Qt QML}: + \list + \li \l {VisualItemModel} + \li \l {VisualDataModel} - Encapsulates a model and a delegate + \li \l {VisualDataGroup} + \endlist + These types are kept due to compatibility reasons and are replaced by the + \l{Qt QML Models QML Types}{Qt QML Models} types. + \endlist \endlist \section2 New Submodules diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index 5709d58d58..d359077426 100644 --- a/src/quick/items/context2d/qquickcontext2d.cpp +++ b/src/quick/items/context2d/qquickcontext2d.cpp @@ -2363,6 +2363,7 @@ static v8::Handle<v8::Value> ctx2d_drawImage(const v8::Arguments &args) } else if (args[0]->IsObject()) { QQuickImage *imageItem = qobject_cast<QQuickImage*>(engine->toQObject(args[0]->ToObject())); QQuickCanvasItem *canvas = qobject_cast<QQuickCanvasItem*>(engine->toQObject(args[0]->ToObject())); + QUrl url(engine->toString(args[0])); QV8Context2DPixelArrayResource *pix = v8_resource_cast<QV8Context2DPixelArrayResource>(args[0]->ToObject()->GetInternalField(0)->ToObject()); if (pix && !pix->image.isNull()) { @@ -2373,6 +2374,8 @@ static v8::Handle<v8::Value> ctx2d_drawImage(const v8::Arguments &args) QImage img = canvas->toImage(); if (!img.isNull()) pixmap.take(new QQuickCanvasPixmap(img, canvas->window())); + } else if (url.isValid()) { + pixmap = r->context->createPixmap(url); } else { V8THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch"); } @@ -2624,7 +2627,7 @@ static v8::Handle<v8::Value> ctx2d_createImageData(const v8::Arguments &args) } /*! - \qmlmethod CanvasImageData QtQuick2::Canvas::getImageData(real sx, real sy, real sw, real sh) + \qmlmethod CanvasImageData QtQuick2::Context2D::getImageData(real sx, real sy, real sw, real sh) Returns an CanvasImageData object containing the image data for the given rectangle of the canvas. */ static v8::Handle<v8::Value> ctx2d_getImageData(const v8::Arguments &args) diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index bfb0620688..f8b69eeedf 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -2280,7 +2280,11 @@ bool QQuickFlickablePrivate::isViewMoving() const within the timeout, both the press and release will be delivered. Note that for nested Flickables with pressDelay set, the pressDelay of - outer Flickables is overridden by the innermost Flickable. + outer Flickables is overridden by the innermost Flickable. If the drag + exceeds the platform drag threshold, the press event will be delivered + regardless of this property. + + \sa QStyleHints */ int QQuickFlickable::pressDelay() const { diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp index f4e34da318..bc71a1c064 100644 --- a/src/quick/items/qquickgridview.cpp +++ b/src/quick/items/qquickgridview.cpp @@ -2575,7 +2575,7 @@ bool QQuickGridViewPrivate::needsRefillForAddedOrRemovedIndex(int modelIndex) co This method forces the GridView to immediately respond to any outstanding changes in the model. - \since 5.1 + \since QtQuick 2.1 \b Note: methods should only be called after the Component has completed. */ diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index c71da3c330..0ffc092a83 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -128,7 +128,7 @@ void QQuickContents::calcGeometry(QQuickItem *changed) class QQuickTransformPrivate : public QObjectPrivate { - Q_DECLARE_PUBLIC(QQuickTransform); + Q_DECLARE_PUBLIC(QQuickTransform) public: static QQuickTransformPrivate* get(QQuickTransform *transform) { return transform->d_func(); } @@ -894,7 +894,7 @@ QSGNode *QQuickItemPrivate::childContainerNode() return groupNode; } -Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickItemPrivate::ChangeTypes); +Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickItemPrivate::ChangeTypes) QT_END_NAMESPACE diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index c5e96a3122..4d42c9ece1 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -3118,7 +3118,7 @@ void QQuickListViewPrivate::translateAndTransitionItemsAfter(int afterModelIndex This method forces the ListView to immediately respond to any outstanding changes in the model. - \since 5.1 + \since QtQuick 2.1 \b Note: methods should only be called after the Component has completed. */ diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index fbf46f51e4..b46f2e5ab9 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -2155,9 +2155,10 @@ void QQuickText::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeo if ((!widthChanged && !heightChanged) || d->internalWidthUpdate) goto geomChangeDone; - if (effectiveHAlign() != QQuickText::AlignLeft && widthChanged) { + if ((effectiveHAlign() != QQuickText::AlignLeft && widthChanged) + || vAlign() != QQuickText::AlignTop && heightChanged) { // If the width has changed and we're not left aligned do an update so the text is - // repositioned even if a full layout isn't required. + // repositioned even if a full layout isn't required. And the same for vertical. d->updateType = QQuickTextPrivate::UpdatePaintNode; update(); } diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 7137bb165e..619c72afb8 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -89,44 +89,49 @@ void QQuickWindowPrivate::updateFocusItemTransform() #endif } - class QQuickWindowIncubationController : public QObject, public QQmlIncubationController { Q_OBJECT public: - QQuickWindowIncubationController(const QQuickWindow *window) - : m_window(QQuickWindowPrivate::get(const_cast<QQuickWindow *>(window))) + QQuickWindowIncubationController(QSGRenderLoop *loop) + : m_renderLoop(loop), m_timer(0) { // Allow incubation for 1/3 of a frame. m_incubation_time = qMax(1, int(1000 / QGuiApplication::primaryScreen()->refreshRate()) / 3); - m_animation_driver = m_window->windowManager->animationDriver(); + m_animation_driver = m_renderLoop->animationDriver(); if (m_animation_driver) { connect(m_animation_driver, SIGNAL(stopped()), this, SLOT(animationStopped())); - connect(window, SIGNAL(frameSwapped()), this, SLOT(incubate())); + connect(m_renderLoop, SIGNAL(timeToIncubate()), this, SLOT(incubate())); } } protected: - virtual bool event(QEvent *e) + void timerEvent(QTimerEvent *) { - if (e->type() == QEvent::User) { - incubate(); - return true; + killTimer(m_timer); + m_timer = 0; + incubate(); + } + + void incubateAgain() { + if (m_timer == 0) { + // Wait for a while before processing the next batch. Using a + // timer to avoid starvation of system events. + m_timer = startTimer(m_incubation_time); } - return QObject::event(e); } public slots: void incubate() { if (incubatingObjectCount()) { - if (m_animation_driver && m_animation_driver->isRunning()) { + if (m_renderLoop->interleaveIncubation()) { incubateFor(m_incubation_time); } else { incubateFor(m_incubation_time * 2); if (incubatingObjectCount()) - QCoreApplication::postEvent(this, new QEvent(QEvent::User)); + incubateAgain(); } } } @@ -136,14 +141,15 @@ public slots: protected: virtual void incubatingObjectCountChanged(int count) { - if (count && (!m_animation_driver || !m_animation_driver->isRunning())) - QCoreApplication::postEvent(this, new QEvent(QEvent::User)); + if (count && !m_renderLoop->interleaveIncubation()) + incubateAgain(); } private: - QQuickWindowPrivate *m_window; + QSGRenderLoop *m_renderLoop; int m_incubation_time; QAnimationDriver *m_animation_driver; + int m_timer; }; #include "qquickwindow.moc" @@ -349,6 +355,7 @@ QQuickWindowPrivate::QQuickWindowPrivate() , persistentGLContext(true) , persistentSceneGraph(true) , lastWheelEventAccepted(false) + , componentCompleted(true) , renderTarget(0) , renderTargetId(0) , incubationController(0) @@ -2779,7 +2786,7 @@ QQmlIncubationController *QQuickWindow::incubationController() const Q_D(const QQuickWindow); if (!d->incubationController) - d->incubationController = new QQuickWindowIncubationController(this); + d->incubationController = new QQuickWindowIncubationController(d->windowManager); return d->incubationController; } diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h index 2465629778..2dddd9ab68 100644 --- a/src/quick/items/qquickwindow_p.h +++ b/src/quick/items/qquickwindow_p.h @@ -209,6 +209,7 @@ public: uint persistentSceneGraph : 1; uint lastWheelEventAccepted : 1; + bool componentCompleted : 1; QOpenGLFramebufferObject *renderTarget; uint renderTargetId; diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp index f826a53a29..b91edc2fd5 100644 --- a/src/quick/items/qquickwindowmodule.cpp +++ b/src/quick/items/qquickwindowmodule.cpp @@ -42,18 +42,40 @@ #include "qquickwindowmodule_p.h" #include "qquickscreen_p.h" #include <QtQuick/QQuickWindow> +#include <QtCore/QCoreApplication> +#include <QtQml/QQmlEngine> QT_BEGIN_NAMESPACE +class QQuickWindowQmlImpl : public QQuickWindow, public QQmlParserStatus +{ + Q_INTERFACES(QQmlParserStatus) + Q_OBJECT +protected: + void classBegin() { + //Give QQuickView behavior when created from QML with QQmlApplicationEngine + if (QCoreApplication::instance()->property("__qml_using_qqmlapplicationengine") == QVariant(true)) { + QQmlEngine* e = qmlEngine(this); + if (e && !e->incubationController()) + e->setIncubationController(incubationController()); + } + } + + void componentComplete() {} +}; + void QQuickWindowModule::defineModule() { const char uri[] = "QtQuick.Window"; qmlRegisterType<QQuickWindow>(uri, 2, 0, "Window"); qmlRegisterRevision<QWindow,1>(uri, 2, 1); - qmlRegisterType<QQuickWindow,1>(uri, 2, 1, "Window"); + qmlRegisterRevision<QQuickWindow,1>(uri, 2, 1);//Type moved to a subclass, but also has new members + qmlRegisterType<QQuickWindowQmlImpl>(uri, 2, 1, "Window"); qmlRegisterUncreatableType<QQuickScreen>(uri, 2, 0, "Screen", QStringLiteral("Screen can only be used via the attached property.")); } +#include "qquickwindowmodule.moc" + QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index c47250662b..6d327b8d80 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -47,7 +47,9 @@ #include <QtQuick/private/qsgdefaultimagenode_p.h> #include <QtQuick/private/qsgdefaultglyphnode_p.h> #include <QtQuick/private/qsgdistancefieldglyphnode_p.h> +#include <QtQuick/private/qsgdistancefieldglyphnode_p_p.h> #include <QtQuick/private/qsgshareddistancefieldglyphcache_p.h> +#include <QtQuick/QSGFlatColorMaterial> #include <QtQuick/private/qsgtexture_p.h> #include <QtQuick/private/qquickpixmapcache_p.h> @@ -261,9 +263,35 @@ void QSGContext::initialize(QOpenGLContext *context) Q_ASSERT(!d->gl); d->gl = context; + precompileMaterials(); + emit initialized(); } +#define QSG_PRECOMPILE_MATERIAL(name) { name m; prepareMaterial(&m); } + +/* + * Some glsl compilers take their time compiling materials, and + * the way the scene graph is being processed, these materials + * get compiled when they are first taken into use. This can + * easily lead to skipped frames. By precompiling the most + * common materials, we potentially add a few milliseconds to the + * start up, and reduce the chance of avoiding skipped frames + * later on. + */ +void QSGContext::precompileMaterials() +{ + if (qEnvironmentVariableIsEmpty("QSG_NO_MATERIAL_PRELOADING")) { + QSG_PRECOMPILE_MATERIAL(QSGVertexColorMaterial); + QSG_PRECOMPILE_MATERIAL(QSGFlatColorMaterial); + QSG_PRECOMPILE_MATERIAL(QSGOpaqueTextureMaterial); + QSG_PRECOMPILE_MATERIAL(QSGTextureMaterial); + QSG_PRECOMPILE_MATERIAL(SmoothTextureMaterial); + QSG_PRECOMPILE_MATERIAL(SmoothColorMaterial); + QSG_PRECOMPILE_MATERIAL(QSGDistanceFieldTextMaterial); + } +} + /*! Returns if the scene graph context is ready or not, meaning that it has a valid diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h index b069c53dd3..bbc42674c6 100644 --- a/src/quick/scenegraph/qsgcontext_p.h +++ b/src/quick/scenegraph/qsgcontext_p.h @@ -90,6 +90,7 @@ public: bool isReady() const; + virtual void precompileMaterials(); QSGMaterialShader *prepareMaterial(QSGMaterial *material); virtual void renderNextFrame(QSGRenderer *renderer, GLuint fboId); diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index 3a608a911d..e099d94a53 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -82,7 +82,7 @@ QSGRenderLoop::~QSGRenderLoop() { } -class QSGGuiThreadRenderLoop : public QObject, public QSGRenderLoop +class QSGGuiThreadRenderLoop : public QSGRenderLoop { Q_OBJECT public: diff --git a/src/quick/scenegraph/qsgrenderloop_p.h b/src/quick/scenegraph/qsgrenderloop_p.h index b18e6f00ad..6ff9c4c5f9 100644 --- a/src/quick/scenegraph/qsgrenderloop_p.h +++ b/src/quick/scenegraph/qsgrenderloop_p.h @@ -51,8 +51,10 @@ class QQuickWindow; class QSGContext; class QAnimationDriver; -class Q_QUICK_PRIVATE_EXPORT QSGRenderLoop +class Q_QUICK_PRIVATE_EXPORT QSGRenderLoop : public QObject { + Q_OBJECT + public: virtual ~QSGRenderLoop(); @@ -77,6 +79,11 @@ public: static QSGRenderLoop *instance(); static void setInstance(QSGRenderLoop *instance); + virtual bool interleaveIncubation() const { return false; } + +signals: + void timeToIncubate(); + private: static QSGRenderLoop *s_instance; }; diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index bd69fd5464..bfd9a2fb20 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -574,6 +574,7 @@ void QSGRenderThread::syncAndRender() int waitTime = vsyncDelta - (int) waitTimer.elapsed(); if (waitTime > 0) msleep(waitTime); + emit wm->timeToIncubate(); return; } @@ -600,6 +601,7 @@ void QSGRenderThread::syncAndRender() d->fireFrameSwapped(); } RLDEBUG(" Render: - rendering done"); + emit wm->timeToIncubate(); #ifndef QSG_NO_RENDER_TIMING if (qsg_render_timing) @@ -723,7 +725,7 @@ QSGContext *QSGThreadedRenderLoop::sceneGraphContext() const return m_thread->sg; } -bool QSGThreadedRenderLoop::anyoneShowing() +bool QSGThreadedRenderLoop::anyoneShowing() const { for (int i=0; i<m_windows.size(); ++i) { QQuickWindow *c = m_windows.at(i).window; @@ -733,6 +735,11 @@ bool QSGThreadedRenderLoop::anyoneShowing() return false; } +bool QSGThreadedRenderLoop::interleaveIncubation() const +{ + return m_animation_driver->isRunning() && anyoneShowing(); +} + void QSGThreadedRenderLoop::animationStarted() { RLDEBUG("GUI: animationStarted()"); @@ -1011,7 +1018,6 @@ void QSGThreadedRenderLoop::polishAndSync() RLDEBUG("GUI: - animations advancing"); m_animation_driver->advance(); RLDEBUG("GUI: - animations done"); - // We need to trigger another sync to keep animations running... maybePostPolishRequest(); } else if (m_sync_triggered_update) { diff --git a/src/quick/scenegraph/qsgthreadedrenderloop_p.h b/src/quick/scenegraph/qsgthreadedrenderloop_p.h index aab0e8726f..6ff5cabf43 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop_p.h +++ b/src/quick/scenegraph/qsgthreadedrenderloop_p.h @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE class QSGRenderThread; -class QSGThreadedRenderLoop : public QObject, public QSGRenderLoop +class QSGThreadedRenderLoop : public QSGRenderLoop { Q_OBJECT public: @@ -79,7 +79,7 @@ public: bool event(QEvent *); - void wakeup(); + bool interleaveIncubation() const; public slots: void animationStarted(); @@ -91,7 +91,7 @@ private: void releaseResources(QQuickWindow *window, bool inDestructor); bool checkAndResetForceUpdate(QQuickWindow *window); - bool anyoneShowing(); + bool anyoneShowing() const; void initialize(); void maybePostPolishRequest(); diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp index ce43ccf531..8e97f65ea5 100644 --- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp +++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp @@ -102,6 +102,11 @@ QSGWindowsRenderLoop::QSGWindowsRenderLoop() #endif } +bool QSGWindowsRenderLoop::interleaveIncubation() const +{ + return m_animationDriver->isRunning() && anyoneShowing(); +} + QSGWindowsRenderLoop::WindowData *QSGWindowsRenderLoop::windowData(QQuickWindow *window) { for (int i=0; i<m_windows.size(); ++i) { @@ -390,6 +395,8 @@ void QSGWindowsRenderLoop::render() // and thus another render pass, so to keep things running, // make sure there is another frame pending. maybePostUpdateTimer(); + + emit timeToIncubate(); } } diff --git a/src/quick/scenegraph/qsgwindowsrenderloop_p.h b/src/quick/scenegraph/qsgwindowsrenderloop_p.h index dc3a409cd5..218e18c3e2 100644 --- a/src/quick/scenegraph/qsgwindowsrenderloop_p.h +++ b/src/quick/scenegraph/qsgwindowsrenderloop_p.h @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE -class QSGWindowsRenderLoop : public QObject, public QSGRenderLoop +class QSGWindowsRenderLoop : public QSGRenderLoop { Q_OBJECT public: @@ -80,6 +80,9 @@ public: void resize(QQuickWindow *, const QSize &) { } bool event(QEvent *event); + bool anyoneShowing() const; + + bool interleaveIncubation() const; public slots: void started(); @@ -93,7 +96,6 @@ private: void handleObscurity(); void maybePostUpdateTimer(); - bool anyoneShowing() const; WindowData *windowData(QQuickWindow *window); QList<WindowData> m_windows; diff --git a/src/quick/scenegraph/util/qsgtexture.cpp b/src/quick/scenegraph/util/qsgtexture.cpp index a104e4af2f..a69f43f8d6 100644 --- a/src/quick/scenegraph/util/qsgtexture.cpp +++ b/src/quick/scenegraph/util/qsgtexture.cpp @@ -663,6 +663,8 @@ void QSGPlainTexture::bind() QImage tmp = (m_image.format() == QImage::Format_RGB32 || m_image.format() == QImage::Format_ARGB32_Premultiplied) ? m_image : m_image.convertToFormat(QImage::Format_ARGB32_Premultiplied); + if (tmp.width() * 4 != tmp.bytesPerLine()) + tmp = tmp.copy(); #ifndef QSG_NO_RENDER_TIMING qint64 convertTime = 0; diff --git a/src/quick/scenegraph/util/qsgtexture_p.h b/src/quick/scenegraph/util/qsgtexture_p.h index 6430a93ed8..7282d4051f 100644 --- a/src/quick/scenegraph/util/qsgtexture_p.h +++ b/src/quick/scenegraph/util/qsgtexture_p.h @@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE class QSGTexturePrivate : public QObjectPrivate { - Q_DECLARE_PUBLIC(QSGTexture); + Q_DECLARE_PUBLIC(QSGTexture) public: QSGTexturePrivate(); diff --git a/tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp b/tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp index 327716f1b5..ca212d333b 100644 --- a/tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp +++ b/tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp @@ -66,6 +66,8 @@ private slots: void crashBug(); void QTBUG_17868(); void metaObjectAccessibility(); + void QTBUG_31226(); + void QTBUG_29836(); }; void tst_QQmlPropertyMap::insert() @@ -286,13 +288,17 @@ class MyEnhancedPropertyMap : public QQmlPropertyMap { Q_OBJECT public: - MyEnhancedPropertyMap() : QQmlPropertyMap(this, 0) {} + MyEnhancedPropertyMap() : QQmlPropertyMap(this, 0), m_testSlotCalled(false) {} + bool testSlotCalled() const { return m_testSlotCalled; } signals: void testSignal(); public slots: - void testSlot() {} + void testSlot() { m_testSlotCalled = true; } + +private: + bool m_testSlotCalled; }; void tst_QQmlPropertyMap::metaObjectAccessibility() @@ -312,6 +318,57 @@ void tst_QQmlPropertyMap::metaObjectAccessibility() QVERIFY2(messageHandler.messages().isEmpty(), qPrintable(messageHandler.messageString())); } +void tst_QQmlPropertyMap::QTBUG_31226() +{ + /* Instantiate a property map from QML, and verify that property changes + * made from C++ are visible from QML */ + QQmlEngine engine; + QQmlContext context(&engine); + qmlRegisterType<QQmlPropertyMap>("QTBUG_31226", 1, 0, "PropertyMap"); + QQmlComponent c(&engine); + c.setData("import QtQuick 2.0\nimport QTBUG_31226 1.0\n" + "Item {\n" + " property string myProp\n" + " PropertyMap { id: qmlPropertyMap; objectName: \"qmlPropertyMap\" }\n" + " Timer { interval: 5; running: true; onTriggered: { myProp = qmlPropertyMap.greeting; } }\n" + "}", + QUrl()); + QObject *obj = c.create(&context); + QVERIFY(obj); + + QQmlPropertyMap *qmlPropertyMap = obj->findChild<QQmlPropertyMap*>(QString("qmlPropertyMap")); + QVERIFY(qmlPropertyMap); + + qmlPropertyMap->insert("greeting", QString("Hello world!")); + QTRY_COMPARE(obj->property("myProp").toString(), QString("Hello world!")); + + delete obj; + +} + +void tst_QQmlPropertyMap::QTBUG_29836() +{ + MyEnhancedPropertyMap map; + QCOMPARE(map.testSlotCalled(), false); + + QQmlEngine engine; + QQmlContext context(&engine); + context.setContextProperty("enhancedMap", &map); + QQmlComponent c(&engine); + c.setData("import QtQuick 2.0\n" + "Item {\n" + " Timer { interval: 5; running: true; onTriggered: enhancedMap.testSlot() }\n" + "}", + QUrl()); + QObject *obj = c.create(&context); + QVERIFY(obj); + + QTRY_COMPARE(map.testSlotCalled(), true); + + delete obj; + +} + QTEST_MAIN(tst_QQmlPropertyMap) #include "tst_qqmlpropertymap.moc" diff --git a/tests/auto/qmltest/text/tst_text.qml b/tests/auto/qmltest/text/tst_text.qml index 87e9501ccd..b1d743f630 100644 --- a/tests/auto/qmltest/text/tst_text.qml +++ b/tests/auto/qmltest/text/tst_text.qml @@ -78,6 +78,13 @@ Item { font.pixelSize: 18 } + Text { + id: txtlines + property string styledtextvalue: "Line 1<br>Line 2<br>Line 3" + text: "Line 1\nLine 2\nLine 3" + textFormat: Text.PlainText + } + TestCase { name: "Text" @@ -116,6 +123,16 @@ Item { txtlinecount.width = 50; compare(txtlinecount.lineCount, 3) } + function test_linecounts() { + compare(txtlines.lineCount, 3) + txtlines.text = txtlines.styledtextvalue; + compare(txtlines.text, "Line 1<br>Line 2<br>Line 3") + tryCompare(txtlines, 'lineCount', 1) + txtlines.textFormat = Text.StyledText; + tryCompare(txtlines, 'lineCount', 3) + txtlines.textFormat = Text.RichText; + tryCompare(txtlines, 'lineCount', 3) + } } } diff --git a/tests/auto/qmltest/textedit/tst_textedit.qml b/tests/auto/qmltest/textedit/tst_textedit.qml index 6e5124253c..eb53eaa604 100644 --- a/tests/auto/qmltest/textedit/tst_textedit.qml +++ b/tests/auto/qmltest/textedit/tst_textedit.qml @@ -91,7 +91,7 @@ Item { id: txtlines property string styledtextvalue: "Line 1<br>Line 2<br>Line 3" text: "Line 1\nLine 2\nLine 3" - textFormat: Text.PlainText + textFormat: TextEdit.PlainText } TestCase { @@ -180,10 +180,7 @@ Item { txtlines.text = txtlines.styledtextvalue; compare(txtlines.text, "Line 1<br>Line 2<br>Line 3") tryCompare(txtlines, 'lineCount', 1) - txtlines.textFormat = Text.StyledText; - expectFail("", "QTBUG-31191") - tryCompare(txtlines, 'lineCount', 3) - txtlines.textFormat = Text.RichText; + txtlines.textFormat = TextEdit.RichText; tryCompare(txtlines, 'lineCount', 3) } } diff --git a/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp b/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp index 73474afbd7..0377eaa71d 100644 --- a/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp +++ b/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp @@ -190,9 +190,6 @@ void tst_qquickanimatedimage::mirror_running() QImage frame0_expected = frame0.transformed(transform); QImage frame1_expected = frame1.transformed(transform); -#ifdef Q_OS_MAC - QSKIP("QTBUG-31370 - sometimes fails on Mac"); -#endif QCOMPARE(frame0_flipped, frame0_expected); QCOMPARE(frame1_flipped, frame1_expected); @@ -204,29 +201,28 @@ void tst_qquickanimatedimage::mirror_notRunning() QFETCH(QUrl, fileUrl); QQuickView window; + window.setSource(fileUrl); window.show(); + QTRY_VERIFY(window.isExposed()); - window.setSource(fileUrl); QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(window.rootObject()); QVERIFY(anim); int width = anim->property("width").toInt(); - QPixmap screenshot = QPixmap::fromImage(window.grabWindow()); + QImage screenshot = window.grabWindow(); QTransform transform; transform.translate(width, 0).scale(-1, 1.0); - QPixmap expected = screenshot.transformed(transform); + QImage expected = screenshot.transformed(transform); int frame = anim->currentFrame(); bool playing = anim->isPlaying(); bool paused = anim->isPlaying(); anim->setProperty("mirror", true); - screenshot = QPixmap::fromImage(window.grabWindow()); + screenshot = window.grabWindow(); -#ifdef Q_OS_MAC - QSKIP("QTBUG-31370 - sometimes fails on Mac"); -#endif + screenshot.save("screen.png"); QCOMPARE(screenshot, expected); // mirroring should not change the current frame or playing status diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_image.qml b/tests/auto/quick/qquickcanvasitem/data/tst_image.qml index 72b6dcdb00..ca95f2aec1 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_image.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_image.qml @@ -216,6 +216,17 @@ CanvasTestCase { } + property url green: 'green.png' + + function test_url(row) { + var canvas = createCanvasObject(row); + var ctx = canvas.getContext('2d'); + + canvas.loadImage(testCase.green); + ctx.drawImage(testCase.green, 0, 0); + comparePixel(ctx, 0,0, 0,255,0,255,2); + } + function test_composite(row) { var canvas = createCanvasObject(row); var ctx = canvas.getContext('2d'); diff --git a/tests/auto/quick/touchmouse/tst_touchmouse.cpp b/tests/auto/quick/touchmouse/tst_touchmouse.cpp index 15a4f0cc27..4779942406 100644 --- a/tests/auto/quick/touchmouse/tst_touchmouse.cpp +++ b/tests/auto/quick/touchmouse/tst_touchmouse.cpp @@ -195,8 +195,9 @@ void tst_TouchMouse::simpleTouchEvent() window->setSource(testFileUrl("singleitem.qml")); window->show(); - window->requestActivate(); QVERIFY(QTest::qWaitForWindowExposed(window)); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); QVERIFY(window->rootObject() != 0); EventItem *eventItem1 = window->rootObject()->findChild<EventItem*>("eventItem1"); @@ -344,7 +345,9 @@ void tst_TouchMouse::mouse() window->setSource(testFileUrl("twoitems.qml")); window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); QVERIFY(window->rootObject() != 0); EventItem *eventItem1 = window->rootObject()->findChild<EventItem*>("eventItem1"); @@ -376,7 +379,9 @@ void tst_TouchMouse::touchOverMouse() window->setSource(testFileUrl("twoitems.qml")); window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); QVERIFY(window->rootObject() != 0); EventItem *eventItem1 = window->rootObject()->findChild<EventItem*>("eventItem1"); @@ -417,7 +422,9 @@ void tst_TouchMouse::mouseOverTouch() window->setSource(testFileUrl("twoitems.qml")); window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); QVERIFY(window->rootObject() != 0); EventItem *eventItem1 = window->rootObject()->findChild<EventItem*>("eventItem1"); @@ -461,7 +468,9 @@ void tst_TouchMouse::buttonOnFlickable() window->setSource(testFileUrl("buttononflickable.qml")); window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); QVERIFY(window->rootObject() != 0); QQuickFlickable *flickable = window->rootObject()->findChild<QQuickFlickable*>("flickable"); @@ -569,7 +578,9 @@ void tst_TouchMouse::buttonOnTouch() QQuickView *window = createView(); window->setSource(testFileUrl("buttonontouch.qml")); window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); QVERIFY(window->rootObject() != 0); QQuickPinchArea *pinchArea = window->rootObject()->findChild<QQuickPinchArea*>("pincharea"); @@ -691,7 +702,9 @@ void tst_TouchMouse::pinchOnFlickable() QQuickView *window = createView(); window->setSource(testFileUrl("pinchonflickable.qml")); window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); QVERIFY(window->rootObject() != 0); QQuickPinchArea *pinchArea = window->rootObject()->findChild<QQuickPinchArea*>("pincharea"); @@ -758,7 +771,9 @@ void tst_TouchMouse::flickableOnPinch() QQuickView *window = createView(); window->setSource(testFileUrl("flickableonpinch.qml")); window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); QVERIFY(window->rootObject() != 0); QQuickPinchArea *pinchArea = window->rootObject()->findChild<QQuickPinchArea*>("pincharea"); @@ -935,8 +950,9 @@ void tst_TouchMouse::tapOnDismissiveTopMouseAreaClicksBottomOne() window->setSource(testFileUrl("twoMouseAreas.qml")); window->show(); - window->requestActivate(); QVERIFY(QTest::qWaitForWindowExposed(window)); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); QVERIFY(window->rootObject() != 0); QQuickMouseArea *bottomMouseArea = diff --git a/tools/qmlprofiler/qmlprofiler.pro b/tools/qmlprofiler/qmlprofiler.pro index c5def993f3..b3833a83ab 100644 --- a/tools/qmlprofiler/qmlprofiler.pro +++ b/tools/qmlprofiler/qmlprofiler.pro @@ -1,4 +1,4 @@ -QT += qml qml-private v8-private network core-private +QT = qml qml-private v8-private network core-private SOURCES += main.cpp \ qmlprofilerapplication.cpp \ diff --git a/tools/qmlprofiler/qqmldebugclient.cpp b/tools/qmlprofiler/qqmldebugclient.cpp index bb57594a3b..3ba8b334ff 100644 --- a/tools/qmlprofiler/qqmldebugclient.cpp +++ b/tools/qmlprofiler/qqmldebugclient.cpp @@ -308,7 +308,9 @@ void QQmlDebugConnection::flush() void QQmlDebugConnection::connectToHost(const QString &hostName, quint16 port) { QTcpSocket *socket = new QTcpSocket(d); +#ifndef QT_NO_NETWORKPROXY socket->setProxy(QNetworkProxy::NoProxy); +#endif d->device = socket; d->connectDeviceSignals(); d->gotHello = false; diff --git a/tools/qmlscene/main.cpp b/tools/qmlscene/main.cpp index d572487218..8a48445d63 100644 --- a/tools/qmlscene/main.cpp +++ b/tools/qmlscene/main.cpp @@ -483,7 +483,9 @@ int main(int argc, char ** argv) QObject *topLevel = component->create(); QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel); QQuickView* qxView = 0; - if (!window) { + if (window) { + engine.setIncubationController(window->incubationController()); + } else { QQuickItem *contentItem = qobject_cast<QQuickItem *>(topLevel); if (contentItem) { qxView = new QQuickView(&engine, NULL); |