diff options
author | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2013-04-29 14:17:46 +0200 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2013-04-29 14:17:46 +0200 |
commit | 7224dd977163335d61ed4297341e6161bf1dbcf7 (patch) | |
tree | 1674bfdd872ba45908437c9cbc67ba98f5f3b534 | |
parent | c704226b6815df4d989142729bae9fadd14f6f9d (diff) | |
parent | f3973cbd077d2d92250958f8bda57fea30827f00 (diff) |
Merge remote-tracking branch 'origin/stable' into dev
Change-Id: I35f07a1725af104952f822274763dd7a96a9d560
164 files changed, 2491 insertions, 896 deletions
diff --git a/examples/quick/painteditem/textballoons/doc/src/textballoons.qdoc b/examples/quick/painteditem/textballoons/doc/src/textballoons.qdoc index d4aabc01d8..9450c19259 100644 --- a/examples/quick/painteditem/textballoons/doc/src/textballoons.qdoc +++ b/examples/quick/painteditem/textballoons/doc/src/textballoons.qdoc @@ -43,12 +43,12 @@ The example consists of an item class, a plugin class and a QML file to use this plugin. The \c TextBalloon class represents the individual text balloons extending QQuickPaintedItem, the \c TextBalloonPlugin class - represents the skeleton code for a QtQuick plugin and the + represents the skeleton code for a \l {Qt Quick} plugin and the \c textballoons.qml file is used to load the plugin and display the text balloons. We will focus on the \c TextBalloon class first and continue with the - \c textballoons.qml file. For an example on how to implement a QtQuick + \c textballoons.qml file. For an example on how to implement a \l {Qt Quick} plugin please look at \l{declarative/tutorials/extending/chapter6-plugins} {Writing an Extension Plugin} diff --git a/examples/quick/particles/system/doc/src/system.qdoc b/examples/quick/particles/system/doc/src/system.qdoc index 04dc1727d2..2bef4c6947 100644 --- a/examples/quick/particles/system/doc/src/system.qdoc +++ b/examples/quick/particles/system/doc/src/system.qdoc @@ -53,6 +53,6 @@ \snippet quick/particles/system/content/dynamicemitters.qml 0 Note that this effect, a flurry of flying rainbow spears, would be better served with TrailEmitter. It is only done with dynamic emitters in this example to show the concept more simply. - Multiple Painters shows how to control paint ordering of individual particles. While the paint ordering of particles within one ImagePainter is not strictly defined, ImageParticle objects follow the normal Z-ordering rules for QtQuick items. This example allow you to paint the inside of the particles above the black borders using a pair of ImageParticles each painting different parts of the same logical particle. + Multiple Painters shows how to control paint ordering of individual particles. While the paint ordering of particles within one ImagePainter is not strictly defined, ImageParticle objects follow the normal Z-ordering rules for \l {Qt Quick} items. This example allow you to paint the inside of the particles above the black borders using a pair of ImageParticles each painting different parts of the same logical particle. */ diff --git a/examples/quick/scenegraph/customgeometry/doc/src/customgeometry.qdoc b/examples/quick/scenegraph/customgeometry/doc/src/customgeometry.qdoc index d98407b6c1..e3cef52bf7 100644 --- a/examples/quick/scenegraph/customgeometry/doc/src/customgeometry.qdoc +++ b/examples/quick/scenegraph/customgeometry/doc/src/customgeometry.qdoc @@ -41,7 +41,7 @@ \section1 BezierCurve Declaration - \snippet quick/scenegraph/customgeometry/beziercurve.h 1 + \snippet scenegraph/customgeometry/beziercurve.h 1 The item declaration subclasses the QQuickItem class and adds five properties. One for each of the four control points in the bezier @@ -52,7 +52,7 @@ signals for each of them so changes will be picked up the QML engine and used accordingly. - \snippet quick/scenegraph/customgeometry/beziercurve.h 2 + \snippet scenegraph/customgeometry/beziercurve.h 2 The synchronization point between the QML scene and the rendering scene graph is the virtual function \l @@ -67,7 +67,7 @@ \section1 BezierCurve Implementation - \snippet quick/scenegraph/customgeometry/beziercurve.cpp 1 + \snippet scenegraph/customgeometry/beziercurve.cpp 1 The BezierCurve constructor sets up default values for the control points and the number of segments. The bezier curve @@ -80,7 +80,7 @@ QQuickItem::updatePaintNode() when it is time for the QML scene to be synchronized with the rendering scene graph. - \snippet quick/scenegraph/customgeometry/beziercurve.cpp 2 + \snippet scenegraph/customgeometry/beziercurve.cpp 2 The BezierCurve class has no data members that need to be cleaned up so the destructor does nothing. It is worth mentioning that the @@ -89,7 +89,7 @@ QSGNode references in the QQuickItem class nor try to clean them up explicitly. - \snippet quick/scenegraph/customgeometry/beziercurve.cpp 3 + \snippet scenegraph/customgeometry/beziercurve.cpp 3 The setter function for the p1 property checks if the value is unchanged and exits early if this is the case. Then it updates the @@ -103,7 +103,7 @@ The other property setters are equivalent, and are omitted from this example. - \snippet quick/scenegraph/customgeometry/beziercurve.cpp 4 + \snippet scenegraph/customgeometry/beziercurve.cpp 4 The updatePaintNode() function is the primary integration point for synchronizing the state of the QML scene with the rendering @@ -113,7 +113,7 @@ our QSGGeometryNode which we will fill with geometry and a material. - \snippet quick/scenegraph/customgeometry/beziercurve.cpp 5 + \snippet scenegraph/customgeometry/beziercurve.cpp 5 We then create the geometry and add it to the node. The first argument to the QSGGeometry constructor is a definition of the @@ -135,7 +135,7 @@ geometry a member of a QSGGeometryNode subclass, in which case, we would not have set the QSGGeometryNode::OwnsGeometry flag. - \snippet quick/scenegraph/customgeometry/beziercurve.cpp 6 + \snippet scenegraph/customgeometry/beziercurve.cpp 6 The scene graph API provides a few commonly used used material implementations. In this example we use the QSGFlatColorMaterial @@ -143,7 +143,7 @@ color. Again we pass the ownership of the material to the node, so it can be cleaned up by the scene graph. - \snippet quick/scenegraph/customgeometry/beziercurve.cpp 7 + \snippet scenegraph/customgeometry/beziercurve.cpp 7 In the case where the QML item has changed and we only want to modify the existing node's geometry, we cast the \c oldNode to a @@ -151,7 +151,7 @@ segment count has changed, we call QSGGeometry::allocate() to make sure it has the right number of vertices. - \snippet quick/scenegraph/customgeometry/beziercurve.cpp 8 + \snippet scenegraph/customgeometry/beziercurve.cpp 8 To fill the geometry, we first extract the vertex array from it. Since we are using one of the default attribute sets, we can @@ -159,14 +159,14 @@ Then we go through each segment and calculate its position and write that value to the vertex. - \snippet quick/scenegraph/customgeometry/beziercurve.cpp 9 + \snippet scenegraph/customgeometry/beziercurve.cpp 9 In the end of the function, we return the node so the scene graph can render it. \section1 Application Entry-Point - \snippet quick/scenegraph/customgeometry/main.cpp 1 + \snippet scenegraph/customgeometry/main.cpp 1 The application is a straightforward QML application, with a QGuiApplication and a QQuickView that we pass a .qml file. To make @@ -183,24 +183,24 @@ \section1 Using the Item - \snippet quick/scenegraph/customgeometry/main.qml 1 + \snippet scenegraph/customgeometry/main.qml 1 Our .qml file imports the \c {QtQuick 2.0} module to get the standard types and also our own \c {CustomGeometry 1.0} module which contains our newly created BezierCurve objects. - \snippet quick/scenegraph/customgeometry/main.qml 2 + \snippet scenegraph/customgeometry/main.qml 2 Then we create the our root item and an instance of the BezierCurve which we anchor to fill the root. - \snippet quick/scenegraph/customgeometry/main.qml 3 + \snippet scenegraph/customgeometry/main.qml 3 To make the example a bit more interesting we add an animation to change the two control points in the curve. The end points stay unchanged. - \snippet quick/scenegraph/customgeometry/main.qml 4 + \snippet scenegraph/customgeometry/main.qml 4 Finally we overlay a short text outlining what the example shows. diff --git a/examples/quick/scenegraph/openglunderqml/doc/src/openglunderqml.qdoc b/examples/quick/scenegraph/openglunderqml/doc/src/openglunderqml.qdoc index 4bf5444d79..1f87412aa4 100644 --- a/examples/quick/scenegraph/openglunderqml/doc/src/openglunderqml.qdoc +++ b/examples/quick/scenegraph/openglunderqml/doc/src/openglunderqml.qdoc @@ -50,7 +50,7 @@ in the QML file and this value is used by the OpenGL shader program that draws the squircles. - \snippet quick/scenegraph/openglunderqml/squircle.h 1 + \snippet scenegraph/openglunderqml/squircle.h 1 First of all, we need a QObject with a slot to connect the signals to. We subclass QQuickItem in order to use the \l @@ -73,13 +73,13 @@ Lets move on to the implementation. - \snippet quick/scenegraph/openglunderqml/squircle.cpp 7 + \snippet scenegraph/openglunderqml/squircle.cpp 7 The constructor of the \c Squircle class simply initializes the values. The shader program will be initialized during rendering later. - \snippet quick/scenegraph/openglunderqml/squircle.cpp 8 + \snippet scenegraph/openglunderqml/squircle.cpp 8 The property setter checks that the value has indeed changed before updating its internal variable. It then calls \l @@ -88,13 +88,13 @@ initialization, before the object has been entered into the scene and before it has a window. - \snippet quick/scenegraph/openglunderqml/squircle.cpp 1 - \snippet quick/scenegraph/openglunderqml/squircle.cpp 2 + \snippet scenegraph/openglunderqml/squircle.cpp 1 + \snippet scenegraph/openglunderqml/squircle.cpp 2 For our paint function to be called, we need to connect to the window's signals. When Squircle object is populated into the - scene, the itemChange function is called with the change type \c - ItemSceneChange. We connect \l QQuickWindow::beforeRendering() to + scene, the windowChanged signal is emitted. In our handler, + we connect \l QQuickWindow::beforeRendering() to \c paint() to do the rendering, and \l QQuickWindow::beforeSynchronizing() to \c sync() to copy the state of the \c t property for the upcoming frame. @@ -106,14 +106,14 @@ slots are invoked on the wrong thread with no OpenGL context present. - \snippet quick/scenegraph/openglunderqml/squircle.cpp 3 + \snippet scenegraph/openglunderqml/squircle.cpp 3 The default behavior of the scene graph is to clear the framebuffer before rendering. Since we render before the scene graph, we need to turn this clearing off. This means that we need to clear ourselves in the \c paint() function. - \snippet quick/scenegraph/openglunderqml/squircle.cpp 4 + \snippet scenegraph/openglunderqml/squircle.cpp 4 The first thing we do in the \c paint() function is to initialize the shader program. By initializing the shader program @@ -126,18 +126,18 @@ all rendering related operations must happen on the rendering thread. - \snippet quick/scenegraph/openglunderqml/squircle.cpp 5 + \snippet scenegraph/openglunderqml/squircle.cpp 5 We use the shader program to draw the squircle. At the end of the \c paint function we release the program and disable the attributes we used so that the OpenGL context is in a "clean" state for the scene graph to pick it up. - \snippet quick/scenegraph/openglunderqml/squircle.cpp 6 + \snippet scenegraph/openglunderqml/squircle.cpp 6 In the \c cleanup() function we delete the program. - \snippet quick/scenegraph/openglunderqml/squircle.cpp 9 + \snippet scenegraph/openglunderqml/squircle.cpp 9 We use the \c sync() function to copy the state of the object in the GUI thread into the rendering thread. @@ -146,20 +146,20 @@ thread is blocked, so it is safe to simply copy the value without any additional protection. - \snippet quick/scenegraph/openglunderqml/main.cpp 1 + \snippet scenegraph/openglunderqml/main.cpp 1 The application's \c main() function instantiates a QQuickView and launches the \c main.qml file. The only thing worth noting is that we export the \c Squircle class to QML using the \l qmlRegisterType() macro. - \snippet quick/scenegraph/openglunderqml/main.qml 1 + \snippet scenegraph/openglunderqml/main.qml 1 We import the Squircle QML type with the name we registered in the \c main() function. We then instantiate it and create a running - NumberAnimation on the its \c t property. + NumberAnimation on its \c t property. - \snippet quick/scenegraph/openglunderqml/main.qml 2 + \snippet scenegraph/openglunderqml/main.qml 2 Then we overlay a short descriptive text, so that it is clearly visible that we are in fact rendering OpenGL under our Qt Quick diff --git a/examples/quick/scenegraph/openglunderqml/squircle.cpp b/examples/quick/scenegraph/openglunderqml/squircle.cpp index 84509fb615..8ceb9c5f9e 100644 --- a/examples/quick/scenegraph/openglunderqml/squircle.cpp +++ b/examples/quick/scenegraph/openglunderqml/squircle.cpp @@ -51,6 +51,7 @@ Squircle::Squircle() , m_t(0) , m_thread_t(0) { + connect(this, SIGNAL(windowChanged(QQuickWindow*)), this, SLOT(handleWindowChanged(QQuickWindow*))); } //! [7] @@ -66,17 +67,11 @@ void Squircle::setT(qreal t) } //! [8] - //! [1] -void Squircle::itemChange(ItemChange change, const ItemChangeData &) +void Squircle::handleWindowChanged(QQuickWindow *win) { - // The ItemSceneChange event is sent when we are first attached to a window. - if (change == ItemSceneChange) { - QQuickWindow *win = window(); - if (!win) - return; + if (win) { //! [1] - // Connect the beforeRendering signal to our paint function. // Since this call is executed on the rendering thread it must be // a Qt::DirectConnection diff --git a/examples/quick/scenegraph/openglunderqml/squircle.h b/examples/quick/scenegraph/openglunderqml/squircle.h index e292ca325f..449e02bbf1 100644 --- a/examples/quick/scenegraph/openglunderqml/squircle.h +++ b/examples/quick/scenegraph/openglunderqml/squircle.h @@ -61,14 +61,14 @@ public: signals: void tChanged(); -protected: - void itemChange(ItemChange change, const ItemChangeData &); - public slots: void paint(); void cleanup(); void sync(); +private slots: + void handleWindowChanged(QQuickWindow *win); + private: QOpenGLShaderProgram *m_program; diff --git a/examples/quick/scenegraph/simplematerial/doc/src/simplematerial.qdoc b/examples/quick/scenegraph/simplematerial/doc/src/simplematerial.qdoc index 1529649798..5d83b9fa5f 100644 --- a/examples/quick/scenegraph/simplematerial/doc/src/simplematerial.qdoc +++ b/examples/quick/scenegraph/simplematerial/doc/src/simplematerial.qdoc @@ -47,7 +47,7 @@ material state is what we assign to each individual node, in this case to give them different colors. - \snippet quick/scenegraph/simplematerial/simplematerial.cpp 1 + \snippet scenegraph/simplematerial/simplematerial.cpp 1 The first thing we do when creating custom materials with the simplified scheme is to create a state class. In this case the @@ -55,7 +55,7 @@ compare function which the scene graph can use to reorder the node rendering. - \snippet quick/scenegraph/simplematerial/simplematerial.cpp 2 + \snippet scenegraph/simplematerial/simplematerial.cpp 2 Next we define the material shader, by subclassing a template instantiation of \l QSGSimpleMaterialShader with our \c State. @@ -74,21 +74,21 @@ classes. Using the same \c State class in multiple shaders will will lead to undefined behavior. - \snippet quick/scenegraph/simplematerial/simplematerial.cpp 3 + \snippet scenegraph/simplematerial/simplematerial.cpp 3 Next comes the declaration of the shader source code, where we define a vertex and fragment shader. The simple material assumes the presence of \c qt_Matrix in the vertex shader and \c qt_Opacity in the fragment shader. - \snippet quick/scenegraph/simplematerial/simplematerial.cpp 4 + \snippet scenegraph/simplematerial/simplematerial.cpp 4 We reimplement the \c attributes function to return the name of the \c aVertex and \c aTexCoord attribute names. These attributes will be mapped to attribute indices 0 and 1 in the node's geometry. - \snippet quick/scenegraph/simplematerial/simplematerial.cpp 6 + \snippet scenegraph/simplematerial/simplematerial.cpp 6 Uniforms can be accessed either by name or by index, where index is faster than name, so we reimplement the \c resolveUniforms() @@ -96,7 +96,7 @@ to worry about resolving \c qt_Opacity or \c qt_Matrix as these are handled by the baseclass. - \snippet quick/scenegraph/simplematerial/simplematerial.cpp 5 + \snippet scenegraph/simplematerial/simplematerial.cpp 5 The \c updateState() function is called once for every unique state and we use it to update the shader program with the current @@ -105,7 +105,7 @@ usecase, where all the colors are different, the updateState will be called once for every node. - \snippet quick/scenegraph/simplematerial/simplematerial.cpp 7 + \snippet scenegraph/simplematerial/simplematerial.cpp 7 The \c ColorNode class is supposed to draw something, so it needs to be a subclass of \l QSGGeometryNode. @@ -129,12 +129,12 @@ Finally, we tell the node to take ownership of the material, so we do not have to explicitly memorymanage it. - \snippet quick/scenegraph/simplematerial/simplematerial.cpp 8 + \snippet scenegraph/simplematerial/simplematerial.cpp 8 Since the Item is providing its own graphics to the scene graph, we set the flag \l QQuickItem::ItemHasContents. - \snippet quick/scenegraph/simplematerial/simplematerial.cpp 9 + \snippet scenegraph/simplematerial/simplematerial.cpp 9 Whenever the Item has changed graphically, the \l QQuickItem::updatePaintNode() function is called. @@ -157,23 +157,23 @@ state. Finally, we notify the scene graph that the node has undergone changes to its geometry and material. - \snippet quick/scenegraph/simplematerial/simplematerial.cpp 11 + \snippet scenegraph/simplematerial/simplematerial.cpp 11 The \c main() function of the application adds the custom QML type using \l qmlRegisterType() and opens up a \l QQuickView with our QML file. - \snippet quick/scenegraph/simplematerial/main.qml 1 + \snippet scenegraph/simplematerial/main.qml 1 In the QML file, we import our custom type so we can instantiate it. - \snippet quick/scenegraph/simplematerial/main.qml 2 + \snippet scenegraph/simplematerial/main.qml 2 Then we create a column of three instances of our custom item, each with a different color. - \snippet quick/scenegraph/simplematerial/main.qml 3 + \snippet scenegraph/simplematerial/main.qml 3 And finally we overlay a short descriptive text. diff --git a/examples/quick/scenegraph/textureinthread/main.cpp b/examples/quick/scenegraph/textureinthread/main.cpp index e415d254a1..3286055496 100644 --- a/examples/quick/scenegraph/textureinthread/main.cpp +++ b/examples/quick/scenegraph/textureinthread/main.cpp @@ -38,6 +38,8 @@ ** ****************************************************************************/ +#include <QtCore/QThread> + #include <QGuiApplication> #include <QtQuick/QQuickView> @@ -49,11 +51,31 @@ int main(int argc, char **argv) QGuiApplication app(argc, argv); qmlRegisterType<ThreadRenderer>("SceneGraphRendering", 1, 0, "Renderer"); + int execReturn = 0; + + { + QQuickView view; + + // Rendering in a thread introduces a slightly more complicated cleanup + // so we ensure that no cleanup of graphics resources happen until the + // application is shutting down. + view.setPersistentOpenGLContext(true); + view.setPersistentSceneGraph(true); + + view.setResizeMode(QQuickView::SizeRootObjectToView); + view.setSource(QUrl("qrc:///scenegraph/textureinsgnode/main.qml")); + view.show(); + + execReturn = app.exec(); + } - QQuickView view; - view.setResizeMode(QQuickView::SizeRootObjectToView); - view.setSource(QUrl("qrc:///scenegraph/textureinsgnode/main.qml")); - view.show(); + // As the render threads make use of our QGuiApplication object + // to clean up gracefully, wait for them to finish before + // QGuiApp is taken off the heap. + foreach (QThread *t, ThreadRenderer::threads) { + t->wait(); + delete t; + } - return app.exec(); + return execReturn; } diff --git a/examples/quick/scenegraph/textureinthread/threadrenderer.cpp b/examples/quick/scenegraph/textureinthread/threadrenderer.cpp index 90b6b49880..7de1d294ba 100644 --- a/examples/quick/scenegraph/textureinthread/threadrenderer.cpp +++ b/examples/quick/scenegraph/textureinthread/threadrenderer.cpp @@ -46,10 +46,13 @@ #include <QtGui/QOpenGLContext> #include <QtGui/QOpenGLFramebufferObject> +#include <QtGui/QGuiApplication> +#include <QtGui/QOffscreenSurface> #include <QtQuick/QQuickWindow> #include <qsgsimpletexturenode.h> +QList<QThread *> ThreadRenderer::threads; /* * The render thread shares a context with the scene graph and will @@ -60,37 +63,39 @@ class RenderThread : public QThread { Q_OBJECT public: - RenderThread(const QSize &size) + RenderThread(const QSize &size, QOpenGLContext *context) : m_renderFbo(0) , m_displayFbo(0) , m_logoRenderer(0) + , m_fakeSurface(0) , m_size(size) { - // Since we're using queued connections, we need affinity to the rendering thread. - moveToThread(this); + ThreadRenderer::threads << this; // Set up the QOpenGLContext to use for rendering in this thread. It is sharing // memory space with the GL context of the scene graph. This constructor is called // during updatePaintNode, so we are currently on the scene graph thread with the // scene graph's OpenGL context current. - QOpenGLContext *current = QOpenGLContext::currentContext(); m_context = new QOpenGLContext(); - m_context->setShareContext(current); - m_context->setFormat(current->format()); - m_context->create(); + m_context->setShareContext(context); + m_context->setFormat(context->format()); m_context->moveToThread(this); - // We need a non-visible surface to make current... - m_fakeSurface = new QWindow(); - m_fakeSurface->setGeometry(0, 0, 64, 64); - m_fakeSurface->setSurfaceType(QWindow::OpenGLSurface); - m_fakeSurface->setFormat(current->format()); + // We need a non-visible surface to make current in the other thread + // and QWindows must be created and managed on the GUI thread. + m_fakeSurface = new QOffscreenSurface(); + m_fakeSurface->setFormat(context->format()); m_fakeSurface->create(); } + void setSurface(QOffscreenSurface *surface) { m_fakeSurface = surface; } + public slots: void renderNext() { + if (!m_context->isValid()) + m_context->create(); + m_context->makeCurrent(m_fakeSurface); if (!m_renderFbo) { @@ -119,6 +124,23 @@ public slots: emit textureReady(m_displayFbo->texture(), m_size); } + void shutDown() + { + m_context->makeCurrent(m_fakeSurface); + delete m_renderFbo; + delete m_displayFbo; + delete m_logoRenderer; + m_context->doneCurrent(); + delete m_context; + + // schedule this to be deleted only after we're done cleaning up + m_fakeSurface->deleteLater(); + + // Stop event processing, move the thread to GUI and make sure it is deleted. + exit(); + moveToThread(QGuiApplication::instance()->thread()); + } + signals: void textureReady(int id, const QSize &size); @@ -128,7 +150,7 @@ private: LogoRenderer *m_logoRenderer; - QWindow *m_fakeSurface; + QOffscreenSurface *m_fakeSurface; QOpenGLContext *m_context; QSize m_size; }; @@ -209,19 +231,35 @@ private: ThreadRenderer::ThreadRenderer() + : m_renderThread(0) { setFlag(ItemHasContents, true); + polish(); } +void ThreadRenderer::updatePolish() +{ + if (!window() || !window()->openglContext()) + return; + m_renderThread = new RenderThread(QSize(512, 512), window()->openglContext()); + m_renderThread->moveToThread(m_renderThread); + m_renderThread->start(); + connect(window(), SIGNAL(sceneGraphInvalidated()), m_renderThread, SLOT(shutDown()), Qt::QueuedConnection); +} QSGNode *ThreadRenderer::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) { + if (!m_renderThread) { + polish(); + update(); + return 0; + } + TextureNode *node = static_cast<TextureNode *>(oldNode); if (!node) { node = new TextureNode(window()); - m_renderThread = new RenderThread(QSize(512, 512)); /* Set up connections to get the production of FBO textures in sync with vsync on the * rendering thread. @@ -242,9 +280,6 @@ QSGNode *ThreadRenderer::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * connect(window(), SIGNAL(beforeRendering()), node, SLOT(prepareNode()), Qt::DirectConnection); connect(node, SIGNAL(textureInUse()), m_renderThread, SLOT(renderNext()), Qt::QueuedConnection); - // Start the render thread and enter let it process events. - m_renderThread->start(); - // Get the production of FBO textures started.. QMetaObject::invokeMethod(m_renderThread, "renderNext", Qt::QueuedConnection); } diff --git a/examples/quick/scenegraph/textureinthread/threadrenderer.h b/examples/quick/scenegraph/textureinthread/threadrenderer.h index f12e6404e5..8c68e27d92 100644 --- a/examples/quick/scenegraph/textureinthread/threadrenderer.h +++ b/examples/quick/scenegraph/textureinthread/threadrenderer.h @@ -52,9 +52,15 @@ class ThreadRenderer : public QQuickItem public: ThreadRenderer(); + static QList<QThread *> threads; + +public slots: + void updatePolish(); + protected: QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); + private: RenderThread *m_renderThread; }; diff --git a/examples/quick/shadereffects/doc/src/shadereffects.qdoc b/examples/quick/shadereffects/doc/src/shadereffects.qdoc index 5d1547a1fe..6f6311a5ae 100644 --- a/examples/quick/shadereffects/doc/src/shadereffects.qdoc +++ b/examples/quick/shadereffects/doc/src/shadereffects.qdoc @@ -32,7 +32,7 @@ \ingroup qtquickexamples This example demonstrates a couple of visual effects that you can perform - with shaders in QtQuick 2.0 + with shaders in \l {Qt Quick}. ShaderEffects typically operate on other types, using a ShaderEffectSource \snippet quick/shadereffects/shadereffects.qml source diff --git a/examples/quick/views/doc/src/views.qdoc b/examples/quick/views/doc/src/views.qdoc index cc8112f4dd..21a2d2e5e0 100644 --- a/examples/quick/views/doc/src/views.qdoc +++ b/examples/quick/views/doc/src/views.qdoc @@ -32,7 +32,7 @@ \image qml-modelviews-example.png \ingroup qtquickexamples - This is a collection of small QML examples relating to model and view functionality. They demonstrate how to show data from a model using the QtQuick view types. + This is a collection of small QML examples relating to model and view functionality. They demonstrate how to show data from a model using the \l {Qt Quick} view types. \section2 GridView and PathView demonstrate usage of these types to display views. \snippet quick/views/gridview/gridview-example.qml 0 diff --git a/src/imports/dialogs/plugins.qmltypes b/src/imports/dialogs/plugins.qmltypes index faf68de909..80eb8bd291 100644 --- a/src/imports/dialogs/plugins.qmltypes +++ b/src/imports/dialogs/plugins.qmltypes @@ -3,39 +3,72 @@ import QtQuick.tooling 1.1 // This file describes the plugin-supplied types contained in the library. // It is used for QML tooling purposes only. // -// This file was auto-generated with the command 'qmlplugindump QtQuick.Dialogs 1.0'. +// This file was auto-generated with the command 'qmlplugindump -notrelocatable QtQuick.Dialogs 1.0'. Module { Component { - name: "QQuickAbstractFileDialog" + name: "QQuickAbstractColorDialog" + prototype: "QQuickAbstractDialog" + Property { name: "showAlphaChannel"; type: "bool" } + Property { name: "color"; type: "QColor" } + Signal { name: "selectionAccepted" } + Method { + name: "setVisible" + Parameter { name: "v"; type: "bool" } + } + Method { + name: "setModality" + Parameter { name: "m"; type: "Qt::WindowModality" } + } + Method { + name: "setTitle" + Parameter { name: "t"; type: "string" } + } + Method { + name: "setColor" + Parameter { name: "arg"; type: "QColor" } + } + Method { + name: "setShowAlphaChannel" + Parameter { name: "arg"; type: "bool" } + } + } + Component { + name: "QQuickAbstractDialog" prototype: "QObject" Property { name: "visible"; type: "bool" } Property { name: "modality"; type: "Qt::WindowModality" } Property { name: "title"; type: "string" } + Property { name: "x"; type: "int" } + Property { name: "y"; type: "int" } + Property { name: "width"; type: "int" } + Property { name: "height"; type: "int" } + Signal { name: "visibilityChanged" } + Signal { name: "geometryChanged" } + Signal { name: "accepted" } + Signal { name: "rejected" } + Method { name: "open" } + Method { name: "close" } + } + Component { + name: "QQuickAbstractFileDialog" + prototype: "QQuickAbstractDialog" Property { name: "selectExisting"; type: "bool" } Property { name: "selectMultiple"; type: "bool" } Property { name: "selectFolder"; type: "bool" } Property { name: "folder"; type: "string" } Property { name: "nameFilters"; type: "QStringList" } Property { name: "selectedNameFilter"; type: "string" } - Property { name: "filePath"; type: "string"; isReadonly: true } - Property { name: "filePaths"; type: "QStringList"; isReadonly: true } - Signal { name: "visibilityChanged" } + Property { name: "fileUrl"; type: "QUrl"; isReadonly: true } + Property { name: "fileUrls"; type: "QList<QUrl>"; isReadonly: true } Signal { name: "filterSelected" } Signal { name: "fileModeChanged" } - Signal { name: "accepted" } - Signal { name: "rejected" } - Method { name: "open" } - Method { name: "close" } + Signal { name: "selectionAccepted" } Method { name: "setVisible" Parameter { name: "v"; type: "bool" } } Method { - name: "setModality" - Parameter { name: "m"; type: "Qt::WindowModality" } - } - Method { name: "setTitle" Parameter { name: "t"; type: "string" } } @@ -65,8 +98,25 @@ Module { } } Component { - name: "QQuickQFileDialog" + name: "QQuickColorDialog" + defaultProperty: "implementation" + prototype: "QQuickAbstractColorDialog" + exports: ["QtQuick.Dialogs/AbstractColorDialog 1.0"] + exportMetaObjectRevisions: [0] + Property { name: "implementation"; type: "QObject"; isPointer: true } + } + Component { + name: "QQuickFileDialog" + defaultProperty: "implementation" prototype: "QQuickAbstractFileDialog" - exports: ["QtQuick.PrivateWidgets/QtFileDialog 1.0"] + exports: ["QtQuick.Dialogs/AbstractFileDialog 1.0"] + exportMetaObjectRevisions: [0] + Property { name: "implementation"; type: "QObject"; isPointer: true } + Method { name: "clearSelection" } + Method { + name: "addSelection" + type: "bool" + Parameter { name: "path"; type: "string" } + } } } diff --git a/src/imports/folderlistmodel/plugins.qmltypes b/src/imports/folderlistmodel/plugins.qmltypes index fabeb9e4b1..20914f4108 100644 --- a/src/imports/folderlistmodel/plugins.qmltypes +++ b/src/imports/folderlistmodel/plugins.qmltypes @@ -3,13 +3,17 @@ import QtQuick.tooling 1.1 // This file describes the plugin-supplied types contained in the library. // It is used for QML tooling purposes only. // -// This file was auto-generated with the command 'qmlplugindump Qt.labs.folderlistmodel 2.0'. +// This file was auto-generated with the command 'qmlplugindump -notrelocatable Qt.labs.folderlistmodel 2.0'. Module { Component { name: "QQuickFolderListModel" prototype: "QAbstractListModel" - exports: ["FolderListModel 1.0", "FolderListModel 2.0"] + exports: [ + "Qt.labs.folderlistmodel/FolderListModel 1.0", + "Qt.labs.folderlistmodel/FolderListModel 2.0" + ] + exportMetaObjectRevisions: [0, 0] Enum { name: "SortField" values: { diff --git a/src/imports/localstorage/plugins.qmltypes b/src/imports/localstorage/plugins.qmltypes index 75b83c762d..ec60a142d4 100644 --- a/src/imports/localstorage/plugins.qmltypes +++ b/src/imports/localstorage/plugins.qmltypes @@ -3,13 +3,14 @@ import QtQuick.tooling 1.1 // This file describes the plugin-supplied types contained in the library. // It is used for QML tooling purposes only. // -// This file was auto-generated with the command 'qmlplugindump QtQuick.LocalStorage 2.0'. +// This file was auto-generated with the command 'qmlplugindump -notrelocatable QtQuick.LocalStorage 2.0'. Module { Component { name: "QQuickLocalStorage" prototype: "QObject" - exports: ["LocalStorage 2.0"] + exports: ["QtQuick.LocalStorage/LocalStorage 2.0"] + exportMetaObjectRevisions: [0] Method { name: "openDatabaseSync" Parameter { name: "args"; type: "QQmlV8Function"; isPointer: true } diff --git a/src/imports/particles/plugins.qmltypes b/src/imports/particles/plugins.qmltypes index 069b561b50..ee948ad7b0 100644 --- a/src/imports/particles/plugins.qmltypes +++ b/src/imports/particles/plugins.qmltypes @@ -3,14 +3,15 @@ import QtQuick.tooling 1.1 // This file describes the plugin-supplied types contained in the library. // It is used for QML tooling purposes only. // -// This file was auto-generated with the command 'qmlplugindump QtQuick.Particles 2.0'. +// This file was auto-generated with the command 'qmlplugindump -notrelocatable QtQuick.Particles 2.0'. Module { Component { name: "QQuickAgeAffector" defaultProperty: "data" prototype: "QQuickParticleAffector" - exports: ["Age 2.0"] + exports: ["QtQuick.Particles/Age 2.0"] + exportMetaObjectRevisions: [0] Property { name: "lifeLeft"; type: "int" } Property { name: "advancePosition"; type: "bool" } Signal { @@ -33,7 +34,8 @@ Module { Component { name: "QQuickAngleDirection" prototype: "QQuickDirection" - exports: ["AngleDirection 2.0"] + exports: ["QtQuick.Particles/AngleDirection 2.0"] + exportMetaObjectRevisions: [0] Property { name: "angle"; type: "double" } Property { name: "magnitude"; type: "double" } Property { name: "angleVariation"; type: "double" } @@ -75,7 +77,8 @@ Module { name: "QQuickAttractorAffector" defaultProperty: "data" prototype: "QQuickParticleAffector" - exports: ["Attractor 2.0"] + exports: ["QtQuick.Particles/Attractor 2.0"] + exportMetaObjectRevisions: [0] Enum { name: "Proportion" values: { @@ -144,14 +147,16 @@ Module { name: "QQuickCumulativeDirection" defaultProperty: "directions" prototype: "QQuickDirection" - exports: ["CumulativeDirection 2.0"] + exports: ["QtQuick.Particles/CumulativeDirection 2.0"] + exportMetaObjectRevisions: [0] Property { name: "directions"; type: "QQuickDirection"; isList: true; isReadonly: true } } Component { name: "QQuickCustomAffector" defaultProperty: "data" prototype: "QQuickParticleAffector" - exports: ["Affector 2.0"] + exports: ["QtQuick.Particles/Affector 2.0"] + exportMetaObjectRevisions: [0] Property { name: "relative"; type: "bool" } Property { name: "position"; type: "QQuickDirection"; isPointer: true } Property { name: "velocity"; type: "QQuickDirection"; isPointer: true } @@ -198,19 +203,22 @@ Module { name: "QQuickCustomParticle" defaultProperty: "data" prototype: "QQuickParticlePainter" - exports: ["CustomParticle 2.0"] + exports: ["QtQuick.Particles/CustomParticle 2.0"] + exportMetaObjectRevisions: [0] Property { name: "fragmentShader"; type: "QByteArray" } Property { name: "vertexShader"; type: "QByteArray" } } Component { name: "QQuickDirection" prototype: "QObject" - exports: ["NullVector 2.0"] + exports: ["QtQuick.Particles/NullVector 2.0"] + exportMetaObjectRevisions: [0] } Component { name: "QQuickEllipseExtruder" prototype: "QQuickParticleExtruder" - exports: ["EllipseShape 2.0"] + exports: ["QtQuick.Particles/EllipseShape 2.0"] + exportMetaObjectRevisions: [0] Property { name: "fill"; type: "bool" } Signal { name: "fillChanged" @@ -225,7 +233,8 @@ Module { name: "QQuickFrictionAffector" defaultProperty: "data" prototype: "QQuickParticleAffector" - exports: ["Friction 2.0"] + exports: ["QtQuick.Particles/Friction 2.0"] + exportMetaObjectRevisions: [0] Property { name: "factor"; type: "double" } Property { name: "threshold"; type: "double" } Signal { @@ -249,7 +258,8 @@ Module { name: "QQuickGravityAffector" defaultProperty: "data" prototype: "QQuickParticleAffector" - exports: ["Gravity 2.0"] + exports: ["QtQuick.Particles/Gravity 2.0"] + exportMetaObjectRevisions: [0] Property { name: "magnitude"; type: "double" } Property { name: "acceleration"; type: "double" } Property { name: "angle"; type: "double" } @@ -278,7 +288,8 @@ Module { name: "QQuickGroupGoalAffector" defaultProperty: "data" prototype: "QQuickParticleAffector" - exports: ["GroupGoal 2.0"] + exports: ["QtQuick.Particles/GroupGoal 2.0"] + exportMetaObjectRevisions: [0] Property { name: "goalState"; type: "string" } Property { name: "jump"; type: "bool" } Signal { @@ -302,7 +313,8 @@ Module { name: "QQuickImageParticle" defaultProperty: "data" prototype: "QQuickParticlePainter" - exports: ["ImageParticle 2.0"] + exports: ["QtQuick.Particles/ImageParticle 2.0"] + exportMetaObjectRevisions: [0] Enum { name: "Status" values: { @@ -480,7 +492,8 @@ Module { name: "QQuickItemParticle" defaultProperty: "data" prototype: "QQuickParticlePainter" - exports: ["ItemParticle 2.0"] + exports: ["QtQuick.Particles/ItemParticle 2.0"] + exportMetaObjectRevisions: [0] attachedType: "QQuickItemParticleAttached" Property { name: "fade"; type: "bool" } Property { name: "delegate"; type: "QQmlComponent"; isPointer: true } @@ -528,7 +541,8 @@ Module { Component { name: "QQuickLineExtruder" prototype: "QQuickParticleExtruder" - exports: ["LineShape 2.0"] + exports: ["QtQuick.Particles/LineShape 2.0"] + exportMetaObjectRevisions: [0] Property { name: "mirrored"; type: "bool" } Signal { name: "mirroredChanged" @@ -542,7 +556,8 @@ Module { Component { name: "QQuickMaskExtruder" prototype: "QQuickParticleExtruder" - exports: ["MaskShape 2.0"] + exports: ["QtQuick.Particles/MaskShape 2.0"] + exportMetaObjectRevisions: [0] Property { name: "source"; type: "QUrl" } Signal { name: "sourceChanged" @@ -557,7 +572,8 @@ Module { name: "QQuickParticleAffector" defaultProperty: "data" prototype: "QQuickItem" - exports: ["ParticleAffector 2.0"] + exports: ["QtQuick.Particles/ParticleAffector 2.0"] + exportMetaObjectRevisions: [0] Property { name: "system"; type: "QQuickParticleSystem"; isPointer: true } Property { name: "groups"; type: "QStringList" } Property { name: "whenCollidingWith"; type: "QStringList" } @@ -623,7 +639,8 @@ Module { name: "QQuickParticleEmitter" defaultProperty: "data" prototype: "QQuickItem" - exports: ["Emitter 2.0"] + exports: ["QtQuick.Particles/Emitter 2.0"] + exportMetaObjectRevisions: [0] Enum { name: "Lifetime" values: { @@ -781,13 +798,15 @@ Module { Component { name: "QQuickParticleExtruder" prototype: "QObject" - exports: ["ParticleExtruder 2.0"] + exports: ["QtQuick.Particles/ParticleExtruder 2.0"] + exportMetaObjectRevisions: [0] } Component { name: "QQuickParticleGroup" defaultProperty: "particleChildren" prototype: "QQuickStochasticState" - exports: ["ParticleGroup 2.0"] + exports: ["QtQuick.Particles/ParticleGroup 2.0"] + exportMetaObjectRevisions: [0] Property { name: "system"; type: "QQuickParticleSystem"; isPointer: true } Property { name: "particleChildren"; type: "QObject"; isList: true; isReadonly: true } Signal { @@ -815,7 +834,8 @@ Module { name: "QQuickParticlePainter" defaultProperty: "data" prototype: "QQuickItem" - exports: ["ParticlePainter 2.0"] + exports: ["QtQuick.Particles/ParticlePainter 2.0"] + exportMetaObjectRevisions: [0] Property { name: "system"; type: "QQuickParticleSystem"; isPointer: true } Property { name: "groups"; type: "QStringList" } Signal { name: "countChanged" } @@ -845,7 +865,8 @@ Module { name: "QQuickParticleSystem" defaultProperty: "data" prototype: "QQuickItem" - exports: ["ParticleSystem 2.0"] + exports: ["QtQuick.Particles/ParticleSystem 2.0"] + exportMetaObjectRevisions: [0] Property { name: "running"; type: "bool" } Property { name: "paused"; type: "bool" } Property { name: "empty"; type: "bool"; isReadonly: true } @@ -881,7 +902,8 @@ Module { Component { name: "QQuickPointDirection" prototype: "QQuickDirection" - exports: ["PointDirection 2.0"] + exports: ["QtQuick.Particles/PointDirection 2.0"] + exportMetaObjectRevisions: [0] Property { name: "x"; type: "double" } Property { name: "y"; type: "double" } Property { name: "xVariation"; type: "double" } @@ -922,7 +944,8 @@ Module { Component { name: "QQuickRectangleExtruder" prototype: "QQuickParticleExtruder" - exports: ["RectangleShape 2.0"] + exports: ["QtQuick.Particles/RectangleShape 2.0"] + exportMetaObjectRevisions: [0] Property { name: "fill"; type: "bool" } Signal { name: "fillChanged" @@ -937,7 +960,8 @@ Module { name: "QQuickSpriteGoalAffector" defaultProperty: "data" prototype: "QQuickParticleAffector" - exports: ["SpriteGoal 2.0"] + exports: ["QtQuick.Particles/SpriteGoal 2.0"] + exportMetaObjectRevisions: [0] Property { name: "goalState"; type: "string" } Property { name: "jump"; type: "bool" } Property { name: "systemStates"; type: "bool" } @@ -969,7 +993,8 @@ Module { Component { name: "QQuickTargetDirection" prototype: "QQuickDirection" - exports: ["TargetDirection 2.0"] + exports: ["QtQuick.Particles/TargetDirection 2.0"] + exportMetaObjectRevisions: [0] Property { name: "targetX"; type: "double" } Property { name: "targetY"; type: "double" } Property { name: "targetItem"; type: "QQuickItem"; isPointer: true } @@ -1038,7 +1063,8 @@ Module { name: "QQuickTrailEmitter" defaultProperty: "data" prototype: "QQuickParticleEmitter" - exports: ["TrailEmitter 2.0"] + exports: ["QtQuick.Particles/TrailEmitter 2.0"] + exportMetaObjectRevisions: [0] Enum { name: "EmitSize" values: { @@ -1100,7 +1126,8 @@ Module { name: "QQuickTurbulenceAffector" defaultProperty: "data" prototype: "QQuickParticleAffector" - exports: ["Turbulence 2.0"] + exports: ["QtQuick.Particles/Turbulence 2.0"] + exportMetaObjectRevisions: [0] Property { name: "strength"; type: "double" } Property { name: "noiseSource"; type: "QUrl" } Signal { @@ -1124,7 +1151,8 @@ Module { name: "QQuickWanderAffector" defaultProperty: "data" prototype: "QQuickParticleAffector" - exports: ["Wander 2.0"] + exports: ["QtQuick.Particles/Wander 2.0"] + exportMetaObjectRevisions: [0] Enum { name: "AffectableParameters" values: { diff --git a/src/imports/testlib/TestCase.qml b/src/imports/testlib/TestCase.qml index 5484d5a96b..7584241ca6 100644 --- a/src/imports/testlib/TestCase.qml +++ b/src/imports/testlib/TestCase.qml @@ -143,7 +143,7 @@ Item { if ("mapFromItem" in o && "mapToItem" in o) { return "declarativeitem"; // @todo improve detection of declarative items } else if ("x" in o && "y" in o && "z" in o) { - return "vector3d"; // Qt3D vector + return "vector3d"; // Qt 3D vector } return "object"; } else if (o instanceof Function) { diff --git a/src/imports/testlib/plugins.qmltypes b/src/imports/testlib/plugins.qmltypes index 5d7c161926..7530e490f3 100644 --- a/src/imports/testlib/plugins.qmltypes +++ b/src/imports/testlib/plugins.qmltypes @@ -3,13 +3,14 @@ import QtQuick.tooling 1.1 // This file describes the plugin-supplied types contained in the library. // It is used for QML tooling purposes only. // -// This file was auto-generated with the command 'qmlplugindump QtTest 1.0'. +// This file was auto-generated with the command 'qmlplugindump -notrelocatable QtTest 1.0'. Module { Component { name: "QuickTestEvent" prototype: "QObject" - exports: ["TestEvent 1.0"] + exports: ["QtTest/TestEvent 1.0"] + exportMetaObjectRevisions: [0] Method { name: "keyPress" type: "bool" @@ -32,6 +33,27 @@ Module { Parameter { name: "delay"; type: "int" } } Method { + name: "keyPressChar" + type: "bool" + Parameter { name: "character"; type: "string" } + Parameter { name: "modifiers"; type: "int" } + Parameter { name: "delay"; type: "int" } + } + Method { + name: "keyReleaseChar" + type: "bool" + Parameter { name: "character"; type: "string" } + Parameter { name: "modifiers"; type: "int" } + Parameter { name: "delay"; type: "int" } + } + Method { + name: "keyClickChar" + type: "bool" + Parameter { name: "character"; type: "string" } + Parameter { name: "modifiers"; type: "int" } + Parameter { name: "delay"; type: "int" } + } + Method { name: "mousePress" type: "bool" Parameter { name: "item"; type: "QObject"; isPointer: true } @@ -96,7 +118,8 @@ Module { Component { name: "QuickTestResult" prototype: "QObject" - exports: ["TestResult 1.0"] + exports: ["QtTest/TestResult 1.0"] + exportMetaObjectRevisions: [0] Enum { name: "RunMode" values: { @@ -230,7 +253,8 @@ Module { Component { name: "QuickTestUtil" prototype: "QObject" - exports: ["TestUtil 1.0"] + exports: ["QtTest/TestUtil 1.0"] + exportMetaObjectRevisions: [0] Property { name: "printAvailableFunctions"; type: "bool"; isReadonly: true } Property { name: "dragThreshold"; type: "int"; isReadonly: true } Method { diff --git a/src/imports/widgets/plugins.qmltypes b/src/imports/widgets/plugins.qmltypes index f9fe1f722c..583a36a357 100644 --- a/src/imports/widgets/plugins.qmltypes +++ b/src/imports/widgets/plugins.qmltypes @@ -3,39 +3,72 @@ import QtQuick.tooling 1.1 // This file describes the plugin-supplied types contained in the library. // It is used for QML tooling purposes only. // -// This file was auto-generated with the command 'qmlplugindump QtQuick.PrivateWidgets 1.0'. +// This file was auto-generated with the command 'qmlplugindump -notrelocatable QtQuick.PrivateWidgets 1.0'. Module { Component { - name: "QQuickAbstractFileDialog" + name: "QQuickAbstractColorDialog" + prototype: "QQuickAbstractDialog" + Property { name: "showAlphaChannel"; type: "bool" } + Property { name: "color"; type: "QColor" } + Signal { name: "selectionAccepted" } + Method { + name: "setVisible" + Parameter { name: "v"; type: "bool" } + } + Method { + name: "setModality" + Parameter { name: "m"; type: "Qt::WindowModality" } + } + Method { + name: "setTitle" + Parameter { name: "t"; type: "string" } + } + Method { + name: "setColor" + Parameter { name: "arg"; type: "QColor" } + } + Method { + name: "setShowAlphaChannel" + Parameter { name: "arg"; type: "bool" } + } + } + Component { + name: "QQuickAbstractDialog" prototype: "QObject" Property { name: "visible"; type: "bool" } Property { name: "modality"; type: "Qt::WindowModality" } Property { name: "title"; type: "string" } + Property { name: "x"; type: "int" } + Property { name: "y"; type: "int" } + Property { name: "width"; type: "int" } + Property { name: "height"; type: "int" } + Signal { name: "visibilityChanged" } + Signal { name: "geometryChanged" } + Signal { name: "accepted" } + Signal { name: "rejected" } + Method { name: "open" } + Method { name: "close" } + } + Component { + name: "QQuickAbstractFileDialog" + prototype: "QQuickAbstractDialog" Property { name: "selectExisting"; type: "bool" } Property { name: "selectMultiple"; type: "bool" } Property { name: "selectFolder"; type: "bool" } Property { name: "folder"; type: "string" } Property { name: "nameFilters"; type: "QStringList" } Property { name: "selectedNameFilter"; type: "string" } - Property { name: "filePath"; type: "string"; isReadonly: true } - Property { name: "filePaths"; type: "QStringList"; isReadonly: true } - Signal { name: "visibilityChanged" } + Property { name: "fileUrl"; type: "QUrl"; isReadonly: true } + Property { name: "fileUrls"; type: "QList<QUrl>"; isReadonly: true } Signal { name: "filterSelected" } Signal { name: "fileModeChanged" } - Signal { name: "accepted" } - Signal { name: "rejected" } - Method { name: "open" } - Method { name: "close" } + Signal { name: "selectionAccepted" } Method { name: "setVisible" Parameter { name: "v"; type: "bool" } } Method { - name: "setModality" - Parameter { name: "m"; type: "Qt::WindowModality" } - } - Method { name: "setTitle" Parameter { name: "t"; type: "string" } } @@ -65,8 +98,15 @@ Module { } } Component { + name: "QQuickQColorDialog" + prototype: "QQuickAbstractColorDialog" + exports: ["QtQuick.PrivateWidgets/QtColorDialog 1.0"] + exportMetaObjectRevisions: [0] + } + Component { name: "QQuickQFileDialog" prototype: "QQuickAbstractFileDialog" - exports: ["QtFileDialog 1.0"] + exports: ["QtQuick.PrivateWidgets/QtFileDialog 1.0"] + exportMetaObjectRevisions: [0] } } diff --git a/src/imports/widgets/widgetsplugin.cpp b/src/imports/widgets/widgetsplugin.cpp index a29c9b3609..be9d59f346 100644 --- a/src/imports/widgets/widgetsplugin.cpp +++ b/src/imports/widgets/widgetsplugin.cpp @@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE \brief Provides QML types for certain QWidgets \internal - This QML module contains types which should not be depended upon in QtQuick + This QML module contains types which should not be depended upon in Qt Quick applications, but are available if the Widgets module is linked. It is recommended to load components from this module conditionally, if at all, and to provide fallback implementations in case they fail to load. diff --git a/src/imports/xmllistmodel/plugins.qmltypes b/src/imports/xmllistmodel/plugins.qmltypes index 281a2adf05..2a431ebf81 100644 --- a/src/imports/xmllistmodel/plugins.qmltypes +++ b/src/imports/xmllistmodel/plugins.qmltypes @@ -3,14 +3,15 @@ import QtQuick.tooling 1.1 // This file describes the plugin-supplied types contained in the library. // It is used for QML tooling purposes only. // -// This file was auto-generated with the command 'qmlplugindump QtQuick.XmlListModel 2.0'. +// This file was auto-generated with the command 'qmlplugindump -notrelocatable QtQuick.XmlListModel 2.0'. Module { Component { name: "QQuickXmlListModel" defaultProperty: "roles" prototype: "QAbstractListModel" - exports: ["XmlListModel 2.0"] + exports: ["QtQuick.XmlListModel/XmlListModel 2.0"] + exportMetaObjectRevisions: [0] Enum { name: "Status" values: { @@ -47,7 +48,8 @@ Module { Component { name: "QQuickXmlListModelRole" prototype: "QObject" - exports: ["XmlRole 2.0"] + exports: ["QtQuick.XmlListModel/XmlRole 2.0"] + exportMetaObjectRevisions: [0] Property { name: "name"; type: "string" } Property { name: "query"; type: "string" } Property { name: "isKey"; type: "bool" } diff --git a/src/particles/qquickmaskextruder.cpp b/src/particles/qquickmaskextruder.cpp index 3153e2b7d0..f8ed042a9b 100644 --- a/src/particles/qquickmaskextruder.cpp +++ b/src/particles/qquickmaskextruder.cpp @@ -114,12 +114,18 @@ bool QQuickMaskExtruder::contains(const QRectF &bounds, const QPointF &point) ensureInitialized(bounds);//###Current usage patterns WILL lead to different bounds/r calls. Separate list? if (m_img.isNull()) return false; - QPoint p = point.toPoint() - bounds.topLeft().toPoint(); + + QPointF pt = point - bounds.topLeft(); + QPoint p(pt.x() * m_img.width() / bounds.width(), + pt.y() * m_img.height() / bounds.height()); return m_img.rect().contains(p) && (bool)m_img.pixelIndex(p); } -void QQuickMaskExtruder::ensureInitialized(const QRectF &r) +void QQuickMaskExtruder::ensureInitialized(const QRectF &rf) { + // Convert to integer coords to avoid comparing floats and ints which would + // often result in rounding errors. + QRect r = rf.toRect(); if (m_lastWidth == r.width() && m_lastHeight == r.height()) return;//Same as before if (!m_pix.isReady()) @@ -129,13 +135,22 @@ void QQuickMaskExtruder::ensureInitialized(const QRectF &r) m_mask.clear(); - m_img = m_pix.image().createAlphaMask(); - m_img = m_img.convertToFormat(QImage::Format_Mono);//Else LSB, but I think that's easier - m_img = m_img.scaled(r.size().toSize());//TODO: Do they need aspect ratio stuff? Or tiling? - for (int i=0; i<r.width(); i++){ - for (int j=0; j<r.height(); j++){ - if (m_img.pixelIndex(i,j))//Direct bit manipulation is presumably more efficient - m_mask << QPointF(i,j); + m_img = m_pix.image(); + // Image will in all likelyhood be in this format already, so + // no extra memory or conversion takes place + if (m_img.format() != QImage::Format_ARGB32 && m_img.format() != QImage::Format_ARGB32_Premultiplied) + m_img = m_img.convertToFormat(QImage::Format_ARGB32_Premultiplied); + + // resample on the fly using 16-bit + int sx = (m_img.width() << 16) / r.width(); + int sy = (m_img.height() << 16) / r.height(); + int w = r.width(); + int h = r.height(); + for (int y=0; y<h; ++y) { + const uint *sl = (const uint *) m_img.constScanLine((y * sy) >> 16); + for (int x=0; x<w; ++x) { + if (sl[(x * sx) >> 16] & 0xff000000) + m_mask << QPointF(x, y); } } } diff --git a/src/particles/qquickparticlepainter.cpp b/src/particles/qquickparticlepainter.cpp index a84f4a66f4..694391a701 100644 --- a/src/particles/qquickparticlepainter.cpp +++ b/src/particles/qquickparticlepainter.cpp @@ -80,8 +80,8 @@ void QQuickParticlePainter::itemChange(ItemChange change, const ItemChangeData & m_window = data.window; if (m_window) connect(m_window, SIGNAL(sceneGraphInvalidated()), this, SLOT(sceneGraphInvalidated()), Qt::DirectConnection); - } + QQuickItem::itemChange(change, data); } void QQuickParticlePainter::componentComplete() diff --git a/src/plugins/accessible/quick/qaccessiblequickitem.cpp b/src/plugins/accessible/quick/qaccessiblequickitem.cpp index da70fe0424..12884ffa4f 100644 --- a/src/plugins/accessible/quick/qaccessiblequickitem.cpp +++ b/src/plugins/accessible/quick/qaccessiblequickitem.cpp @@ -40,16 +40,20 @@ ****************************************************************************/ #include "qaccessiblequickitem.h" + +#include <QtGui/qtextdocument.h> + #include "QtQuick/private/qquickitem_p.h" #include "QtQuick/private/qquicktext_p.h" #include "QtQuick/private/qquickaccessibleattached_p.h" +#include "QtQuick/qquicktextdocument.h" QT_BEGIN_NAMESPACE #ifndef QT_NO_ACCESSIBILITY QAccessibleQuickItem::QAccessibleQuickItem(QQuickItem *item) - : QQmlAccessible(item) + : QQmlAccessible(item), m_doc(textDocument()) { } @@ -86,7 +90,6 @@ bool QAccessibleQuickItem::clipsChildren() const return static_cast<QQuickItem *>(item())->clip(); } - QAccessibleInterface *QAccessibleQuickItem::parent() const { QQuickItem *parent = item()->parentItem(); @@ -231,10 +234,11 @@ QString QAccessibleQuickItem::text(QAccessible::Text textType) const // the following block handles item-specific behavior if (role() == QAccessible::EditableText) { if (textType == QAccessible::Value) { + if (QTextDocument *doc = textDocument()) { + return doc->toPlainText(); + } QVariant text = object()->property("text"); return text.toString(); - } else if (textType == QAccessible::Name) { - return object()->objectName(); } } @@ -310,6 +314,143 @@ QRect itemScreenRect(QQuickItem *item) return QRect(screenPos, itemSize); } +QTextDocument *QAccessibleQuickItem::textDocument() const +{ + QVariant docVariant = item()->property("textDocument"); + if (docVariant.canConvert<QQuickTextDocument*>()) { + QQuickTextDocument *qqdoc = docVariant.value<QQuickTextDocument*>(); + return qqdoc->textDocument(); + } + return 0; +} + +int QAccessibleQuickItem::characterCount() const +{ + if (m_doc) { + QTextCursor cursor = QTextCursor(m_doc); + cursor.movePosition(QTextCursor::End); + return cursor.position(); + } + return text(QAccessible::Value).size(); +} + +int QAccessibleQuickItem::cursorPosition() const +{ + QVariant pos = item()->property("cursorPosition"); + return pos.toInt(); +} + +void QAccessibleQuickItem::setCursorPosition(int position) +{ + item()->setProperty("cursorPosition", position); +} + +QString QAccessibleQuickItem::text(int startOffset, int endOffset) const +{ + if (m_doc) { + QTextCursor cursor = QTextCursor(m_doc); + cursor.setPosition(startOffset); + cursor.setPosition(endOffset, QTextCursor::KeepAnchor); + return cursor.selectedText(); + } + return text(QAccessible::Value).mid(startOffset, endOffset - startOffset); +} + +QString QAccessibleQuickItem::textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const +{ + Q_ASSERT(startOffset); + Q_ASSERT(endOffset); + + if (m_doc) { + QTextCursor cursor = QTextCursor(m_doc); + cursor.setPosition(offset); + QPair<int, int> boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType); + cursor.setPosition(boundaries.first - 1); + boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType); + + *startOffset = boundaries.first; + *endOffset = boundaries.second; + + return text(boundaries.first, boundaries.second); + } else { + return QAccessibleTextInterface::textBeforeOffset(offset, boundaryType, startOffset, endOffset); + } +} + +QString QAccessibleQuickItem::textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const +{ + Q_ASSERT(startOffset); + Q_ASSERT(endOffset); + + if (m_doc) { + QTextCursor cursor = QTextCursor(m_doc); + cursor.setPosition(offset); + QPair<int, int> boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType); + cursor.setPosition(boundaries.second); + boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType); + + *startOffset = boundaries.first; + *endOffset = boundaries.second; + + return text(boundaries.first, boundaries.second); + } else { + return QAccessibleTextInterface::textAfterOffset(offset, boundaryType, startOffset, endOffset); + } +} + +QString QAccessibleQuickItem::textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const +{ + Q_ASSERT(startOffset); + Q_ASSERT(endOffset); + + if (m_doc) { + QTextCursor cursor = QTextCursor(m_doc); + cursor.setPosition(offset); + QPair<int, int> boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType); + + *startOffset = boundaries.first; + *endOffset = boundaries.second; + return text(boundaries.first, boundaries.second); + } else { + return QAccessibleTextInterface::textAtOffset(offset, boundaryType, startOffset, endOffset); + } +} + +void QAccessibleQuickItem::selection(int selectionIndex, int *startOffset, int *endOffset) const +{ + if (selectionIndex == 0) { + *startOffset = item()->property("selectionStart").toInt(); + *endOffset = item()->property("selectionEnd").toInt(); + } else { + *startOffset = 0; + *endOffset = 0; + } +} + +int QAccessibleQuickItem::selectionCount() const +{ + if (item()->property("selectionStart").toInt() != item()->property("selectionEnd").toInt()) + return 1; + return 0; +} + +void QAccessibleQuickItem::addSelection(int /* startOffset */, int /* endOffset */) +{ + +} +void QAccessibleQuickItem::removeSelection(int /* selectionIndex */) +{ + +} +void QAccessibleQuickItem::setSelection(int /* selectionIndex */, int /* startOffset */, int /* endOffset */) +{ + +} + + #endif // QT_NO_ACCESSIBILITY QT_END_NAMESPACE diff --git a/src/plugins/accessible/quick/qaccessiblequickitem.h b/src/plugins/accessible/quick/qaccessiblequickitem.h index e82b2f84d2..d9eb652030 100644 --- a/src/plugins/accessible/quick/qaccessiblequickitem.h +++ b/src/plugins/accessible/quick/qaccessiblequickitem.h @@ -50,6 +50,8 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_ACCESSIBILITY +class QTextDocument; + class QAccessibleQuickItem : public QQmlAccessible, public QAccessibleValueInterface, public QAccessibleTextInterface { public: @@ -81,37 +83,41 @@ public: // Text Interface - // selection (ignored for now) - void selection(int /* selectionIndex */, int *startOffset, int *endOffset) const { *startOffset = 0; *endOffset = 0; } - int selectionCount() const { return 0; } - void addSelection(int /* startOffset */, int /* endOffset */) {} - void removeSelection(int /* selectionIndex */) {} - void setSelection(int /* selectionIndex */, int /* startOffset */, int /* endOffset */) {} + void selection(int selectionIndex, int *startOffset, int *endOffset) const; + int selectionCount() const; + void addSelection(int startOffset, int endOffset); + void removeSelection(int selectionIndex); + void setSelection(int selectionIndex, int startOffset, int endOffset); // cursor - int cursorPosition() const { return 0; } - void setCursorPosition(int /* position */) {} + int cursorPosition() const; + void setCursorPosition(int position); // text - QString text(int startOffset, int endOffset) const { return text(QAccessible::Name).mid(startOffset, endOffset - startOffset); } -// QString textBeforeOffset(int offset, QAccessible2::BoundaryType boundaryType, -// int *startOffset, int *endOffset) const; -// QString textAfterOffset(int offset, QAccessible2::BoundaryType boundaryType, -// int *startOffset, int *endOffset) const; -// QString textAtOffset(int offset, QAccessible2::BoundaryType boundaryType, -// int *startOffset, int *endOffset) const; - int characterCount() const { return text(QAccessible::Name).count(); } + QString text(int startOffset, int endOffset) const; + QString textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const; + QString textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const; + QString textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const; + int characterCount() const; // character <-> geometry QRect characterRect(int /* offset */) const { return QRect(); } int offsetAtPoint(const QPoint & /* point */) const { return -1; } void scrollToSubstring(int /* startIndex */, int /* endIndex */) {} - QString attributes(int /* offset */, int * /* startOffset */, int * /* endOffset */) const { return QString(); } + QString attributes(int /* offset */, int *startOffset, int *endOffset) const { *startOffset = 0; *endOffset = 0; return QString(); } + + QTextDocument *textDocument() const; protected: QQuickItem *item() const { return static_cast<QQuickItem*>(object()); } void *interface_cast(QAccessible::InterfaceType t); + +private: + QTextDocument *m_doc; }; QRect itemScreenRect(QQuickItem *item); diff --git a/src/plugins/accessible/shared/qqmlaccessible.cpp b/src/plugins/accessible/shared/qqmlaccessible.cpp index 3ee443c98f..d08f9bdb2c 100644 --- a/src/plugins/accessible/shared/qqmlaccessible.cpp +++ b/src/plugins/accessible/shared/qqmlaccessible.cpp @@ -154,7 +154,7 @@ void QQmlAccessible::doAction(const QString &actionName) return; } - // Role-specific default action handling follows. Items are excepted to provide + // Role-specific default action handling follows. Items are expected to provide // properties according to role conventions. These will then be read and/or updated // by the accessibility system. // Checkable roles : checked diff --git a/src/plugins/accessible/shared/qqmlaccessible.h b/src/plugins/accessible/shared/qqmlaccessible.h index c6ac4e49dd..5280c78485 100644 --- a/src/plugins/accessible/shared/qqmlaccessible.h +++ b/src/plugins/accessible/shared/qqmlaccessible.h @@ -54,8 +54,8 @@ QT_BEGIN_NAMESPACE -- Declarative Accessibility Overview. -- * Item interface classes: - QAccessibleDeclarativeItem for QtQuick1 - QAccessibleQuickItem for for QtQuick2 + QAccessibleDeclarativeItem for Qt Quick 1 + QAccessibleQuickItem for for Qt Quick 2 Common base class: QQmlAccessible * View interface classes. diff --git a/src/qml/debugger/qqmldebugserver.cpp b/src/qml/debugger/qqmldebugserver.cpp index e263343b0d..dcb553912d 100644 --- a/src/qml/debugger/qqmldebugserver.cpp +++ b/src/qml/debugger/qqmldebugserver.cpp @@ -102,9 +102,8 @@ public: bool gotHello; bool blockingMode; - QMutex messageArrivedMutex; - QWaitCondition messageArrivedCondition; - QStringList waitingForMessageNames; + QMutex helloMutex; + QWaitCondition helloCondition; QQmlDebugServerThread *thread; QPluginLoader loader; QAtomicInt changeServiceStateCalls; @@ -331,11 +330,11 @@ QQmlDebugServer *QQmlDebugServer::instance() QQmlDebugServerPrivate *d = qQmlDebugServer->d_func(); d->blockingMode = block; - QMutexLocker locker(&d->messageArrivedMutex); + QMutexLocker locker(&d->helloMutex); thread->start(); if (d->blockingMode) - d->messageArrivedCondition.wait(&d->messageArrivedMutex); + d->helloCondition.wait(&d->helloMutex); } else { qWarning() << QString(QLatin1String( @@ -447,7 +446,8 @@ void QQmlDebugServer::receiveMessage(const QByteArray &message) d->_q_changeServiceState(iter.value()->name(), newState); } - d->messageArrivedCondition.wakeAll(); + QMutexLocker helloLock(&d->helloMutex); + d->helloCondition.wakeAll(); } else if (op == 1) { @@ -487,9 +487,6 @@ void QQmlDebugServer::receiveMessage(const QByteArray &message) qWarning() << "QML Debugger: Message received for missing plugin" << name << '.'; } else { (*iter)->messageReceived(message); - - if (d->waitingForMessageNames.removeOne(name)) - d->messageArrivedCondition.wakeAll(); } } else { qWarning("QML Debugger: Invalid hello message."); diff --git a/src/qml/debugger/qv8debugservice.cpp b/src/qml/debugger/qv8debugservice.cpp index f41907a032..9045b4b50e 100644 --- a/src/qml/debugger/qv8debugservice.cpp +++ b/src/qml/debugger/qv8debugservice.cpp @@ -107,7 +107,8 @@ class QV8DebugServicePrivate : public QQmlDebugServicePrivate { public: QV8DebugServicePrivate() - : engine(0) + : engine(0), + debugIsolate(0) { } @@ -119,6 +120,7 @@ public: QWaitCondition initializeCondition; QStringList breakOnSignals; const QV8Engine *engine; + v8::Isolate *debugIsolate; }; QV8DebugService::QV8DebugService(QObject *parent) @@ -186,6 +188,9 @@ void QV8DebugService::signalEmitted(const QString &signal) // executed in the gui thread void QV8DebugService::init() { + Q_D(QV8DebugService); + if (!d->debugIsolate) + d->debugIsolate = v8::Isolate::GetCurrent(); v8::Debug::SetMessageHandler2(DebugMessageHandler); v8::Debug::SetDebugMessageDispatchHandler(DebugMessageDispatchHandler); QV4Compiler::enableV4(false); @@ -267,7 +272,8 @@ void QV8DebugService::messageReceived(const QByteArray &message) void QV8DebugService::sendDebugMessage(const QString &message) { - v8::Debug::SendCommand(message.utf16(), message.size()); + Q_D(QV8DebugService); + v8::Debug::SendCommand(message.utf16(), message.size(), 0, d->debugIsolate); } void QV8DebugService::processDebugMessages() diff --git a/src/qml/doc/snippets/qml/imports/merged-named-imports.qml b/src/qml/doc/snippets/qml/imports/merged-named-imports.qml index c95d9e66eb..65e2bfd4ce 100644 --- a/src/qml/doc/snippets/qml/imports/merged-named-imports.qml +++ b/src/qml/doc/snippets/qml/imports/merged-named-imports.qml @@ -39,9 +39,16 @@ ****************************************************************************/ //! [imports] -import QtQuick 2.0 as Nokia -import Ovi 1.0 as Nokia -//! [imports] +import QtQuick 2.0 as Project +import QtMultimedia 5.0 as Project + +Project.Rectangle { + width: 100; height: 50 -Item { + Project.Audio { + source: "music.wav" + autoPlay: true + } } +//! [imports] + diff --git a/src/qml/doc/snippets/qml/qtbinding/resources/example.qdoc b/src/qml/doc/snippets/qml/qtbinding/resources/example.qdoc new file mode 100644 index 0000000000..c3b85ce15a --- /dev/null +++ b/src/qml/doc/snippets/qml/qtbinding/resources/example.qdoc @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//![0] +<!DOCTYPE RCC> +<RCC version="1.0"> + +<qresource prefix="/"> + <file>main.qml</file> + <file>images/background.png</file> +</qresource> + +</RCC> +//![0] diff --git a/src/qml/doc/snippets/qml/qtbinding/resources/example.qrc b/src/qml/doc/snippets/qml/qtbinding/resources/example.qrc deleted file mode 100644 index 5e4941512b..0000000000 --- a/src/qml/doc/snippets/qml/qtbinding/resources/example.qrc +++ /dev/null @@ -1,10 +0,0 @@ -<!DOCTYPE RCC> -<RCC version="1.0"> - -<qresource prefix="/"> - <file>main.qml</file> - <file>images/background.png</file> -</qresource> - -</RCC> - diff --git a/src/qml/doc/src/cppclasses/topic.qdoc b/src/qml/doc/src/cppclasses/topic.qdoc index 8b97048c03..66a374e811 100644 --- a/src/qml/doc/src/cppclasses/topic.qdoc +++ b/src/qml/doc/src/cppclasses/topic.qdoc @@ -29,7 +29,7 @@ \title Important C++ Classes Provided By The Qt QML Module \brief Overview of the C++ classes provided by the Qt QML module -The Qt QML module provides C++ classes which implement the QML framework. +The \l{Qt QML} module provides C++ classes which implement the QML framework. Clients can use these classes to interact with the QML run-time (for example, by injecting data or invoking methods on objects), and to instantiate a hierarchy of objects from a QML document. The Qt QML module provides more @@ -113,4 +113,20 @@ engine. See the \l{QQmlExpression} class documentation for in depth information about how to use QQmlExpression in an application. +\section1 Usage of the Classes within QML Applications + +These pages describe how to create QML applications which interact with the +C++ classes: + +\list +\li \l{qtqml-cppintegration-topic.html}{Integrating QML and C++} + \list + \li \l{qtqml-cppintegration-exposecppattributes.html}{Exposing Attributes of C++ Classes to QML} + \li \l{qtqml-cppintegration-definetypes.html}{Defining QML Types from C++} + \li \l{qtqml-cppintegration-contextproperties.html}{Embedding C++ Objects into QML with Context Properties} + \li \l{qtqml-cppintegration-interactqmlfromcpp.html}{Interacting with QML Objects from C++} + \li \l{qtqml-cppintegration-data.html}{Data Type Conversion Between QML and C++} + \endlist +\endlist + */ diff --git a/src/qml/doc/src/cppintegration/data.qdoc b/src/qml/doc/src/cppintegration/data.qdoc index ba8ad47bab..dc1b4cae9c 100644 --- a/src/qml/doc/src/cppintegration/data.qdoc +++ b/src/qml/doc/src/cppintegration/data.qdoc @@ -119,9 +119,9 @@ when passed from C++ to QML and vice-versa: \li \l enumeration \endtable -(Note that classes provided by the QtGui module, such as QColor, QFont, -QQuaternion and QMatrix4x4, are only available from QML when the \l QtQuick -module is imported.) +\note Classes provided by the \l {Qt GUI} module, such as QColor, QFont, +QQuaternion and QMatrix4x4, are only available from QML when the \l {Qt Quick} +module is included. As a convenience, many of these types can be specified in QML by string values, or by a related method provided by the \l {QML:Qt} object. For example, the \l diff --git a/src/qml/doc/src/cppintegration/definetypes.qdoc b/src/qml/doc/src/cppintegration/definetypes.qdoc index b8879ebb04..995fb1bce8 100644 --- a/src/qml/doc/src/cppintegration/definetypes.qdoc +++ b/src/qml/doc/src/cppintegration/definetypes.qdoc @@ -291,7 +291,7 @@ qmlRegisterRevision<BaseType,1>("MyTypes", 1, 1); \endcode This is useful when deriving from base classes provided by other authors, -e.g. when extending classes from the QtQuick library. +e.g. when extending classes from the Qt Quick module. \section1 Defining QML-Specific Types and Attributes @@ -675,19 +675,19 @@ to be declared for an item without explicitly assigning them to the \l{Item::}{children} property.) -\section2 Defining Visual Items with the QtQuick Module +\section2 Defining Visual Items with the Qt Quick Module -When building user interfaces with the QtQuick module, all QML objects that are +When building user interfaces with the \l {Qt Quick} module, all QML objects that are to be visually rendered must derive from the \l Item type, as it is the base -type for all visual objects in the QtQuick module. This \l Item type is -implemented by the QQuickItem C++ class, which is provided as part of the -QtQuick C++ module. Therefore, this class should be subclassed when it is +type for all visual objects in \l {Qt Quick}. This \l Item type is +implemented by the QQuickItem C++ class, which is provided by the +\l {Qt Quick} module. Therefore, this class should be subclassed when it is necessary to implement a visual type in C++ that can be integrated into a QML-based user interface. See the QQuickItem documentation for more information. Additionally, the \l{Writing QML Extensions with C++} tutorial demonstrates how a QQuickItem-based -visual item can be implemented in C++ and integrated into a QtQuick-based user +visual item can be implemented in C++ and integrated into a Qt Quick-based user interface. diff --git a/src/qml/doc/src/cppintegration/extending-tutorial.qdoc b/src/qml/doc/src/cppintegration/extending-tutorial.qdoc index ffa36c31ee..763e72447d 100644 --- a/src/qml/doc/src/cppintegration/extending-tutorial.qdoc +++ b/src/qml/doc/src/cppintegration/extending-tutorial.qdoc @@ -30,7 +30,7 @@ \title Writing QML Extensions with C++ \brief tutorial about extending QML with Qt C++ -The \l Qt QML} C++ module provides a set of APIs for extending QML through +The \l {Qt QML} module provides a set of APIs for extending QML through C++ extensions. You can write extensions to add your own QML types, extend existing Qt types, or call C/C++ functions that are not accessible from ordinary QML code. diff --git a/src/qml/doc/src/cppintegration/topic.qdoc b/src/qml/doc/src/cppintegration/topic.qdoc index 41645e2379..4d12ab9d08 100644 --- a/src/qml/doc/src/cppintegration/topic.qdoc +++ b/src/qml/doc/src/cppintegration/topic.qdoc @@ -29,7 +29,7 @@ \title Integrating QML and C++ \brief Description of how to integrate QML and C++ code -QML is designed to be easily extensible through C++ code. The classes in the \l {Qt QML} C++ module +QML is designed to be easily extensible through C++ code. The classes in the \l {Qt QML} module enables QML objects to be loaded and manipulated from C++, and the nature of QML engine's integration with Qt's \l{Meta Object System}{meta object system} enables C++ functionality to be invoked directly from QML. This allows the development of hybrid applications which are implemented @@ -43,7 +43,7 @@ with QML and JavaScript within \l{qtqml-documents-topic.html}{QML documents}, an C++ \li Use and invoke some C++ functionality from QML (for example, to invoke your application logic, use a data model implemented in C++, or call some functions in a third-party C++ library) -\li Access functionality in the \l {Qt QML} or QtQuick C++ API (for example, to dynamically generate +\li Access functionality in the \l {Qt QML} or \l {Qt Quick} C++ API (for example, to dynamically generate images using QQuickImageProvider) \li Implement your own \l{qtqml-typesystem-objecttypes.html}{QML object types} from C++ \unicode{0x2014} whether for use within your own specific application, or for distribution to others diff --git a/src/qml/doc/src/javascript/dynamicobjectcreation.qdoc b/src/qml/doc/src/javascript/dynamicobjectcreation.qdoc index 09faa61672..421b180f7b 100644 --- a/src/qml/doc/src/javascript/dynamicobjectcreation.qdoc +++ b/src/qml/doc/src/javascript/dynamicobjectcreation.qdoc @@ -66,7 +66,7 @@ can take one or two arguments: \li The first is the parent for the new object. The parent can be a graphical object (i.e. of the \l Item type) or non-graphical object (i.e. of the \l QtObject or C++ QObject type). Only graphical objects with graphical - parent objects will be rendered to the QtQuick visual canvas. If you wish + parent objects will be rendered to the \l {Qt Quick} visual canvas. If you wish to set the parent later you can safely pass \c null to this function. \li The second is optional and is a map of property-value pairs that define initial any property values for the object. Property values specified by @@ -109,7 +109,7 @@ the \c finishCreation() function and call \l {Component::createObject()} Notice in both instances, \l {Component::createObject()}{createObject()} is called with \c appWindow passed as the parent argument, since the dynamically -created object is a visual (QtQuick) object. The created object will become a +created object is a visual (Qt Quick) object. The created object will become a child of the \c appWindow object in \c main.qml, and appear in the scene. When using files with relative paths, the path should diff --git a/src/qml/doc/src/javascript/imports.qdoc b/src/qml/doc/src/javascript/imports.qdoc index 800091689c..f4d7f7dc08 100644 --- a/src/qml/doc/src/javascript/imports.qdoc +++ b/src/qml/doc/src/javascript/imports.qdoc @@ -71,13 +71,13 @@ parameters and return values when calling such functions from QML. \section1 Imports Within JavaScript Resources -In QtQuick 2.0, support has been added to allow JavaScript resources to import +In \c {QtQuick 2.0}, support has been added to allow JavaScript resources to import other JavaScript resources and also QML type namespaces using a variation of the standard QML import syntax (where all of the previously described rules and qualifications apply). Due to the ability of a JavaScript resource to import another script or QML -module in this fashion in QtQuick 2.0, some extra semantics are defined: +module in this fashion in \c {QtQuick 2.0}, some extra semantics are defined: \list \li a script with imports will not inherit imports from the QML document which imported it (so accessing Component.errorString will fail, for example) \li a script without imports will inherit imports from the QML document which imported it (so accessing Component.errorString will succeed, for example) diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc index 5db275407d..976403adea 100644 --- a/src/qml/doc/src/qmlfunctions.qdoc +++ b/src/qml/doc/src/qmlfunctions.qdoc @@ -392,7 +392,7 @@ url must be an absolute URL, i.e. url.isRelative() == false. Normally QML files can be loaded as types directly from other QML files, or using a qmldir file. This function allows - registration of files to types from a C++ module, such as when the type mapping needs to be procedurally determined at startup. + registration of files to types from C++ code, such as when the type mapping needs to be procedurally determined at startup. #include <QtQml> to use this function. diff --git a/src/qml/doc/src/documents/definetypes.qdoc b/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc index b9df6a4381..4e1d4a2c86 100644 --- a/src/qml/doc/src/documents/definetypes.qdoc +++ b/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc @@ -29,7 +29,7 @@ \title Defining Object Types through QML Documents \brief Description of how a QML document is a reusable type definition -One of the core features of QML is that it enables QML object types to be easily defined in a lightweight manner through QML documents to suit the needs of individual QML applications. The standard QtQuick module provides various types like \l Rectangle, \l Text and \l Image for building a QML application; beyond these, you can easily define your own QML types to be reused within your application. This ability to create your own types forms the building blocks of any QML application. +One of the core features of QML is that it enables QML object types to be easily defined in a lightweight manner through QML documents to suit the needs of individual QML applications. The standard \l {Qt Quick} module provides various types like \l Rectangle, \l Text and \l Image for building a QML application; beyond these, you can easily define your own QML types to be reused within your application. This ability to create your own types forms the building blocks of any QML application. \section1 Defining an Object Type with a QML File diff --git a/src/qml/doc/src/documents/networktransparency.qdoc b/src/qml/doc/src/qmllanguageref/documents/networktransparency.qdoc index ea46b3381e..ea46b3381e 100644 --- a/src/qml/doc/src/documents/networktransparency.qdoc +++ b/src/qml/doc/src/qmllanguageref/documents/networktransparency.qdoc diff --git a/src/qml/doc/src/documents/scope.qdoc b/src/qml/doc/src/qmllanguageref/documents/scope.qdoc index 9da77a4905..9da77a4905 100644 --- a/src/qml/doc/src/documents/scope.qdoc +++ b/src/qml/doc/src/qmllanguageref/documents/scope.qdoc diff --git a/src/qml/doc/src/documents/structure.qdoc b/src/qml/doc/src/qmllanguageref/documents/structure.qdoc index c8176f7e0f..c8176f7e0f 100644 --- a/src/qml/doc/src/documents/structure.qdoc +++ b/src/qml/doc/src/qmllanguageref/documents/structure.qdoc diff --git a/src/qml/doc/src/documents/topic.qdoc b/src/qml/doc/src/qmllanguageref/documents/topic.qdoc index f8a402476c..f8a402476c 100644 --- a/src/qml/doc/src/documents/topic.qdoc +++ b/src/qml/doc/src/qmllanguageref/documents/topic.qdoc diff --git a/src/qml/doc/src/modules/cppplugins.qdoc b/src/qml/doc/src/qmllanguageref/modules/cppplugins.qdoc index af2a36c903..af2a36c903 100644 --- a/src/qml/doc/src/modules/cppplugins.qdoc +++ b/src/qml/doc/src/qmllanguageref/modules/cppplugins.qdoc diff --git a/src/qml/doc/src/modules/identifiedmodules.qdoc b/src/qml/doc/src/qmllanguageref/modules/identifiedmodules.qdoc index 34d4b864a8..34d4b864a8 100644 --- a/src/qml/doc/src/modules/identifiedmodules.qdoc +++ b/src/qml/doc/src/qmllanguageref/modules/identifiedmodules.qdoc diff --git a/src/qml/doc/src/modules/legacymodules.qdoc b/src/qml/doc/src/qmllanguageref/modules/legacymodules.qdoc index 26981334b7..26981334b7 100644 --- a/src/qml/doc/src/modules/legacymodules.qdoc +++ b/src/qml/doc/src/qmllanguageref/modules/legacymodules.qdoc diff --git a/src/qml/doc/src/modules/qmldir.qdoc b/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc index de3698c533..de3698c533 100644 --- a/src/qml/doc/src/modules/qmldir.qdoc +++ b/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc diff --git a/src/qml/doc/src/modules/topic.qdoc b/src/qml/doc/src/qmllanguageref/modules/topic.qdoc index 597e7b7ca3..597e7b7ca3 100644 --- a/src/qml/doc/src/modules/topic.qdoc +++ b/src/qml/doc/src/qmllanguageref/modules/topic.qdoc diff --git a/src/qml/doc/src/qmllanguageref/qmlreference.qdoc b/src/qml/doc/src/qmllanguageref/qmlreference.qdoc new file mode 100644 index 0000000000..34336c2def --- /dev/null +++ b/src/qml/doc/src/qmllanguageref/qmlreference.qdoc @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! +\page qmlreference.html +\title The QML Reference +\brief A declarative language for application development + +QML is a declarative language for creating highly dynamic applications. With +QML, application building blocks such as UI components are \e declared and +various properties set to define the application behavior. When coupled with +JavaScript, application behavior becomes scriptable. In addition, QML heavily +uses Qt, which allows types and other Qt features to be accessible directly from +QML applications. + +This reference guide describes the features of the QML language. Many of the +QML types in the guide originate from the \l{Qt QML} or \l{Qt Quick} +modules. + +\list + \li \l{qtqml-syntax-basics.html}{QML Syntax Basics} + \list + \li \l{qtqml-syntax-imports.html}{Import Statements} + \li \l{qtqml-syntax-basics.html#object-declarations}{Object Declarations} + \list + \li \l{qtqml-syntax-basics.html#child-objects}{Child Objects} + \endlist + \li \l{qtqml-syntax-basics.html#comments}{Comments} + \endlist + + \li \l{qtqml-javascript-topic.html}{Integrating QML and JavaScript} + \list + \li \l{qtqml-javascript-expressions.html}{Using JavaScript Expressions with QML} + \li \l{qtqml-javascript-dynamicobjectcreation.html}{Dynamic QML Object Creation from JavaScript} + \li \l{qtqml-javascript-resources.html}{Defining JavaScript Resources In QML} + \li \l{qtqml-javascript-imports.html}{Importing JavaScript Resources In QML} + \li \l{qtqml-javascript-hostenvironment.html}{JavaScript Host Environment} + \endlist + + \li \l{qtqml-syntax-objectattributes.html}{QML Object Attributes} + \list + \li \l{qtqml-syntax-objectattributes.html#the-id-attribute}{The \e id Attribute} + \li \l{qtqml-syntax-objectattributes.html#property-attributes}{Property Attributes} + \li \l{qtqml-syntax-objectattributes.html#signal-attributes}{Signal Attributes} + \li \l{qtqml-syntax-objectattributes.html#method-attributes}{Method Attributes} + \li \l{qtqml-syntax-objectattributes.html#attached-properties-and-attached-signal-handlers}{Attached Properties and Attached Signal Handlers} + \endlist + + \li \l{qtqml-syntax-propertybinding.html}{Property Binding} + \li \l{qtqml-syntax-signals.html}{Signal and Handler Event System} + + \li \l{qtqml-typesystem-topic.html}{The QML Type System} + \list + \li \l{qtqml-typesystem-basictypes.html}{Basic Types} + \li \l{qtqml-typesystem-topic.html#javascript-types}{JavaScript Types} + \li \l{qtqml-typesystem-objecttypes.html}{QML Object Types} + \list + \li \l{qtqml-documents-definetypes.html}{Defining Object Types from QML} + \li \l{qtqml-cppintegration-definetypes.html}{Defining Object Types from C++} + \endlist + \endlist + + \li \l{qtqml-modules-topic.html}{QML Modules} + \list + \li \l{qtqml-modules-qmldir.html}{Specifying A QML Module} + \li \l{qtqml-modules-topic.html#supported-qml-module-types}{Supported QML Module Types} + \list + \li \l{qtqml-modules-identifiedmodules.html}{Identified Modules} + \li \l{qtqml-modules-legacymodules.html}{Legacy Modules} + \endlist + \li \l{qtqml-modules-cppplugins.html}{Providing Types and Functionality in a C++ Plugin} + \endlist + + \li \l{qtqml-documents-topic.html}{QML Documents} + \list + \li \l{qtqml-documents-structure.html}{Structure of a QML Document} + \li \l{Syntax of the QML Language} + \li \l{qtqml-documents-definetypes.html}{Defining Object Types through QML Documents} + \list + \li \l{qtqml-documents-definetypes.html#defining-an-object-type-with-a-qml-file}{Defining an Object Type with a QML File} + \li \l{qtqml-documents-definetypes.html#accessible-attributes-of-custom-types}{Accessible Attributes of Custom Types} + \endlist + \li \l{qtqml-documents-networktransparency.html}{Resource Loading and Network Transparency} + \li \l{qtqml-documents-scope.html}{Scope and Naming Resolution} + \endlist +\endlist + +*/ diff --git a/src/qml/doc/src/syntax/basics.qdoc b/src/qml/doc/src/qmllanguageref/syntax/basics.qdoc index d20f66d80a..cdfab3cd3f 100644 --- a/src/qml/doc/src/syntax/basics.qdoc +++ b/src/qml/doc/src/qmllanguageref/syntax/basics.qdoc @@ -89,9 +89,9 @@ Rectangle { } \endqml -This declares an object of type \l Rectangle, followed by a set of curly braces that encompasses the attributes defined for that object. The \l Rectangle type is a type made available by the \l QtQuick module, and the attributes defined in this case are the values of the rectangle's \c width, \c height and \c color properties. (These are properties made available by the \l Rectangle type, as described in the \l Rectangle documentation.) +This declares an object of type \l Rectangle, followed by a set of curly braces that encompasses the attributes defined for that object. The \l Rectangle type is a type made available by the \c QtQuick module, and the attributes defined in this case are the values of the rectangle's \c width, \c height and \c color properties. (These are properties made available by the \l Rectangle type, as described in the \l Rectangle documentation.) -The above object can be loaded by the engine if it is part of a \l{qtqml-documents-topic.html}{QML document}. That is, if the source code is complemented with \e import statement that imports the QtQuick module (to make the \l Rectangle type available), as below: +The above object can be loaded by the engine if it is part of a \l{qtqml-documents-topic.html}{QML document}. That is, if the source code is complemented with \e import statement that imports the \c QtQuick module (to make the \l Rectangle type available), as below: \qml import QtQuick 2.0 @@ -103,7 +103,7 @@ Rectangle { } \endqml -When placed into a \c .qml file and loaded by the QML engine, the above code creates a \l Rectangle object using the \l Rectangle type supplied by the QtQuick module: +When placed into a \c .qml file and loaded by the QML engine, the above code creates a \l Rectangle object using the \l Rectangle type supplied by the \c QtQuick module: \image qtqml-syntax-basics-object-declaration.png @@ -140,7 +140,7 @@ Rectangle { When this code is loaded by the engine, it creates an object tree with a \l Rectangle object at the root; this object has a \l Gradient child object, which in turn has two \l GradientStop children. Note, however, that this is a parent-child relationship in the context of the QML object tree, not -in the context of the visual scene. The concept of a parent-child relationship in a visual scene is provided by the \l Item type from the \l QtQuick module, which is the base type for most QML types, as most QML objects are intended to be visually rendered. For example, \l Rectangle and \l Text are both \l {Item}-based types, and below, a \l Text object has been declared as a visual child of a \l Rectangle object: +in the context of the visual scene. The concept of a parent-child relationship in a visual scene is provided by the \l Item type from the \c QtQuick module, which is the base type for most QML types, as most QML objects are intended to be visually rendered. For example, \l Rectangle and \l Text are both \l {Item}-based types, and below, a \l Text object has been declared as a visual child of a \l Rectangle object: \qml import QtQuick 2.0 diff --git a/src/qml/doc/src/syntax/directoryimports.qdoc b/src/qml/doc/src/qmllanguageref/syntax/directoryimports.qdoc index 7a6fb58c27..7a6fb58c27 100644 --- a/src/qml/doc/src/syntax/directoryimports.qdoc +++ b/src/qml/doc/src/qmllanguageref/syntax/directoryimports.qdoc diff --git a/src/qml/doc/src/syntax/imports.qdoc b/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc index eda7dbf006..1496a1e5c9 100644 --- a/src/qml/doc/src/syntax/imports.qdoc +++ b/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc @@ -144,7 +144,7 @@ the types should be imported into a particular document-local namespace. If a namespace is specified, then any references to the types made available by the import must be prefixed by the local namespace qualifier. -Below, the QtQuick module is imported into the namespace "CoreItems". Now, any +Below, the \c QtQuick module is imported into the namespace "CoreItems". Now, any references to types from the \c QtQuick module must be prefixed with the \c CoreItems name: @@ -178,7 +178,7 @@ CoreItems.Rectangle { width: 100; height: 100 MyModule.Text { text: "Hello from my custom text item!" } - CoreItems.Text { text: "Hello from QtQuick!" } + CoreItems.Text { text: "Hello from Qt Quick!" } } \endqml diff --git a/src/qml/doc/src/syntax/objectattributes.qdoc b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc index f336d14b14..f336d14b14 100644 --- a/src/qml/doc/src/syntax/objectattributes.qdoc +++ b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc diff --git a/src/qml/doc/src/syntax/propertybinding.qdoc b/src/qml/doc/src/qmllanguageref/syntax/propertybinding.qdoc index 6803901efd..6803901efd 100644 --- a/src/qml/doc/src/syntax/propertybinding.qdoc +++ b/src/qml/doc/src/qmllanguageref/syntax/propertybinding.qdoc diff --git a/src/qml/doc/src/syntax/signals.qdoc b/src/qml/doc/src/qmllanguageref/syntax/signals.qdoc index 6c90ddcf0a..fba072d2e4 100644 --- a/src/qml/doc/src/syntax/signals.qdoc +++ b/src/qml/doc/src/qmllanguageref/syntax/signals.qdoc @@ -115,7 +115,7 @@ Even though the \l MouseArea documentation does not document a signal handler na \section2 Using the Connections Type -In some cases it may be desirable to access a signal outside of the object that emits it. For these purposes, the QtQuick module provides the \l Connections type for connecting to signals of arbitrary objects. A \l Connections object can receive any signal from its specified \l {Connections::target}{target}. +In some cases it may be desirable to access a signal outside of the object that emits it. For these purposes, the \c QtQuick module provides the \l Connections type for connecting to signals of arbitrary objects. A \l Connections object can receive any signal from its specified \l {Connections::target}{target}. For example, the \c onClicked handler in the earlier example could have been received by the root \l Rectangle instead, by placing the \c onClicked handler in a \l Connections object that has its \l {Connections::target}{target} set to the \l MouseArea: diff --git a/src/qml/doc/src/typesystem/basictypes.qdoc b/src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc index 6f468d42bc..7d2d662e4e 100644 --- a/src/qml/doc/src/typesystem/basictypes.qdoc +++ b/src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc @@ -67,7 +67,7 @@ The basic types supported natively in the QML language are listed below: \section2 Basic Types Provided By QML Modules QML modules may extend the QML language with more basic types. -For example, the basic types provided by the QtQuick module are listed below: +For example, the basic types provided by the \c QtQuick module are listed below: \annotatedlist qtquickbasictypes Currently only QML modules which are provided by Qt may provide their @@ -241,7 +241,7 @@ property is only invoked when the property is reassigned to a different object v \brief a resource locator. The \c url type refers to a resource locator (like a file name, for example). It can be either - absolute, e.g. "http://qt.nokia.com", or relative, e.g. "pics/logo.png". A relative URL is + absolute, e.g. "http://qt-project.org", or relative, e.g. "pics/logo.png". A relative URL is resolved relative to the URL of the containing component. For example, the following assigns a valid URL to the \l {Image::source} diff --git a/src/qml/doc/src/typesystem/objecttypes.qdoc b/src/qml/doc/src/qmllanguageref/typesystem/objecttypes.qdoc index 9209ebe68e..9209ebe68e 100644 --- a/src/qml/doc/src/typesystem/objecttypes.qdoc +++ b/src/qml/doc/src/qmllanguageref/typesystem/objecttypes.qdoc diff --git a/src/qml/doc/src/typesystem/topic.qdoc b/src/qml/doc/src/qmllanguageref/typesystem/topic.qdoc index 76e28f7ef1..76e28f7ef1 100644 --- a/src/qml/doc/src/typesystem/topic.qdoc +++ b/src/qml/doc/src/qmllanguageref/typesystem/topic.qdoc diff --git a/src/qml/doc/src/qmltypereference.qdoc b/src/qml/doc/src/qmltypereference.qdoc index 799945fa37..54e10b63a8 100644 --- a/src/qml/doc/src/qmltypereference.qdoc +++ b/src/qml/doc/src/qmltypereference.qdoc @@ -24,20 +24,18 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + /*! \qmlmodule QtQml 2 \title Qt QML QML Types \ingroup qmlmodules \brief List of QML types provided by the Qt QML module -The \c QtQml module provides the definition and implementation of various +The \l{Qt QML} module provides the definition and implementation of various convenience types which can be used with the QML language, including some elementary QML types which can provide the basis for further extensions to the -QML language. - -The \c QtQml module provides the \c QtObject and \c Component object types -which may be used in QML documents. These types are non-visual and provide -building-blocks for extensions to QML. +QML language. The \l QtObject and \l Component object types are non-visual and +provide building-blocks for extensions to QML. \section1 Importing QtQml @@ -53,8 +51,8 @@ import QtQml 2.0 \endqml Most clients will never need to use the \c QtQml import, as all of the types -and functionality provided by the \c QtQml namespace are also provided by the -\c QtQuick namespace which may be imported as follows: +are also provided by the \c QtQuick namespace which may be imported as +follows: \qml import QtQuick 2.0 @@ -78,82 +76,6 @@ provided: The following \l{qtqml-typesystem-objecttypes.html}{QML object types} are provided: -\section2 QtObject - -The \c QtObject type provides a basic instantiable object which can be used in -QML applications. It is non-visual, but may have properties, methods, signals -and signal handlers. - -For example, the following QtObject has several properties, one of which has -been assigned a \l{Property Binding} -{binding}, and a \l{Signal and Handler Event System}{signal handler} for -the default change signal which exists for one of its properties: - -\code - import QtQuick 2.0 - - QtObject { - property int a: 15 - property int b: a + 22 - property int changeCount: 0 - - onAChanged: { - changeCount += 1; - } - } -\endcode - -\section2 Component - -The \c Component type provides a basic re-usable component which allows -instances of another type to be instantiated on-demand. It may be given an -\c id and it has a default property which is the object type to instantiate, -but no other properties may be added to it. - -For example, the following QtObject has two different \l Component -properties, and it uses those components to dynamically construct objects at -run-time: - -\code - import QtQuick 2.0 - - QtObject { - id: root - property bool which: true - - property Component a: Component { - id: firstComponent - QtObject { - property int answer: 42 - function activate() { - console.log("The answer is: " + answer); - } - } - } - - property Component b: Component { - id: secondComponent - QtObject { - property string message: "Hello, World!" - function activate() { - console.log(message); - } - } - } - - function activateDynamicObject() { - var o = {}; - if (which) { - which = false; - o = a.createObject(null); // no parent - } else { - which = true; - o = b.createObject(null); // no parent - } - o.activate(); - } - } -\endcode */ /*! @@ -322,5 +244,3 @@ is automatically converted into a QRectF value. \sa{QML Basic Types} */ - - diff --git a/src/qml/doc/src/qtqml.qdoc b/src/qml/doc/src/qtqml.qdoc index 05a33f351a..8bd41875fe 100644 --- a/src/qml/doc/src/qtqml.qdoc +++ b/src/qml/doc/src/qtqml.qdoc @@ -30,159 +30,103 @@ \title Qt QML \brief The Qt QML module defines and implements the QML language -\section1 Overview of the Qt QML Module - -The Qt QML module provides a framework for developing applications and -libraries with the QML language. It defines and implements the language -and engine infrastructure, and provides an API to enable application +The Qt QML module provides a framework for developing applications and libraries +with the \l{The QML Language}{QML language}. It defines and implements the +language and engine infrastructure, and provides an API to enable application developers to extend the QML language with custom types and integrate QML code -with JavaScript and C++. - -The Qt QML module provides both the \c QtQml QML module, which supplies -\l{Qt QML QML Types}{a set of core QML types} for creating QML -applications, and the \c QtQml C++ module, which supplies \l{Qt QML C++ Classes}{a set of C++ -APIs} for extending QML applications with custom types and integrating C++ -implementations with QML applications. +with JavaScript and C++. The Qt QML module provides both a \l{Qt QML QML Types} +{QML API} and a \l{Qt QML C++ Classes}{C++ API}. -Note that the Qt QML module provides only the language and infrastructure -for the QML, and does not provide a visual canvas or rendering engine for -creating user interfaces. These are provided instead by the -\l{Qt Quick} module, which provides many visual components, -model/view support, an animation framework and much more for building user -interfaces with QML. +Note that while the Qt QML module provides the language and infrastructure +for QML applications, the \l{Qt Quick} module provides many visual components, +model-view support, an animation framework, and much more for building user +interfaces. For those new to QML and Qt Quick, please see \l{qtquick-applicationdevelopers.html}{QML Application Developer Resources} for an introduction to writing QML applications. +\section1 Getting Started -\section1 Qt QML Module Documentation +To include the definitions of the module's classes, use the +following directive: -\list - \li \l{qtqml-cppclasses-topic.html}{Important C++ Classes} - \list - \li \l{QQmlEngine} - \li \l{QQmlContext} - \li \l{QQmlComponent} - \li \l{QQmlExpression} - \endlist - - \li \l{qtqml-typesystem-topic.html}{The QML Type System} - \list - \li \l{qtqml-typesystem-basictypes.html}{Basic Types} - \li \l{qtqml-typesystem-topic.html#javascript-types}{JavaScript Types} - \li \l{qtqml-typesystem-objecttypes.html}{QML Object Types} - \list - \li \l{qtqml-documents-definetypes.html}{Defining Object Types from QML} - \li \l{qtqml-cppintegration-definetypes.html}{Defining Object Types from C++} - \endlist - \endlist - - \li \l{qtqml-modules-topic.html}{QML Modules} - \list - \li \l{qtqml-modules-qmldir.html}{Specifying A QML Module} - \li \l{qtqml-modules-topic.html#supported-qml-module-types}{Supported QML Module Types} - \list - \li \l{qtqml-modules-identifiedmodules.html}{Identified Modules} - \li \l{qtqml-modules-legacymodules.html}{Legacy Modules} - \endlist - \li \l{qtqml-modules-cppplugins.html}{Providing Types and Functionality in a C++ Plugin} - \endlist - - \li \l{qtqml-documents-topic.html}{QML Documents} - \list - \li \l{qtqml-documents-structure.html}{Structure of a QML Document} - \li \l{Syntax of the QML Language} - \li \l{qtqml-documents-definetypes.html}{Defining Object Types through QML Documents} - \list - \li \l{qtqml-documents-definetypes.html#defining-an-object-type-with-a-qml-file}{Defining an Object Type with a QML File} - \li \l{qtqml-documents-definetypes.html#accessible-attributes-of-custom-types}{Accessible Attributes of Custom Types} - \endlist - \li \l{qtqml-documents-networktransparency.html}{Resource Loading and Network Transparency} - \li \l{qtqml-documents-scope.html}{Scope and Naming Resolution} - \endlist - - \li \l{qtqml-typereference-topic.html}{QML Types Provided by the Qt QML Module} - \list - \li \l{qtqml-typereference-topic.html#importing-qtqml}{Importing \c QtQml} - \li \l{qtqml-typereference-topic.html#basic-types}{Basic Types} - \li \l{qtqml-typereference-topic.html#object-types}{Object Types} - \list - \li \l{qtqml-typereference-topic.html#qtobject}{QtObject} - \li \l{qtqml-typereference-topic.html#component}{Component} - \endlist - \endlist - - \li \l{qtqml-javascript-topic.html}{Integrating QML and JavaScript} - \list - \li \l{qtqml-javascript-expressions.html}{Using JavaScript Expressions with QML} - \li \l{qtqml-javascript-dynamicobjectcreation.html}{Dynamic QML Object Creation from JavaScript} - \li \l{qtqml-javascript-resources.html}{Defining JavaScript Resources In QML} - \li \l{qtqml-javascript-imports.html}{Importing JavaScript Resources In QML} - \li \l{qtqml-javascript-hostenvironment.html}{JavaScript Host Environment} - \list - \li \l{qtqml-javascript-hostenvironment.html#common-base}{Common Base} - \li \l{qtqml-javascript-hostenvironment.html#qml-global-object}{QML Global Object} - \li \l{qtqml-javascript-hostenvironment.html#javascript-objects-and-functions}{JavaScript Objects and Functions} - \li \l{qtqml-javascript-hostenvironment.html#javascript-environment-restrictions}{JavaScript Environment Restrictions} - \endlist - \endlist - - \li \l{qtqml-cppintegration-topic.html}{Integrating QML and C++} - \list - \li \l{qtqml-cppintegration-exposecppattributes.html}{Exposing Attributes of C++ Classes to QML} - \li \l{qtqml-cppintegration-definetypes.html}{Defining QML Types from C++} - \li \l{qtqml-cppintegration-contextproperties.html}{Embedding C++ Objects into QML with Context Properties} - \li \l{qtqml-cppintegration-interactqmlfromcpp.html}{Interacting with QML Objects from C++} - \li \l{qtqml-cppintegration-data.html}{Data Type Conversion Between QML and C++} - \endlist +\code +#include <QtQml> +\endcode -\endlist +The QML types in Qt QML are available through the \c QtQML import. To use the +types, add the following import statement to your .qml file: +\code +import QtQml 2.0 +\endcode + + +To link against the module, add this line to your \l qmake \c +.pro file: +\code +QT += qml +\endcode -\section1 Syntax of the QML Language +\section1 QML and QML Types +The Qt QML module contains the QML framework and important QML types used in +applications. The constructs of QML are described in the \l{The QML Reference}. + +In addition to the \l{QML Basic Types}, the module comes with +various QML object types: \list - \li \l{qtqml-syntax-basics.html}{QML Syntax Basics} - \list - \li \l{qtqml-syntax-imports.html}{Import Statements} - \li \l{qtqml-syntax-basics.html#object-declarations}{Object Declarations} - \list - \li \l{qtqml-syntax-basics.html#child-objects}{Child Objects} - \endlist - \li \l{qtqml-syntax-basics.html#comments}{Comments} - \endlist - - \li \l{qtqml-syntax-objectattributes.html}{QML Object Attributes} - \list - \li \l{qtqml-syntax-objectattributes.html#the-id-attribute}{The \e id Attribute} - \li \l{qtqml-syntax-objectattributes.html#property-attributes}{Property Attributes} - \li \l{qtqml-syntax-objectattributes.html#signal-attributes}{Signal Attributes} - \li \l{qtqml-syntax-objectattributes.html#method-attributes}{Method Attributes} - \li \l{qtqml-syntax-objectattributes.html#attached-properties-and-attached-signal-handlers}{Attached Properties and Attached Signal Handlers} - \endlist - - \li \l{qtqml-syntax-propertybinding.html}{Property Binding} - \li \l{qtqml-syntax-signals.html}{Signal and Handler Event System} +\li \l Component +\li \l QtObject +\li \l Binding +\li \l Connections +\li \l Timer \endlist -\section1 Reference Documentation +\section1 JavaScript Environment for QML Applications + +JavaScript expressions allow QML code to contain application logic. Qt QML +provides the framework for running JavaScript expressions in QML and from C++. + +These sections are from \l{The QML Reference}. +\l{qtqml-javascript-topic.html}{Integrating QML and JavaScript} + \list + \li \l{qtqml-javascript-expressions.html}{Using JavaScript Expressions with QML} + \li \l{qtqml-javascript-dynamicobjectcreation.html}{Dynamic QML Object Creation from JavaScript} + \li \l{qtqml-javascript-resources.html}{Defining JavaScript Resources In QML} + \li \l{qtqml-javascript-imports.html}{Importing JavaScript Resources In QML} + \li \l{qtqml-javascript-hostenvironment.html}{JavaScript Host Environment} + \endlist + +\section1 Integrating QML with C++ Applications + +The module also provides the framework for running QML applications. +The QML framework allows QML code to contain JavaScript expressions and for +the QML code to interact with C++ code. -Additional Qt QML information: \list -\li \l{Qt QML C++ Classes} - the C++ API provided by the - Qt QML module -\li \l{Qt QML Release Notes} - list of changes and - additions in the Qt QML module +\li \l{Important C++ Classes Provided By The Qt QML Module} +\li \l{Integrating QML and C++} \endlist +\section1 Guides and Other Information + Further information for writing QML applications: \list +\li \l{The QML Reference} \li \l{QML Application Developer Resources} - essential information for application development with QML and Qt Quick -\li \l{Qt Quick} - documentation for the Qt Quick module, which provides a - visual canvas, an animation framework, model/view components and more for - building fluid user interfaces and applications with QML +\li \l{Qt Quick} - a module which provides a set of QML types and C++ classes + for building user interfaces and applications with QML +\li \l{Qt QML Release Notes} - list of changes and + additions in the Qt QML module \endlist -*/ +\section2 Reference +\list +\li \l{Qt QML C++ Classes}{C++ Classes} +\li \l{Qt QML QML Types}{QML Types} +\endlist + +*/ diff --git a/src/qml/doc/src/whatsnew.qdoc b/src/qml/doc/src/whatsnew.qdoc index b73b6436f1..154c7cfd0d 100644 --- a/src/qml/doc/src/whatsnew.qdoc +++ b/src/qml/doc/src/whatsnew.qdoc @@ -34,9 +34,9 @@ The \l{Qt QML} module is new in Qt 5.0. It provides the QML engine and implements the QML language supporting infrastructure. -(Prior to Qt 5, this functionality was provided by the QtDeclarative module, which -has now been replaced by the new \l {Qt QML} and QtQuick C++ modules. See the -\l {Porting QML Applications to Qt 5} for more information.) +(Prior to Qt 5, this functionality was provided by the \l {Qt Quick 1}{QtDeclarative} module, which +has now been replaced by the new \l {Qt QML} and \l {Qt Quick} modules. See the +\l {Porting QML Applications to Qt 5} page for more information.) \section2 QML Engine @@ -72,11 +72,11 @@ has now been replaced by the new \l {Qt QML} and QtQuick C++ modules. See the \list \li QML now supports defining properties of value type basic types within QML documents. Supported types include QSizeF, QPointF and QRectF as \c size, \c point and \c rect respectively. - \li QColor is now a value type provided by the QtQuick module. The red, green, blue and alpha channels + \li QColor is now a value type provided by the \c QtQuick module. The red, green, blue and alpha channels of a \l color property can be accessed via \c r, \c g, \c b and \c a properties. \li Factory functions for various value types have been added to the \c Qt object exposed to QML. - Some of those functions require the QtQuick module to be imported in order to return valid values. - See the QtQuick 2.0 release notes for more information about these functions. + Some of those functions require the \c QtQuick module to be imported in order to return valid values. + See the \l {Qt Quick Release Notes} for more information about these functions. \endlist \li Support for sequence types QList<int>, QList<qreal>, QList<bool>, QList<QUrl>, QList<QString> and QStringList has been improved. QObjects can define Q_PROPERTYs of diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp index 7dc2c77922..a5f8f463c9 100644 --- a/src/qml/qml/qqmlapplicationengine.cpp +++ b/src/qml/qml/qqmlapplicationengine.cpp @@ -158,7 +158,7 @@ void QQmlApplicationEnginePrivate::_q_finishLoad(QObject *o) } \endcode - You can also use QCoreApplication with QQmlApplicationEngine, if you are not using any QML modules which require a QGuiApplication (such as QtQuick). + You can also use QCoreApplication with QQmlApplicationEngine, if you are not using any QML modules which require a QGuiApplication (such as \c QtQuick). List of configuration changes from a default QQmlEngine: diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 9cb444b75d..7cf7c5475e 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -186,7 +186,7 @@ static inline QString buildTypeNameForDebug(const QMetaObject *metaObject) } \endcode - Note that the QtQuick 1 version is named QDeclarativeComponent. + Note that the \l {Qt Quick 1} version is named QDeclarativeComponent. */ /*! @@ -1135,7 +1135,7 @@ static void QQmlComponent_setQmlParent(QObject *me, QObject *parent) it is not destroyed by the garbage collector. This is true regardless of whether \l{Item::parent} is set afterwards, since setting the Item parent does not change object ownership; only the graphical parent is changed. - As of QtQuick 1.1, this method accepts an optional \a properties argument that specifies a + As of \c {QtQuick 1.1}, this method accepts an optional \a properties argument that specifies a map of initial property values for the created object. These values are applied before object creation is finalized. This is more efficient than setting property values after object creation, particularly where large sets of property values are defined, and also allows property bindings diff --git a/src/qml/qml/qqmlcomponentattached_p.h b/src/qml/qml/qqmlcomponentattached_p.h index 3c27e795c6..ae416dcb1c 100644 --- a/src/qml/qml/qqmlcomponentattached_p.h +++ b/src/qml/qml/qqmlcomponentattached_p.h @@ -43,12 +43,13 @@ #define QQMLCOMPONENTATTACHED_P_H #include <QtQml/qqml.h> +#include <private/qtqmlglobal_p.h> #include <QtCore/QObject> QT_BEGIN_NAMESPACE -class Q_AUTOTEST_EXPORT QQmlComponentAttached : public QObject +class Q_QML_PRIVATE_EXPORT QQmlComponentAttached : public QObject { Q_OBJECT public: diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index f128e6684a..5fa5cfd9ef 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -314,7 +314,7 @@ when the property has one of the following types: \li \c size - use \l{Qt::size()}{Qt.size()} \endlist -If the QtQuick module has been imported, the following helper functions for +If the \c QtQuick module has been imported, the following helper functions for creating objects of specific data types are also available for clients to use: \list \li \c color - use \l{Qt::rgba()}{Qt.rgba()}, \l{Qt::hsla()}{Qt.hsla()}, \l{Qt::darker()}{Qt.darker()}, \l{Qt::lighter()}{Qt.lighter()} or \l{Qt::tint()}{Qt.tint()} @@ -800,7 +800,7 @@ QQuickWorkerScriptEngine *QQmlEnginePrivate::getWorkerScriptEngine() In this case, the Text item will be created in the engine's \l {QQmlEngine::rootContext()}{root context}. - Note that the QtQuick 1 version is called QDeclarativeEngine. + Note that the \l {Qt Quick 1} version is called QDeclarativeEngine. \sa QQmlComponent, QQmlContext */ diff --git a/src/qml/qml/qqmlerror.cpp b/src/qml/qml/qqmlerror.cpp index 88129b7240..98d8259dda 100644 --- a/src/qml/qml/qqmlerror.cpp +++ b/src/qml/qml/qqmlerror.cpp @@ -71,7 +71,7 @@ QT_BEGIN_NAMESPACE ^ \endcode - Note that the QtQuick 1 version is named QDeclarativeError + Note that the \l {Qt Quick 1} version is named QDeclarativeError \sa QQuickView::errors(), QQmlComponent::errors() */ diff --git a/src/qml/qml/qqmlexpression.cpp b/src/qml/qml/qqmlexpression.cpp index 3bc0c50ba4..accc645f1e 100644 --- a/src/qml/qml/qqmlexpression.cpp +++ b/src/qml/qml/qqmlexpression.cpp @@ -162,7 +162,7 @@ QQmlExpressionPrivate::create(QQmlContextData *ctxt, QObject *object, int result = expr->evaluate().toInt(); // result = 400 \endcode - Note that the QtQuick 1 version is called QDeclarativeExpression. + Note that the \l {Qt Quick 1} version is called QDeclarativeExpression. */ /*! diff --git a/src/qml/qml/qqmlextensionplugin.cpp b/src/qml/qml/qqmlextensionplugin.cpp index edef5a91cd..babdd6ea71 100644 --- a/src/qml/qml/qqmlextensionplugin.cpp +++ b/src/qml/qml/qqmlextensionplugin.cpp @@ -121,7 +121,7 @@ QT_BEGIN_NAMESPACE The \l {Writing QML Extensions with C++} tutorial also contains a chapter on creating QML plugins. - Note that the QtQuick 1 version is called QDeclarativeExtensionPlugin. + Note that the \l {Qt Quick 1} version is called QDeclarativeExtensionPlugin. \sa QQmlEngine::importPlugin(), {How to Create Qt Plugins} */ diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h index 6ca54f65cd..19139ce920 100644 --- a/src/qml/qml/qqmlglobal_p.h +++ b/src/qml/qml/qqmlglobal_p.h @@ -317,7 +317,7 @@ class QQmlApplicationPrivate; class Q_QML_PRIVATE_EXPORT QQmlApplication : public QObject { - //Application level logic, subclassed by QtQuick if available via QQmlGuiProvider + //Application level logic, subclassed by Qt Quick if available via QQmlGuiProvider Q_OBJECT Q_PROPERTY(QStringList arguments READ args CONSTANT) Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) diff --git a/src/qml/qml/qqmllist.cpp b/src/qml/qml/qqmllist.cpp index e6913f01a8..91c9bc2416 100644 --- a/src/qml/qml/qqmllist.cpp +++ b/src/qml/qml/qqmllist.cpp @@ -112,7 +112,7 @@ Attempting to add objects of the incorrect type to a list property will fail. Like with normal lists, when accessing a list element by index, it is the callers responsibility to ensure that it does not request an out of range element using the count() method before calling at(). -The QtQuick 1 version of this class is named QDeclarativeListReference. +The \l {Qt Quick 1} version of this class is named QDeclarativeListReference. */ /*! @@ -369,7 +369,7 @@ Q_PROPERTY(QQmlListProperty<Fruit> fruit READ fruit); QML list properties are typesafe - in this case \c {Fruit} is a QObject type that \c {Apple}, \c {Orange} and \c {Banana} all derive from. -The QtQuick 1 version of this class is named QDeclarativeListProperty. +The \l {Qt Quick 1} version of this class is named QDeclarativeListProperty. \note QQmlListProperty can only be used for lists of QObject-derived object pointers. */ diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp index 018c55a925..15ddcc7c29 100644 --- a/src/qml/qml/qqmllocale.cpp +++ b/src/qml/qml/qqmllocale.cpp @@ -812,7 +812,7 @@ V8_DEFINE_EXTENSION(QV8LocaleDataDeletable, localeV8Data); } \endcode - QtQuick Locale's data is based on Common Locale Data Repository v1.8.1. + Qt Quick Locale's data is based on Common Locale Data Repository v1.8.1. \target FormatType diff --git a/src/qml/qml/qqmlnetworkaccessmanagerfactory.cpp b/src/qml/qml/qqmlnetworkaccessmanagerfactory.cpp index 156c341158..b0271b11f2 100644 --- a/src/qml/qml/qqmlnetworkaccessmanagerfactory.cpp +++ b/src/qml/qml/qqmlnetworkaccessmanagerfactory.cpp @@ -80,7 +80,7 @@ QT_BEGIN_NAMESPACE For more information about signals and threads, see \l {Threads and QObjects} and \l {Signals and Slots Across Threads}. - The QtQuick 1 version of this class is named QDeclarativeNetworkAccessManagerFactory. + The \l {Qt Quick 1} version of this class is named QDeclarativeNetworkAccessManagerFactory. \sa {qml/networkaccessmanagerfactory}{NetworkAccessManagerFactory example} */ diff --git a/src/qml/qml/qqmlparserstatus.cpp b/src/qml/qml/qqmlparserstatus.cpp index 452a8d7eb8..41b7d962ce 100644 --- a/src/qml/qml/qqmlparserstatus.cpp +++ b/src/qml/qml/qqmlparserstatus.cpp @@ -84,7 +84,7 @@ QT_BEGIN_NAMESPACE } \endcode - The QtQuick 1.0 version of this class is named QDeclarativeParserStatus. + The \l {Qt Quick 1} version of this class is named QDeclarativeParserStatus. */ /*! \internal */ diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index fa728fec0d..0baf450cbf 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -112,7 +112,7 @@ property.write(24); qWarning() << "Pixel size should now be 24:" << property.read().toInt(); \endcode -The QtQuick 1 version of this class was named QDeclarativeProperty. +The \l {Qt Quick 1} version of this class was named QDeclarativeProperty. */ /*! diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 309d896d86..b5f4bf555c 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -1130,7 +1130,7 @@ Example (where \c parentItem is the id of an existing QML item): \snippet qml/createQmlObject.qml 0 -In the case of an error, a QtScript Error object is thrown. This object has an additional property, +In the case of an error, a \l {Qt Script} Error object is thrown. This object has an additional property, \c qmlErrors, which is an array of the errors encountered. Each object in this array has the members \c lineNumber, \c columnNumber, \c fileName and \c message. For example, if the above snippet had misspelled color as 'colro' then the array would contain an object like the following: @@ -1634,9 +1634,9 @@ v8::Handle<v8::Value> locale(const v8::Arguments &args) \snippet qml/qtBinding.4.qml 0 - Note: in QtQuick 1.x, all function assignment was treated as + \note In \l {Qt Quick 1}, all function assignment was treated as binding assignment, so the Qt.binding() function is new in - QtQuick 2.0. + \l {Qt Quick}{Qt Quick 2}. \since QtQuick 2.0 */ diff --git a/src/qml/qml/v8/qv8qobjectwrapper.cpp b/src/qml/qml/v8/qv8qobjectwrapper.cpp index 0982f177d3..0336457027 100644 --- a/src/qml/qml/v8/qv8qobjectwrapper.cpp +++ b/src/qml/qml/v8/qv8qobjectwrapper.cpp @@ -1612,7 +1612,8 @@ static v8::Handle<v8::Value> CallMethod(QObject *object, int index, int returnTy Returns the match score for converting \a actual to be of type \a conversionType. A zero score means "perfect match" whereas a higher score is worse. - The conversion table is copied out of the QtScript callQtMethod() function. + The conversion table is copied out of the \l QScript::callQtMethod() + function. */ static int MatchScore(v8::Handle<v8::Value> actual, int conversionType) { diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp index ad2b6f91e4..16572c44dd 100644 --- a/src/qml/types/qqmldelegatemodel.cpp +++ b/src/qml/types/qqmldelegatemodel.cpp @@ -128,7 +128,7 @@ QQmlDelegateModelParts::QQmlDelegateModelParts(QQmlDelegateModel *parent) The VisualDataModel type encapsulates a model and the delegate that will be instantiated for items in a model. - This type is provided by QtQuick 2 for compatibility reasons. The same implementation + 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. \sa {QtQml.Models2::DelegateModel} @@ -142,7 +142,7 @@ 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 QtQuick module. For full details, + 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 @@ -1158,8 +1158,8 @@ void QQmlDelegateModelPrivate::itemsInserted( cacheIndex = insert.cacheIndex + insert.count; } } - for (; cacheIndex < m_cache.count(); ++cacheIndex) - incrementIndexes(m_cache.at(cacheIndex), m_groupCount, inserted); + for (const QList<QQmlDelegateModelItem *> cache = m_cache; cacheIndex < cache.count(); ++cacheIndex) + incrementIndexes(cache.at(cacheIndex), m_groupCount, inserted); } void QQmlDelegateModelPrivate::itemsInserted(const QVector<Compositor::Insert> &inserts) @@ -1183,8 +1183,9 @@ void QQmlDelegateModel::_q_itemsInserted(int index, int count) d->m_count += count; - for (int i = 0, c = d->m_cache.count(); i < c; ++i) { - QQmlDelegateModelItem *item = d->m_cache.at(i); + const QList<QQmlDelegateModelItem *> cache = d->m_cache; + for (int i = 0, c = cache.count(); i < c; ++i) { + QQmlDelegateModelItem *item = cache.at(i); if (item->modelIndex() >= index) item->setModelIndex(item->modelIndex() + count); } @@ -1275,8 +1276,8 @@ void QQmlDelegateModelPrivate::itemsRemoved( } } - for (; cacheIndex < m_cache.count(); ++cacheIndex) - incrementIndexes(m_cache.at(cacheIndex), m_groupCount, removed); + for (const QList<QQmlDelegateModelItem *> cache = m_cache; cacheIndex < cache.count(); ++cacheIndex) + incrementIndexes(cache.at(cacheIndex), m_groupCount, removed); } void QQmlDelegateModelPrivate::itemsRemoved(const QVector<Compositor::Remove> &removes) @@ -1298,9 +1299,9 @@ void QQmlDelegateModel::_q_itemsRemoved(int index, int count) return; d->m_count -= count; - - for (int i = 0, c = d->m_cache.count(); i < c; ++i) { - QQmlDelegateModelItem *item = d->m_cache.at(i); + const QList<QQmlDelegateModelItem *> cache = d->m_cache; + for (int i = 0, c = cache.count(); i < c; ++i) { + QQmlDelegateModelItem *item = cache.at(i); if (item->modelIndex() >= index + count) item->setModelIndex(item->modelIndex() - count); else if (item->modelIndex() >= index) @@ -1346,8 +1347,9 @@ void QQmlDelegateModel::_q_itemsMoved(int from, int to, int count) const int maximum = qMax(from, to) + count; const int difference = from > to ? count : -count; - for (int i = 0, c = d->m_cache.count(); i < c; ++i) { - QQmlDelegateModelItem *item = d->m_cache.at(i); + const QList<QQmlDelegateModelItem *> cache = d->m_cache; + for (int i = 0, c = cache.count(); i < c; ++i) { + QQmlDelegateModelItem *item = cache.at(i); if (item->modelIndex() >= from && item->modelIndex() < from + count) item->setModelIndex(item->modelIndex() - from + to); else if (item->modelIndex() >= minimum && item->modelIndex() < maximum) @@ -1421,8 +1423,9 @@ void QQmlDelegateModel::_q_modelReset() if (d->m_complete) { d->m_count = d->m_adaptorModel.count(); - for (int i = 0, c = d->m_cache.count(); i < c; ++i) { - QQmlDelegateModelItem *item = d->m_cache.at(i); + const QList<QQmlDelegateModelItem *> cache = d->m_cache; + for (int i = 0, c = cache.count(); i < c; ++i) { + QQmlDelegateModelItem *item = cache.at(i); if (item->modelIndex() != -1) item->setModelIndex(-1); } @@ -2183,7 +2186,7 @@ void QQmlDelegateModelGroupPrivate::destroyingPackage(QQuickPackage *package) 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 QtQuick module. For full details, + This element is also available as DelegateModelGroup in the \c QtQuick module. For full details, see the \l DelegateModelGroup documentation. \sa {QtQuick::DelegateModelGroup} diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp index 5b8cb436c0..9277b6ea8f 100644 --- a/src/qml/types/qqmllistmodel.cpp +++ b/src/qml/types/qqmllistmodel.cpp @@ -1431,7 +1431,7 @@ QQmlListModelParser::ListInstruction *QQmlListModelParser::ListModelData::instru 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 QtQuick 2 import. For full documentation, see \l QtQuick2::ListModel + This type is also available in the \c {QtQuick 2} import. For full documentation, see \l QtQuick2::ListModel */ /*! \qmltype ListModel @@ -2540,7 +2540,7 @@ bool QQmlListModelParser::definesEmptyList(const QString &s) List elements are defined inside ListModel definitions, and represent items in a list. - This type is also available in the QtQuick 2 import. For full documentation, see \l QtQuick2::ListElement + This type is also available in the \c {QtQuick 2} import. For full documentation, see \l QtQuick2::ListElement */ /*! \qmltype ListElement diff --git a/src/qml/types/qqmlobjectmodel.cpp b/src/qml/types/qqmlobjectmodel.cpp index b60dae4126..3e8a67a7d2 100644 --- a/src/qml/types/qqmlobjectmodel.cpp +++ b/src/qml/types/qqmlobjectmodel.cpp @@ -176,7 +176,7 @@ public: as a model. This element is now primarily available as ObjectModel in the QtQml.Models module. - VisualItemModel continues to be provided, with the same implementation, in QtQuick for + VisualItemModel continues to be provided, with the same implementation, in \c QtQuick for compatibility reasons. For full details about the type, see the \l ObjectModel documentation. diff --git a/src/qmltest/quicktest.cpp b/src/qmltest/quicktest.cpp index 1dc0e3fecb..2db68bad16 100644 --- a/src/qmltest/quicktest.cpp +++ b/src/qmltest/quicktest.cpp @@ -344,7 +344,7 @@ int quick_test_main(int argc, char **argv, const char *name, const char *sourceD rootobj.setWindowShown(true); if (!rootobj.hasQuit && rootobj.hasTestCase()) eventLoop.exec(); - // view->hide(); Causes a crash in Qt3D due to deletion of the GL context, see QTBUG-27696 + // view->hide(); Causes a crash in Qt 3D due to deletion of the GL context, see QTBUG-27696 } } diff --git a/src/quick/designer/designersupport.cpp b/src/quick/designer/designersupport.cpp index 063fa6ebb1..2dd041b968 100644 --- a/src/quick/designer/designersupport.cpp +++ b/src/quick/designer/designersupport.cpp @@ -51,6 +51,8 @@ #include <QtQuick/private/qquickstategroup_p.h> #include <QtGui/QImage> #include <private/qqmlvme_p.h> +#include <private/qqmlcomponentattached_p.h> +#include <private/qqmldata_p.h> #include "designerwindowmanager_p.h" @@ -375,6 +377,17 @@ void DesignerSupport::resetAnchor(QQuickItem *item, const QString &name) } } +void DesignerSupport::emitComponentCompleteSignalForAttachedProperty(QQuickItem *item) +{ + QQmlData *data = QQmlData::get(item); + if (data && data->context) { + QQmlComponentAttached *componentAttached = data->context->componentAttached; + if (componentAttached) { + emit componentAttached->completed(); + } + } +} + QList<QObject*> DesignerSupport::statesForItem(QQuickItem *item) { QList<QObject*> objectList; diff --git a/src/quick/designer/designersupport.h b/src/quick/designer/designersupport.h index 4567e5c3d8..5139a65645 100644 --- a/src/quick/designer/designersupport.h +++ b/src/quick/designer/designersupport.h @@ -125,6 +125,7 @@ public: static QQuickItem *anchorCenterInTargetItem(QQuickItem *item); static QPair<QString, QObject*> anchorLineTarget(QQuickItem *item, const QString &name, QQmlContext *context); static void resetAnchor(QQuickItem *item, const QString &name); + static void emitComponentCompleteSignalForAttachedProperty(QQuickItem *item); static QList<QObject*> statesForItem(QQuickItem *item); diff --git a/src/quick/doc/snippets/qml/text/onLinkActivated.qml b/src/quick/doc/snippets/qml/text/onLinkActivated.qml index 9bb4d3a0bb..7a44dcc557 100644 --- a/src/quick/doc/snippets/qml/text/onLinkActivated.qml +++ b/src/quick/doc/snippets/qml/text/onLinkActivated.qml @@ -45,7 +45,7 @@ Rectangle { //![0] Text { textFormat: Text.RichText - text: "The main website is at <a href=\"http://qt.nokia.com\">Nokia Qt DF</a>." + text: "See the <a href=\"http://qt-project.org\">Qt Project website</a>." onLinkActivated: console.log(link + " link activated") } //![0] diff --git a/src/quick/doc/src/appdevguide/applicationdevelopers.qdoc b/src/quick/doc/src/appdevguide/applicationdevelopers.qdoc index c1b5a937a0..80fdc3607d 100644 --- a/src/quick/doc/src/appdevguide/applicationdevelopers.qdoc +++ b/src/quick/doc/src/appdevguide/applicationdevelopers.qdoc @@ -49,8 +49,8 @@ through other modules. If you require the functionality of those modules, you sh their QML documentation. Qt Essentials modules exposing QML types include: \list -\li \l QtMultimedia for playing and managing multimedia content and cameras. -\li \l QtWebkit for rendering web content. +\li \l {Qt Multimedia} for playing and managing multimedia content and cameras. +\li \l {Qt WebKit} for rendering web content. \endlist \section1 Quick Start diff --git a/src/quick/doc/src/appdevguide/debugging.qdoc b/src/quick/doc/src/appdevguide/debugging.qdoc index 94ce13459c..07d9bac801 100644 --- a/src/quick/doc/src/appdevguide/debugging.qdoc +++ b/src/quick/doc/src/appdevguide/debugging.qdoc @@ -45,7 +45,7 @@ function f(a, b) { \endcode The output is generated using the qDebug, qWarning, qCritical methods in C++ -(see also http://doc.qt.nokia.com/latest/debug.html#warning-and-debugging-messages). +(see also \l {Debugging Techniques}). Setting the environment variable QML_CONSOLE_EXTENDED also prints the source code location of the call. @@ -81,8 +81,8 @@ function f() { \section2 Trace -\c console.trace prints the stack trace of JavaScript execution at the point where -it was called. The stack trace info contains function name, file name, line number +\c console.trace prints the stack trace of the JavaScript execution at the point where +it was called. The stack trace info contains the function name, file name, line number and column number. The stack trace is limited to last 10 stack frames. \section2 Count @@ -150,7 +150,7 @@ QQmlImportDatabase::resolveType "Rectangle" = "QDeclarativeRectangle" \section1 Debugging with Qt Creator -\l{http://qt.nokia.com/products/developer-tools}{Qt Creator} provides built-in +\l{http://qt-project.org/doc/qtcreator}{Qt Creator} provides built-in support for QML debugging. QML projects and standalone C++ applications that utilize QML can be debugged on desktops as well as on remote devices. For more information, see the Qt Creator Manual. diff --git a/src/quick/doc/src/appdevguide/deployment.qdoc b/src/quick/doc/src/appdevguide/deployment.qdoc index 1c8bd20c4d..3788cbdb08 100644 --- a/src/quick/doc/src/appdevguide/deployment.qdoc +++ b/src/quick/doc/src/appdevguide/deployment.qdoc @@ -28,7 +28,7 @@ /*! \page qtquick-deployment.html \title Deploying QML Applications -\brief process of deploying QML applications +\brief Deploying QML applications @@ -60,7 +60,8 @@ QQmlEngine by either: \section2 Deploying with QQuickView QQuickView is a QWindow-based class that is able to load QML files. -For example, if there is a QML file, \c application.qml, like this: +For example, if there is a QML file, \c application.qml, it will +look like this: \qml import QtQuick 2.0 @@ -130,7 +131,7 @@ loaded as a QQmlComponent instance rather than placed into a view: QGuiApplication can be replaced by a QCoreApplication in the code above in case you are not using any graphical items from Qt Quick. This allows using QML as a language without any -dependencies to the Qt Gui module. +dependencies to the \l {Qt GUI} module. See \l{qtqml-cppintegration-data.html}{qtqml-cppintegration-exposecppattributes.html}{Exposing Attributes of C++ Types to QML} for more information about using QQmlEngine, QQmlContext and QQmlComponent, as well @@ -189,7 +190,7 @@ project The \c main.qml and \c background.png files will be packaged as resource files. This is done in the \c example.qrc resource collection file: -\quotefile ../src/qml/doc/snippets/qml/qtbinding/resources/example.qrc +\snippet ../src/qml/doc/snippets/qml/qtbinding/resources/example.qdoc 0 Since \c background.png is a resource file, \c main.qml can refer to it using the relative path specified in \c example.qrc: @@ -201,7 +202,7 @@ file, \c main.qml, as a resource file using the \c qrc scheme: \snippet ../src/qml/doc/snippets/qml/qtbinding/resources/main.cpp 0 -Finally \c project.pro uses the RESOURCES variable to indicate that \c example.qrc should +Finally, \c project.pro uses the RESOURCES variable to indicate that \c example.qrc should be used to build the application resources: \quotefile ../src/qml/doc/snippets/qml/qtbinding/resources/resources.pro diff --git a/src/quick/doc/src/appdevguide/glossary.qdoc b/src/quick/doc/src/appdevguide/glossary.qdoc index 2ece38256f..3c02918576 100644 --- a/src/quick/doc/src/appdevguide/glossary.qdoc +++ b/src/quick/doc/src/appdevguide/glossary.qdoc @@ -28,7 +28,7 @@ /*! \page qtquick-glossary.html \title Qt Quick Glossary Of Terms -\brief Glossary of terms used in the documentation for QML and QtQuick +\brief Glossary of terms used in the documentation for QML and Qt Quick \section1 Common Terms @@ -56,7 +56,7 @@ The QML language provides a number of built in (\l{qtqml-typesystem-basictypes.html}{basic types}), and the - QtQuick module provides various \l{qtquick-qmltypereference.html} + Qt Quick module provides various \l{qtquick-qmltypereference.html} {Qt Quick types} for building QML applications. Types can also be provided by third-party developers through (\l{qtqml-modules-topic.html}{modules}) or by the application diff --git a/src/quick/doc/src/appdevguide/performance.qdoc b/src/quick/doc/src/appdevguide/performance.qdoc index 28217e06d6..c6c4835afc 100644 --- a/src/quick/doc/src/appdevguide/performance.qdoc +++ b/src/quick/doc/src/appdevguide/performance.qdoc @@ -33,15 +33,19 @@ \section1 Timing Considerations As an application developer, you must strive to allow the rendering engine -to achieve a consistent 60 frames-per-second refresh rate. 60 FPS means +to achieve a consistent 60 frames-per-second refresh rate. 60 FPS means that there is approximately 16 milliseconds between each frame in which processing can be done, which includes the processing required to upload the draw primitives to the graphics hardware. -In practice, this means that the application developer should use asynchronous, -event driven programming wherever possible, should use worker threads to do -significant processing, should never manually spin the event loop, and should -never spend more than a couple of milliseconds per frame within blocking functions. +In practice, this means that the application developer should: +\list + \li use asynchronous,event driven programming wherever possible + \li use worker threads to do significant processing + \li never manually spin the event loop + \li never spend more than a couple of milliseconds per frame within blocking functions. +\endlist + Failure to do so will result in skipped frames, which has a drastic effect on the user experience. @@ -55,15 +59,15 @@ your event loop. \section1 Profiling -The most important tip is: use the QML profiler included with Qt Creator. Knowing +The most important tip is: use the QML profiler included with Qt Creator. Knowing where time is spent in an application will allow you to focus on problem areas which -actually exist, rather than problem areas which potentially exist. See the Qt Creator +actually exist, rather than problem areas which potentially exist. See the Qt Creator manual for more information on how to use the QML profiling tool. Determining which bindings are being run the most often, or which functions your application is spending the most time in, will allow you to decide whether you need to optimize the problem areas, or redesign some implementation details of your -application so that the performance is improved. Attempting to optimize code without +application so that the performance is improved. Attempting to optimize code without profiling is likely to result in very minor rather than significant performance improvements. @@ -71,10 +75,10 @@ improvements. Most QML applications will have a large amount of JavaScript code in them, in the form of dynamic functions, signal handlers, and property binding expressions. -This is not generally a problem (in fact, due to some optimizations in the QML engine -(bindings compiler, etc) it can for some use-cases be faster than calling a C++ function) -however care must be taken to ensure that unnecessary processing isn't triggered -accidentally. +This is generally not a problem. Thanks to some optimizations in the QML engine, +such as to the bindings compiler, it can for some use-cases be faster than calling a C++ +function. However, care must be taken to ensure that unnecessary processing isn't +triggered accidentally. \section2 Bindings @@ -82,8 +86,8 @@ There are two types of bindings in QML: optimized and non-optimized bindings. It is a good idea to keep binding expressions as simple as possible, since the QML engine makes use of an optimized binding expression evaluator which can evaluate simple binding expressions without needing to switch into a full -JavaScript execution environment. These optimized bindings are evaluated far -more efficiently than more complex (non-optimized) bindings. The basic +JavaScript execution environment. These optimized bindings are evaluated far +more efficiently than more complex (non-optimized) bindings. The basic requirement for optimization of bindings is that the type information of every symbol accessed must be known at compile time. @@ -101,7 +105,7 @@ The QML_COMPILER_STATS environment variable may be set when running a QML applic to print statistics about how many bindings were able to be optimized. Bindings are quickest when they know the type of objects and properties they are working -with. This means that non-final property lookup in a binding expression can be slower +with. This means that non-final property lookup in a binding expression can be slower in some cases, where it is possible that the type of the property being looked up has been changed (for example, by a derived type). @@ -120,17 +124,17 @@ will not be optimized. Note that if a binding cannot be optimized by the QML engine's optimized binding expression evaluator, and thus must be evaluated by the full JavaScript environment, -some of the tips listed above will no longer apply. For example, it can sometimes be +some of the tips listed above will no longer apply. For example, it can sometimes be beneficial to cache the result of property resolution in an intermediate JavaScript -variable, in a very complex binding. Upcoming sections have more information on these +variable in a very complex binding. Upcoming sections have more information on these sorts of optimizations. \section2 Type-Conversion One major cost of using JavaScript is that in most cases when a property from a QML type is accessed, a JavaScript object with an external resource containing the -underlying C++ data (or a reference to it) is created. In most cases, this is fairly -inexpensive, but in others it can be quite expensive. One example of where it is +underlying C++ data (or a reference to it) is created. In most cases, this is fairly +inexpensive, but in others it can be quite expensive. One example of where it is expensive is assigning a C++ QVariantMap Q_PROPERTY to a QML "variant" property. Lists can also be expensive, although sequences of specific types (QList of int, qreal, bool, QString, and QUrl) should be inexpensive; other list types involve an @@ -138,11 +142,11 @@ expensive conversion cost (creating a new JavaScript Array, and adding new types one by one, with per-type conversion from C++ type instance to JavaScript value). Converting between some basic property types (such as "string" and "url" properties) -can also be expensive. Using the closest matching property type will avoid unnecessary +can also be expensive. Using the closest matching property type will avoid unnecessary conversion. If you must expose a QVariantMap to QML, use a "var" property rather than a "variant" -property. In general, "property var" should be considered to be superior to +property. In general, "property var" should be considered to be superior to "property variant" for every use-case in QtQuick 2.0 (note that "property variant" is marked as obsolete in the QtQuick 2.0 documentation), as it allows a true JavaScript reference to be stored (which can reduce the number of conversions required in certain @@ -150,7 +154,7 @@ expressions). \section2 Resolving Properties -Property resolution takes time. While in some cases the result of a lookup can be +Property resolution takes time. While in some cases the result of a lookup can be cached and reused, it is always best to avoid doing unnecessary work altogether, if possible. @@ -264,7 +268,7 @@ Item { \section2 Property Bindings A property binding expression will be re-evaluated if any of the properties -it references are changed. As such, binding expressions should be kept as +it references are changed. As such, binding expressions should be kept as simple as possible. If you have a loop where you do some processing, but only the final result @@ -339,9 +343,9 @@ Item { \section2 Sequence tips -As mentioned earlier, some sequence types are fast (eg, QList<int>, QList<qreal>, +As mentioned earlier, some sequence types are fast (for example, QList<int>, QList<qreal>, QList<bool>, QList<QString>, QStringList and QList<QUrl>) while others will be -much slower. Aside from using these types wherever possible instead of slower types, +much slower. Aside from using these types wherever possible instead of slower types, there are some other performance-related semantics you need to be aware of to achieve the best performance. @@ -351,7 +355,7 @@ and another for where the sequence is returned from a Q_INVOKABLE function of a QObject (we'll call this a copy sequence). A reference sequence is read and written via QMetaObject::property() and thus is read -and written as a QVariant. This means that changing the value of any element in the +and written as a QVariant. This means that changing the value of any element in the sequence from JavaScript will result in three steps occurring: the complete sequence will be read from the QObject (as a QVariant, but then cast to a sequence of the correct type); the element at the specified index will be changed in that sequence; and the @@ -362,7 +366,7 @@ object's resource data, so no read/modify/write cycle occurs (instead, the resou data is modified directly). Therefore, writes to elements of a reference sequence will be much slower than writes -to elements of a copy sequence. In fact, writing to a single element of an N-element +to elements of a copy sequence. In fact, writing to a single element of an N-element reference sequence is equivalent in cost to assigning a N-element copy sequence to that reference sequence, so you're usually better off modifying a temporary copy sequence and then assigning the result to a reference sequence, during computation. @@ -419,7 +423,7 @@ SequenceTypeExample { \endqml The QObject property read and write in the inner loop caused by the -\c{"qrealListProperty[j] = j"} expression makes this code very suboptimal. Instead, +\c{"qrealListProperty[j] = j"} expression makes this code very suboptimal. Instead, something functionally equivalent but much faster would be: \qml @@ -482,7 +486,7 @@ SequenceTypeExample { Note that even though only the element at index 2 is modified in the loop, the three bindings will all be re-evaluated since the granularity of the change signal is that -the entire property has changed. As such, adding an intermediate binding can +the entire property has changed. As such, adding an intermediate binding can sometimes be beneficial: \qml @@ -515,8 +519,8 @@ resulting in a significant performance increase. \section2 Value-Type tips Value-type properties (font, color, vector3d, etc) have similar QObject property -and change notification semantics to sequence type properties. As such, the tips -given above for sequences are also applicable for value-type properties. While +and change notification semantics to sequence type properties. As such, the tips +given above for sequences are also applicable for value-type properties. While they are usually less of a problem with value-types (since the number of sub-properties of a value-type is usually far less than the number of elements in a sequence), any increase in the number of bindings being re-evaluated needlessly @@ -524,12 +528,12 @@ will have a negative impact on performance. \section2 Other JavaScript Objects -Different JavaScript engines provide different optimizations. The JavaScript engine -which QtQuick 2 uses is optimized for object instantiation and property lookup, but -the optimizations which it provides relies on certain criteria. If your application -does not meet the criteria, the JavaScript engine falls back to a "slow-path" mode -with much worse performance. As such, always try to ensure you meet the following -criteria: +Different JavaScript engines provide different optimizations. The JavaScript engine +which \l {Qt Quick}{Qt Quick 2} uses is optimized for object instantiation and property +lookup, but the optimizations which it provides relies on certain criteria. If your +application does not meet the criteria, the JavaScript engine falls back to a +"slow-path" mode with much worse performance. As such, always try to ensure you +meet the following criteria: \list \li Avoid using eval() if at all possible @@ -540,27 +544,27 @@ criteria: \section2 Text Elements -Calculating text layouts can be a slow operation. Consider using the \c PlainText +Calculating text layouts can be a slow operation. Consider using the \c PlainText format instead of \c StyledText wherever possible, as this reduces the amount of work -required of the layout engine. If you cannot use \c PlainText (as you need to embed +required of the layout engine. If you cannot use \c PlainText (as you need to embed images, or use tags to specify ranges of characters to have certain formatting (bold, italic, etc) as opposed to the entire text) then you should use \c StyledText. You should only use \c AutoText if the text might be (but probably isn't) -\c StyledText as this mode will incur a parsing cost. The \c RichText mode should +\c StyledText as this mode will incur a parsing cost. The \c RichText mode should not be used, as \c StyledText provides almost all of its features at a fraction of its cost. \section2 Images -Images are a vital part of any user interface. Unfortunately, they are also a big +Images are a vital part of any user interface. Unfortunately, they are also a big source of problems due to the time it takes to load them, the amount of memory they consume, and the way in which they are used. \section3 Asynchronous Loading Images are often quite large, and so it is wise to ensure that loading an image doesn't -block the UI thread. Set the "asynchronous" property of the QML Image element to +block the UI thread. Set the "asynchronous" property of the QML Image element to \c true to enable asynchronous loading of images from the local file system (remote images are always loaded asynchronously) where this would not result in a negative impact upon the aesthetics of the user interface. @@ -579,13 +583,13 @@ Beware that changing the sourceSize will cause the image to be reloaded. \section3 Avoid Run-time Composition Also remember that you can avoid doing composition work at run-time by providing the -pre-composed image resource with your application (e.g., providing elements with shadow +pre-composed image resource with your application (for example, providing elements with shadow effects). \section2 Position Elements With Anchors It is more efficient to use anchors rather than bindings to position items -relative to each other. Consider this use of bindings to position rect2 +relative to each other. Consider this use of bindings to position rect2 relative to rect1: \code @@ -626,9 +630,9 @@ and height properties of visual objects, rather than using anchors) is relatively slow, although it allows maximum flexibility. If the layout is not dynamic, the most performant way to specify the layout is -via static initialization of the x, y, width and height properties. Item +via static initialization of the x, y, width and height properties. Item coordinates are always relative to their parent, so if you wanted to be a fixed -offset from your parent's 0,0 coordinate you should not use anchors. In the +offset from your parent's 0,0 coordinate you should not use anchors. In the following example the child Rectangle objects are in the same place, but the anchors code shown is not as resource efficient as the code which uses fixed positioning via static initialization: @@ -654,14 +658,14 @@ Rectangle { \section1 Models and Views -Most applications will have at least one model feeding data to a view. There are +Most applications will have at least one model feeding data to a view. There are some semantics which application developers need to be aware of, in order to achieve maximal performance. \section2 Custom C++ Models It is often desirable to write your own custom model in C++ for use with a view in -QML. While the optimal implementation of any such model will depend heavily on the +QML. While the optimal implementation of any such model will depend heavily on the use-case it must fulfil, some general guidelines are as follows: \list @@ -673,7 +677,7 @@ use-case it must fulfil, some general guidelines are as follows: It is important to note that using a low-priority worker thread is recommended to minimise the risk of starving the GUI thread (which could result in worse perceived -performance). Also, remember that synchronization and locking mechanisms can be a +performance). Also, remember that synchronization and locking mechanisms can be a significant cause of slow performance, and so care should be taken to avoid unnecessary locking. @@ -685,35 +689,35 @@ it is used correctly. \section3 Populate Within A Worker Thread -ListModel elements can be populated in a (low priority) worker thread in JavaScript. The +ListModel elements can be populated in a (low priority) worker thread in JavaScript. The developer must explicitly call "sync()" on the ListModel from within the WorkerScript to -have the changes synchronized to the main thread. See the WorkerScript documentation +have the changes synchronized to the main thread. See the WorkerScript documentation for more information. Please note that using a WorkerScript element will result in a separate JavaScript engine -being created (as the JavaScript engine is per-thread). This will result in increased -memory usage. Multiple WorkerScript elements will all use the same worker thread, however, +being created (as the JavaScript engine is per-thread). This will result in increased +memory usage. Multiple WorkerScript elements will all use the same worker thread, however, so the memory impact of using a second or third WorkerScript element is negligible once an application already uses one. \section3 Don't Use Dynamic Roles -The ListModel element in QtQuick 2.0 is much more performant than in QtQuick 1.0. The +The ListModel element in \c {QtQuick 2.0} is much more performant than in \c {QtQuick 1.0}. The performance improvements mainly come from assumptions about the type of roles within each element in a given model - if the type doesn't change, the caching performance improves -dramatically. If the type can change dynamically from element to element, this optimization +dramatically. If the type can change dynamically from element to element, this optimization becomes impossible, and the performance of the model will be an order of magnitude worse. Therefore, dynamic typing is disabled by default; the developer must specifically set the boolean "dynamicRoles" property of the model to enable dynamic typing (and suffer -the attendant performance degradation). We recommend that you do not use dynamic typing +the attendant performance degradation). We recommend that you do not use dynamic typing if it is possible to redesign your application to avoid it. \section2 Views -View delegates should be kept as simple as possible. Have just enough QML in the delegate -to display the necessary information. Any additional functionality which is not immediately -required (e.g., if it displays more information when clicked) should not be created until +View delegates should be kept as simple as possible. Have just enough QML in the delegate +to display the necessary information. Any additional functionality which is not immediately +required (for example, if it displays more information when clicked) should not be created until needed (see the upcoming section on lazy initialization). The following list is a good summary of things to keep in mind when designing a delegate: @@ -727,31 +731,31 @@ The following list is a good summary of things to keep in mind when designing a \endlist You may set the \c cacheBuffer property of a view to allow asynchronous creation and -buffering of delegates outside of the visible area. Utilizing a \c cacheBuffer is +buffering of delegates outside of the visible area. Utilizing a \c cacheBuffer is recommended for view delegates that are non-trivial and unlikely to be created within a single frame. Be mindful that a \c cacheBuffer keeps additional delegates in-memory and therefore the value derived from utilizing the \c cacheBuffer must be balanced against additional memory -usage. Developers should use benchmarking to find the best value for their use-case, since +usage. Developers should use benchmarking to find the best value for their use-case, since the increased memory pressure caused by utilizing a \c cacheBuffer can, in some rare cases, cause reduced frame rate when scrolling. \section1 Visual Effects -QtQuick 2 includes several features which allow developers and designers to create -exceptionally appealing user interfaces. Fluidity and dynamic transitions as well +\l {Qt Quick}{Qt Quick 2} includes several features which allow developers and designers to create +exceptionally appealing user interfaces. Fluidity and dynamic transitions as well as visual effects can be used to great effect in an application, but some care must be taken when using some of the features in QML as they can have performance implications. \section2 Animations In general, animating a property will cause any bindings which reference that property -to be re-evaluated. Usually, this is what is desired but in other cases it may be better +to be re-evaluated. Usually, this is what is desired but in other cases it may be better to disable the binding prior to performing the animation, and then reassign the binding once the animation has completed. -Avoid running JavaScript during animation. For example, running a complex JavaScript +Avoid running JavaScript during animation. For example, running a complex JavaScript expression for each frame of an x property animation should be avoided. Developers should be especially careful using script animations, as these are run in the main @@ -759,29 +763,29 @@ thread (and therefore can cause frames to be skipped if they take too long to co \section2 Particles -The QtQuick 2.0 Particles module allows beautiful particle effects to be integrated -seamlessly into user interfaces. However every platform has different graphics hardware +The \l {QtQuick.Particles 2}{Qt Quick 2.0 Particles} module allows beautiful particle effects to be integrated +seamlessly into user interfaces. However every platform has different graphics hardware capabilities, and the Particles module is unable to limit parameters to what your hardware -can gracefully support. The more particles you attempt to render (and the larger they are), -the faster your graphics hardware will need to be in order to render at 60 FPS. Affecting -more particles requires a faster CPU. It is therefore important to test all +can gracefully support. The more particles you attempt to render (and the larger they are), +the faster your graphics hardware will need to be in order to render at 60 FPS. Affecting +more particles requires a faster CPU. It is therefore important to test all particle effects on your target platform carefully, to calibrate the number and size of particles you can render at 60 FPS. It should be noted that a particle system can be disabled when not in use -(e.g., on a non-visible element) to avoid doing unnecessary simulation. +(for example, on a non-visible element) to avoid doing unnecessary simulation. See the \l{Particle System Performance Guide} for more in-depth information. \section2 Shaders Shaders written in GLSL allow for complex transformations and visual effects to be written, -however they should be used with care. Using a ShaderEffectSource causes a scene to -prerendered into an FBO before it can be drawn. This extra overhead is quite expensive. +however they should be used with care. Using a ShaderEffectSource causes a scene to +prerendered into an FBO before it can be drawn. This extra overhead is quite expensive. A ShaderEffect element can imply a ShaderEffectSource (and the indirect rendering costs associated with that) and also involves uploading a vertex and fragment shader program -(which is then compiled into a GLSL shader). Each fragment shader runs once for every +(which is then compiled into a GLSL shader). Each fragment shader runs once for every pixel of the scene, and so these should be kept as simple as possible. \section1 Controlling Element Lifetime @@ -793,9 +797,9 @@ usage, and reduce the number of active-but-invisible elements in your applicatio \section2 Lazy Initialization The QML engine does some tricky things to try to ensure that loading and initialization of -components doesn't cause frames to be skipped, however there is no better way to reduce +components doesn't cause frames to be skipped. However, there is no better way to reduce startup time than to avoid doing work you don't need to do, and delaying the work until -it is necessary. This may be achieved by using either \l Loader or creating components +it is necessary. This may be achieved by using either \l Loader or creating components \l {qtqml-javascript-dynamicobjects.html}{dynamically}. \section3 Using Loader @@ -813,29 +817,29 @@ The Loader is an element which allows dynamic loading and unloading of component \section3 Using Dynamic Creation Developers can use the Qt.createComponent() function to create a component dynamically at -runtime from within JavaScript, and then call createObject() to instantiate it. Depending +runtime from within JavaScript, and then call createObject() to instantiate it. Depending on the ownership semantics specified in the call, the developer may have to delete the -created object manually. See \l{qtqml-javascript-dynamicobjects.html} +created object manually. See \l{qtqml-javascript-dynamicobjects.html} {Dynamic Object Management in QML} for more information. \section2 Destroy Unused Elements -Elements which are invisible because they are a child of a non-visible element (e.g., the +Elements which are invisible because they are a child of a non-visible element (for example, the second tab in a tab-widget, while the first tab is shown) should be initialized lazily in most cases, and deleted when no longer in use, to avoid the ongoing cost of leaving them -active (e.g., rendering, animations, property binding evaluation, etc). +active (for example, rendering, animations, property binding evaluation, etc). An item loaded with a Loader element may be released by resetting the "source" or "sourceComponent" property of the Loader, while other items may be explicitly -released by calling destroy() on them. In some cases, it may be necessary to +released by calling destroy() on them. In some cases, it may be necessary to leave the item active, in which case it should be made invisible at the very least. See the upcoming section on Rendering for more information on active but invisible elements. \section1 Rendering -The scene graph used for rendering in QtQuick 2.0 allows highly dynamic, animated user -interfaces to be rendered fluidly at 60 FPS. There are some things which can +The scene graph used for rendering in \c {QtQuick 2.0} allows highly dynamic, animated user +interfaces to be rendered fluidly at 60 FPS. There are some things which can dramatically decrease rendering performance, however, and developers should be careful to avoid these pitfalls wherever possible. @@ -843,9 +847,9 @@ to avoid these pitfalls wherever possible. Clipping is disabled by default, and should only be enabled when required. -Clipping is a visual effect, NOT an optimization. It increases (rather than reduces) -complexity for the renderer. If clipping is enabled, an item will clip its own painting, -as well as the painting of its children, to its bounding rectangle. This stops the renderer +Clipping is a visual effect, NOT an optimization. It increases (rather than reduces) +complexity for the renderer. If clipping is enabled, an item will clip its own painting, +as well as the painting of its children, to its bounding rectangle. This stops the renderer from being able to reorder the drawing order of elements freely, resulting in a sub-optimal best-case scene graph traversal. @@ -854,10 +858,10 @@ Clipping inside a delegate is especially bad and should be avoided at all costs. \section2 Over-drawing and Invisible Elements If you have elements which are totally covered by other (opaque) elements, it is best to -set their "visible" property to \c false or they will be needlessly drawn. +set their "visible" property to \c false or they will be drawn needlessly. -Similarly, elements which are invisible (e.g., the second tab in a tab widget, while the -first tab is shown) but need to be initialized at startup time (e.g., if the cost of +Similarly, elements which are invisible (for example, the second tab in a tab widget, while the +first tab is shown) but need to be initialized at startup time (for example, if the cost of instantiating the second tab takes too long to be able to do it only when the tab is activated), should have their "visible" property set to \c false, in order to avoid the cost of drawing them (although as previously explained, they will still incur the cost of @@ -866,50 +870,50 @@ any animations or bindings evaluation since they are still active). \section2 Manual Layouts The scene graph renderer is able to batch up certain operations to minimise the number of -OpenGL state changes required. However, this optimization is only possible for the -built-in layout elements provided by QtQuick 2.0, and cannot be applied to manual layouts. +OpenGL state changes required. However, this optimization is only possible for the +built-in layout elements provided by \c {QtQuick 2.0}, and cannot be applied to manual layouts. -Therefore, application developers should use the Row, Column, Grid, GridView and ListView +Therefore, application developers should use the Row, Column, Grid, GridView, and ListView elements instead of manual layouts wherever possible. \section1 Memory Allocation And Collection The amount of memory which will be allocated by an application and the way in which that -memory will be allocated are very important considerations. Aside from the obvious +memory will be allocated are very important considerations. Aside from the obvious concerns about out-of-memory conditions on memory-constrained devices, allocating memory on the heap is a fairly computationally expensive operation, and certain allocation -strategies can result in increased fragmentation of data across pages. JavaScript uses +strategies can result in increased fragmentation of data across pages. JavaScript uses a managed memory heap which is automatically garbage collected, and this provides some advantages but also has some important implications. An application written in QML uses memory from both the C++ heap and an automatically -managed JavaScript heap. The application developer needs to be aware of the subtleties +managed JavaScript heap. The application developer needs to be aware of the subtleties of each in order to maximise performance. \section2 Tips For QML Application Developers The tips and suggestions contained in this section are guidelines only, and may not be -applicable in all circumstances. Be sure to benchmark and analyse your application +applicable in all circumstances. Be sure to benchmark and analyze your application carefully using empirical metrics, in order to make the best decisions possible. \section3 Instantiate and initialize components lazily If your application consists of multiple views (for example, multiple tabs) but only one is required at any one time, you can use lazy instantiation to minimize the -amount of memory you need to have allocated at any given time. See the prior section +amount of memory you need to have allocated at any given time. See the prior section on \l{Lazy Initialization} for more information. \section3 Destroy unused objects If you lazily instantiate components, or dynamically create objects during a JavaScript expression, it is often better to manually \c{destroy()} them rather than waiting for -automatic garbage collection to do so. See the prior section on +automatic garbage collection to do so. See the prior section on \l{Controlling Element Lifetime} for more information. \section3 Don't manually invoke the garbage collector In most cases, it is not wise to manually invoke the garbage collector, as it will block -the GUI thread for a substantial period of time. This can result in skipped frames and +the GUI thread for a substantial period of time. This can result in skipped frames and jerky animations, which should be avoided at all costs. There are some cases where manually invoking the garbage collector is acceptable (and @@ -926,34 +930,34 @@ evaluated by QML's optimized binding expression evaluator. \section3 Avoid defining multiple identical implicit types If a QML element has a custom property defined in QML, it becomes its own implicit type. -This is explained in greater detail in an upcoming section. If multiple identical -implicit types are defined inline in a component, some memory will be wasted. In that +This is explained in greater detail in an upcoming section. If multiple identical +implicit types are defined inline in a component, some memory will be wasted. In that situation it is usually better to explicitly define a new component which can then be reused. Defining a custom property can often be a beneficial performance optimization (for example, to reduce the number of bindings which are required or re-evaluated), or it -can improve the modularity and maintainability of a component. In those cases, using -custom properties is encouraged; however, the new type should, if it is used more than +can improve the modularity and maintainability of a component. In those cases, using +custom properties is encouraged. However, the new type should, if it is used more than once, be split into its own component (.qml file) in order to conserve memory. \section3 Re-use existing components If you are considering defining a new component, it's worth double checking that such a -component doesn't already exist in the component set for your platform. Otherwise, you +component doesn't already exist in the component set for your platform. Otherwise, you will be forcing the QML engine to generate and store type-data for a type which is essentially a duplicate of another pre-existing and potentially already loaded component. \section3 Use singleton types instead of pragma library scripts If you are using a pragma library script to store application-wide instance data, -consider using a QObject singleton type instead. This should result in better performance, +consider using a QObject singleton type instead. This should result in better performance, and will result in less JavaScript heap memory being used. \section2 Memory Allocation in a QML Application -The memory usage of a QML application may be split into two parts: its C++ heap usage, -and its JavaScript heap usage. Some of the memory allocated in each will be unavoidable, +The memory usage of a QML application may be split into two parts: its C++ heap usage +and its JavaScript heap usage. Some of the memory allocated in each will be unavoidable, as it is allocated by the QML engine or the JavaScript engine, while the rest is dependent upon decisions made by the application developer. @@ -983,16 +987,16 @@ The JavaScript heap will contain: \endlist Furthermore, there will be one JavaScript heap allocated for use in the main thread, and -optionally one other JavaScript heap allocated for use in the WorkerScript thread. If an -application does not use a WorkerScript element, that overhead will not be incurred. The +optionally one other JavaScript heap allocated for use in the WorkerScript thread. If an +application does not use a WorkerScript element, that overhead will not be incurred. The JavaScript heap can be several megabytes in size, and so applications written for memory-constrained devices may be best served to avoid using the WorkerScript element despite its usefulness in populating list models asynchronously. Note that both the QML engine and the JavaScript engine will automatically generate their -own caches of type-data about observed types. Every component loaded by an application +own caches of type-data about observed types. Every component loaded by an application is a distinct (explicit) type, and every element (component instance) which defines its -own custom properties in QML is an implicit type. Any element (instance of a component) +own custom properties in QML is an implicit type. Any element (instance of a component) which does not define any custom properties is considered by the JavaScript and QML engines to be of the type explicitly defined by the component, rather than its own implicit type. @@ -1032,10 +1036,10 @@ Item { \endqml In the previous example, the rectangles \c r0 and \c r1 do not have any custom properties, -and thus the JavaScript and QML engines consider them both to be of the same type. That +and thus the JavaScript and QML engines consider them both to be of the same type. That is, \c r0 and \c r1 are both considered to be of the explicitly defined \c Rectangle type. The rectangles \c r2, \c r3 and \c r4 each have custom properties and are each considered -to be different (implicit) types. Note that \c r3 and \c r4 are each considered to be of +to be different (implicit) types. Note that \c r3 and \c r4 are each considered to be of different types, even though they have identical property information, simply because the custom property was not declared in the component which they are instances of. @@ -1048,26 +1052,26 @@ instances of the \c RectangleWithString type, rather than defining their own imp Whenever making decisions regarding memory allocation or performance trade-offs, it is important to keep in mind the impact of CPU-cache performance, operating system paging, -and JavaScript engine garbage collection. Potential solutions should be benchmarked +and JavaScript engine garbage collection. Potential solutions should be benchmarked carefully in order to ensure that the best one is selected. No set of general guidelines can replace a solid understanding of the underlying principles of computer science combined with a practical knowledge of the implementation -details of the platform for which the application developer is developing. Furthermore, +details of the platform for which the application developer is developing. Furthermore, no amount of theoretical calculation can replace a good set of benchmarks and analysis tools when making trade-off decisions. \section3 Fragmentation -Fragmentation is a C++ development issue. If the application developer is not defining +Fragmentation is a C++ development issue. If the application developer is not defining any C++ types or plugins, they may safely ignore this section. Over time, an application will allocate large portions of memory, write data to that memory, and subsequently free some portions of that memory once it has finished using -some of the data. This can result in "free" memory being located in non-contiguous +some of the data. This can result in "free" memory being located in non-contiguous chunks, which cannot be returned to the operating system for other applications to use. It also has an impact on the caching and access characteristics of the application, as -the "living" data may be spread across many different pages of physical memory. This +the "living" data may be spread across many different pages of physical memory. This in turn could force the operating system to swap which can cause filesystem I/O - which is, comparatively speaking, an extremely slow operation. @@ -1078,18 +1082,18 @@ or by utilizing a memory-managed runtime with garbage collection (such as JavaSc \section3 Garbage Collection -JavaScript provides garbage collection. Memory which is allocated on the JavaScript -heap (as opposed to the C++ heap) is owned by the JavaScript engine. The engine will +JavaScript provides garbage collection. Memory which is allocated on the JavaScript +heap (as opposed to the C++ heap) is owned by the JavaScript engine. The engine will periodically collect all unreferenced data on the JavaScript heap, and if fragmentation becomes an issue, it will compact its heap by moving all "living" data into a contiguous region of memory (allowing the freed memory to be returned to the operating system). \section4 Implications of Garbage Collection -Garbage collection has advantages and disadvantages. It ensures that fragmentation is +Garbage collection has advantages and disadvantages. It ensures that fragmentation is less of an issue, and it means that manually managing object lifetime is less important. However, it also means that a potentially long-lasting operation may be initiated by the -JavaScript engine at a time which is out of the application developer's control. Unless +JavaScript engine at a time which is out of the application developer's control. Unless JavaScript heap usage is considered carefully by the application developer, the frequency and duration of garbage collection may have a negative impact upon the application experience. @@ -1097,17 +1101,17 @@ experience. \section4 Manually Invoking the Garbage Collector An application written in QML will (most likely) require garbage collection to be -performed at some stage. While garbage collection will be automatically triggered by +performed at some stage. While garbage collection will be automatically triggered by the JavaScript engine when the amount of available free memory is low, it is occasionally better if the application developer makes decisions about when to invoke the garbage collector manually (although usually this is not the case). The application developer is likely to have the best understanding of when an application -is going to be idle for substantial periods of time. If a QML application uses a lot +is going to be idle for substantial periods of time. If a QML application uses a lot of JavaScript heap memory, causing regular and disruptive garbage collection cycles during particularly performance-sensitive tasks (for example, list scrolling, animations, and so forth), the application developer may be well served to manually invoke the -garbage collector during periods of zero activity. Idle periods are ideal for performing +garbage collector during periods of zero activity. Idle periods are ideal for performing garbage collection since the user will not notice any degradation of user experience (skipped frames, jerky animations, and so on) which would result from invoking the garbage collector while activity is occurring. @@ -1120,14 +1124,14 @@ so should be avoided if at all possible. \section3 Memory vs Performance Trade-offs In some situations, it is possible to trade-off increased memory usage for decreased -processing time. For example, caching the result of a symbol lookup used in a tight loop +processing time. For example, caching the result of a symbol lookup used in a tight loop to a temporary variable in a JavaScript expression will result in a significant performance improvement when evaluating that expression, but it involves allocating a temporary variable. In some cases, these trade-offs are sensible (such as the case above, which is almost always sensible), but in other cases it may be better to allow processing to take slightly longer in order to avoid increasing the memory pressure on the system. -In some cases, the impact of increased memory pressure can be extreme. In some situations, +In some cases, the impact of increased memory pressure can be extreme. In some situations, trading off memory usage for an assumed performance gain can result in increased page-thrash or cache-thrash, causing a huge reduction in performance. It is always necessary to benchmark the impact of trade-offs carefully in order to determine which solution is best in a given diff --git a/src/quick/doc/src/appdevguide/porting.qdoc b/src/quick/doc/src/appdevguide/porting.qdoc index 750a0e1242..7d972002e7 100644 --- a/src/quick/doc/src/appdevguide/porting.qdoc +++ b/src/quick/doc/src/appdevguide/porting.qdoc @@ -40,16 +40,16 @@ interested in the summary of all new features in Qt 5 for QML application develo \section1 QML Language changes -There are very few changes in the QML language which affect the porting of existing Qt 4.8 QML code to Qt 5. These are: +There are very few changes in the QML language that affect the porting of existing Qt 4.8 QML code to Qt 5. These are: \list -\li Individual file imports no longer work (e.g. import "MyType.qml"). Import the containing directory instead. +\li Individual file imports no longer work (for example, import "MyType.qml"). Import the containing directory instead. \li Relative file paths in JavaScript files are now resolved relative to the location of the JavaScript file instead of the QML file that imported it. \endlist \section1 QtQuick Module -The QtQuick module has been updated to version 2.0. All QML applications should update their import +The \c QtQuick module has been updated to version 2.0. All QML applications should update their import statements to use the new version: \qml @@ -77,12 +77,12 @@ into a \c QtQuick.LocalStorage singleton type. Any code that requires the local \e {QtQuick.LocalStorage} instead. See the \l {QtQuick.LocalStorage 2}{QtQuick.LocalStorage} documentation for examples. \li The \c LayoutItem type has been removed from the \c QtQuick module as it was specific to the -Graphics View framework backend used in QtQuick 1. +Graphics View framework backend used in \l {Qt Quick 1}. \endlist \section2 Behavioral Changes -QtQuick 2.0 includes a number of behavioral changes and you should thoroughly test your applications after +\c {QtQuick 2.0} includes a number of behavioral changes and you should thoroughly test your applications after porting. These changes will not necessarily lead to run-time errors, but may break certain assumptions in your code. Below are the prominent changes to be aware of when porting your applications. @@ -96,7 +96,7 @@ Item opacity and visibility: \tt {(visible && opacity > 0.0)}. \li Previously, if an item was in a positioner (i.e. a \l Row, \l Column, \l Grid and \l Flow) and the item's \c opacity changed to 0, or its \c visible value became \c false, the positioner - would remove the item from its layout and collapse the space for that item. In QtQuick 2.0, this + would remove the item from its layout and collapse the space for that item. In \c {QtQuick 2.0}, this now only happens when an item's \c visible is \c false; the item opacity no longer affects whether the item is laid out. (This is consistent with the existing behavior of ListView and GridView). \endlist @@ -127,9 +127,9 @@ Other: \list \li The \c Qt.labs.particles module has been removed. It is replaced by the fully-fledged \l -QtQuick.particles module which is an enormous improvement on its predecessor. +QtQuick.Particles module which is an enormous improvement on its predecessor. \li The \c Qt.labs.shaders module has been removed as the \c ShaderEffectItem and \l -ShaderEffectSource types from this module have been moved into the \l QtQuick module. Note the \c +ShaderEffectSource types from this module have been moved into the \c QtQuick module. Note the \c ShaderEffectItem type has been renamed to \l ShaderEffect. \endlist @@ -138,18 +138,18 @@ ShaderEffectItem type has been renamed to \l ShaderEffect. In Qt 5, all QML applications are rendered with an OpenGL scenegraph architecture rather than the Graphics View framework used in Qt 4. Due to the scale of this architectural change, the C++ API has -been extensively restructured and the \c QtDeclarative module has been deprecated in favour of two -new modules: \l {Qt QML}, which implements the QML engine and language infrastructure, and \l QtQuick, +been extensively restructured and the \c QtDeclarative module has been deprecated in favor of two +new modules: \l {Qt QML}, which implements the QML engine and language infrastructure, and \l {Qt Quick}, which implements the visual canvas and scenegraph backend. All classes that were previously in the \c QtDeclarative module have been moved into the \l {Qt QML} -and \l QtQuick modules, and their class names have been changed to reflect their new module +and \l {Qt Quick} modules, and their class names have been changed to reflect their new module locations. The class name changes are as follows: \table \header \li Qt QML - \li QtQuick + \li Qt Quick \row \li \list @@ -176,8 +176,8 @@ locations. The class name changes are as follows: \endlist \endtable -To use the new \c QQml* and \c QtQuick* classes in Qt 5, link against the approprate module from -your qmake \c .pro file. For example the following will link against both the \l {Qt QML} and QtQuick +To use the new \c QQml* and \c QQuick* classes in Qt 5, link against the approprate module from +your qmake \c .pro file. For example the following will link against both the \l {Qt QML} and \l {Qt Quick} modules: \code @@ -191,8 +191,8 @@ Required header files can then be included: #include <QtQuick/QQuickView> \endcode -(The \c QtDeclarative module is still available to developers as the \l QtQuick1 module, as -discussed in \l{Using the QtDeclarative module in Qt 5}{below}. However, it should not be used for +(The \c QtDeclarative module is still available to developers as the \c {Qt Quick 1} module, as +discussed \l {Qt Quick 1}{below}. However, it should not be used for new applications.) @@ -232,20 +232,22 @@ See the updated \l {qtqml-modules-cppplugins.html}{Creating C++ Plugins For QML} an overview of creating QML plugins in Qt 5. +\keyword Qt Quick 1 + \section2 QtDeclarative module in Qt 5 -For the purposes of porting older applications, the \c QtDeclarative module is still available in Qt -5 but has been renamed to \c QtQuick1. Applications that required QtQuick 1 specific API (e.g. +For the purposes of porting older applications, the \c {QtDeclarative} module is still available in Qt +5 but has been renamed to \c {Qt Quick 1}. Applications that required Qt Quick 1 specific API (e.g. QDeclarativeView or QDeclarativeItem and the Graphics View integration) can use this module. Note -that new applications should use the new \l {Qt QML} and \l QtQuick modules instead. +that new applications should use the new \l {Qt QML} and \l {Qt Quick} modules instead. -To use the \c QtQuick1 module, add “quick1” module to your qmake \c .pro file: +To use the \c {Qt Quick 1} module, add "quick1" to your qmake \c .pro file: \code QT += quick1 \endcode -Required header files can be included from the QtQuick 1 module: +Required header files can be included from the Qt Quick 1 module: \code #include <QtQuick1/QDeclarativeView> diff --git a/src/quick/doc/src/appdevguide/qmlscene.qdoc b/src/quick/doc/src/appdevguide/qmlscene.qdoc index a749b48c04..1a2e66e962 100644 --- a/src/quick/doc/src/appdevguide/qmlscene.qdoc +++ b/src/quick/doc/src/appdevguide/qmlscene.qdoc @@ -106,7 +106,7 @@ } \endqml - If within the document's directory, there is a \c{dummydata} directory + If, within the document's directory, there is a \c{dummydata} directory which contains a \c lottoNumbers.qml file like this: \qml diff --git a/src/quick/doc/src/appdevguide/qtquicktest.qdoc b/src/quick/doc/src/appdevguide/qtquicktest.qdoc index a5712cab8a..62369c1526 100644 --- a/src/quick/doc/src/appdevguide/qtquicktest.qdoc +++ b/src/quick/doc/src/appdevguide/qtquicktest.qdoc @@ -54,7 +54,7 @@ \endcode Functions whose names start with \c{test_} are treated as test cases - to be executed. See the documentation for the \l TestCase and + to be executed. See the documentation for the \l TestCase and \l SignalSpy types for more information on writing test cases. \section1 Running tests @@ -67,8 +67,8 @@ QUICK_TEST_MAIN(example) \endcode - Where "example" is an identifier to use to uniquely identify - this set of tests. You should add \c{CONFIG += qmltestcase}. + Where "example" is the identifier to use to uniquely identify + this set of tests. You should add \c{CONFIG += qmltestcase}. for example: \code @@ -79,15 +79,15 @@ \endcode The test harness scans the specified source directory recursively - for "tst_*.qml" files. If \c{QUICK_TEST_SOURCE_DIR} is not defined, + for "tst_*.qml" files. If \c{QUICK_TEST_SOURCE_DIR} is not defined, then the current directory will be scanned when the harness is run. Other *.qml files may appear for auxillary QML components that are used by the test. The \c{-input} command-line option can be set at runtime to run - test cases from a different directory. This may be needed to run + test cases from a different directory. This may be needed to run tests on a target device where the compiled-in directory name refers - to a host. For example: + to a host. For example: \code tst_example -input /mnt/SDCard/qmltests diff --git a/src/quick/doc/src/appdevguide/usecases/animations.qdoc b/src/quick/doc/src/appdevguide/usecases/animations.qdoc index b237849caf..3249a632f5 100644 --- a/src/quick/doc/src/appdevguide/usecases/animations.qdoc +++ b/src/quick/doc/src/appdevguide/usecases/animations.qdoc @@ -29,7 +29,7 @@ \title Usecase - Animations In QML \brief Example of how to include animations in QML applications -QtQuick provides the ability to animate properties. Animating properties allows property values to move through +\l {Qt Quick} provides the ability to animate properties. Animating properties allows property values to move through intermediate values instead of immediately changing to the target value. To animate the position of an item, you can animate the properties that controle the item's position, x and y for example, so that the item's position changes each frame on the way to the target position. diff --git a/src/quick/doc/src/appdevguide/usecases/styling.qdoc b/src/quick/doc/src/appdevguide/usecases/styling.qdoc index 68b8d0302c..f8c7a94d30 100644 --- a/src/quick/doc/src/appdevguide/usecases/styling.qdoc +++ b/src/quick/doc/src/appdevguide/usecases/styling.qdoc @@ -29,8 +29,8 @@ \title Use Case - Style And Theme Support \brief Example of how to style user interface components in QML -The types provided in the QtQuick module are not complete user interface components on their own. A common use case is to -develop a set of custom styled user interface components out of the types in the QtQuick module. This is easily +The types provided in the \l {Qt Quick} module are not complete user interface components on their own. A common use case is to +develop a set of custom styled user interface components out of the types in the \l {Qt Quick} module. This is easily accomplished by creating your own reusable components. With the reusable components approach, you define your own type with the appearance you want to have in your diff --git a/src/quick/doc/src/appdevguide/usecases/text.qdoc b/src/quick/doc/src/appdevguide/usecases/text.qdoc index d0b8901170..7b8e21eb5b 100644 --- a/src/quick/doc/src/appdevguide/usecases/text.qdoc +++ b/src/quick/doc/src/appdevguide/usecases/text.qdoc @@ -28,8 +28,8 @@ \page qtquick-usecase-text.html \title Use Case - Displaying Text In QML \brief Example of how to display text in QML -To display text the Text type is provided by the QtQuick module. For related uses, the \l{TextInput} and -\l{TextEdit} types provide editable text controls. For full HTML markup, see the \c{QtWebkit} module. +To display text the Text type is provided by the \l {Qt Quick} module. For related uses, the \l{TextInput} and +\l{TextEdit} types provide editable text controls. For full HTML markup, see the \l {Qt WebKit} module. \section1 Displaying and Formatting Text diff --git a/src/quick/doc/src/appdevguide/usecases/userinput.qdoc b/src/quick/doc/src/appdevguide/usecases/userinput.qdoc index 1e20f9d275..7e93a263f1 100644 --- a/src/quick/doc/src/appdevguide/usecases/userinput.qdoc +++ b/src/quick/doc/src/appdevguide/usecases/userinput.qdoc @@ -31,14 +31,14 @@ \section1 Supported Types of User Input -The \l QtQuick module provides support for the most common types of user input, +The \l {Qt Quick} module provides support for the most common types of user input, including mouse and touch events, text input and key-press events. Other modules provide support for other types of user input (for example, the -\l QtSensors module provides support for shake-gestures in QML applications). +\l {Qt Sensors} module provides support for shake-gestures in QML applications). This article covers how to handle basic user input; for further information -about motion-gesture support, please see the \l QtSensors documentation. For -information about audio-visual input, please see the \l QtMultimedia documentation. +about motion-gesture support, please see the \l {Qt Sensors} documentation. For +information about audio-visual input, please see the \l {Qt Multimedia} documentation. \section2 Mouse and Touch Events @@ -65,7 +65,7 @@ to true on a single \l Item and do all your key handling there. \snippet qml/usecases/userinput-keys.qml 0 -For text input the \l QtQuick module provides several built-in types. +For text input the \l {Qt Quick} module provides several built-in types. In particular, the \l TextInput and \l TextEdit types allow for single-line entry and multi-line editing respectively. diff --git a/src/quick/doc/src/appdevguide/usecases/visual.qdoc b/src/quick/doc/src/appdevguide/usecases/visual.qdoc index a022b185fe..fc7b96cadc 100644 --- a/src/quick/doc/src/appdevguide/usecases/visual.qdoc +++ b/src/quick/doc/src/appdevguide/usecases/visual.qdoc @@ -31,7 +31,7 @@ \section1 The Rectangle Type -For the most basic of visuals, QtQuick provides a \l Rectangle type to draw rectangles. These rectangles can be colored with a +For the most basic of visuals, \l {Qt Quick} provides a \l Rectangle type to draw rectangles. These rectangles can be colored with a color or a vertical gradient. The \l Rectangle type can also draw borders on the rectangle. For drawing custom shapes beyond rectangles, see the \l Canvas type or display @@ -42,7 +42,7 @@ a pre-rendered image using the \l Image type. \section1 The Image Type -QtQuick provides an \l Image type which may be used to display images. The +\l {Qt Quick} provides an \l Image type which may be used to display images. The \l Image type has a \l source property whose value can be a remote or local URL, or the URL of an image file embedded in a compiled resource file. @@ -54,11 +54,11 @@ borders. \l AnimatedImage plays animated .gif and .mng images. \l AnimatedSprite and \l SpriteSequence play animations comprised of multiple frames stored adjacently in a non animated image format. -For displaying video files and camera data, see the \l QtMultimedia module. +For displaying video files and camera data, see the \l {Qt Multimedia} module. \section1 Shared Visual Properties -All visual items provided by the QtQuick are based on the Item type, which provides a common set of attributes for +All visual items provided by \l {Qt Quick} are based on the Item type, which provides a common set of attributes for visual items, including opacity and transform attributes. \section2 Opacity and Visibility diff --git a/src/quick/doc/src/concepts/convenience/topic.qdoc b/src/quick/doc/src/concepts/convenience/topic.qdoc index 113b4952a6..1a6feeaa61 100644 --- a/src/quick/doc/src/concepts/convenience/topic.qdoc +++ b/src/quick/doc/src/concepts/convenience/topic.qdoc @@ -66,7 +66,7 @@ required (or when it becomes available). \section1 Dynamic Signal Connections QML supports dynamic signal connections through a signal's \c{connect()} -method. The QtQuick module provides the convenience \l Connections type which +method. The \l {Qt Quick} module provides the convenience \l Connections type which allows setting up a signal connection involving an object which isn't part of the static object hierarchy. It also allows the connection to be dynamically retargeted at runtime, which allows an application to process different signal diff --git a/src/quick/doc/src/concepts/effects/sprites.qdoc b/src/quick/doc/src/concepts/effects/sprites.qdoc index 7ee98a533b..3a82f1963b 100644 --- a/src/quick/doc/src/concepts/effects/sprites.qdoc +++ b/src/quick/doc/src/concepts/effects/sprites.qdoc @@ -36,7 +36,7 @@ \section1 Sprite Engine -The QtQuick sprite engine is a stochastic state machine combined with the ability +The \l {Qt Quick} sprite engine is a stochastic state machine combined with the ability to chop up images containing multiple frames of an animation. \section2 State Machine diff --git a/src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc b/src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc index 7b8d66f2a6..7310d25929 100644 --- a/src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc +++ b/src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc @@ -28,7 +28,7 @@ /*! \page qtquick-modelviewsdata-cppmodels.html \title Using C++ Models with Qt Quick Views -\brief using QtQuick views with models defined in C++ +\brief using Qt Quick views with models defined in C++ \section1 Data Provided In A Custom C++ Model diff --git a/src/quick/doc/src/examples.qdoc b/src/quick/doc/src/examples.qdoc index 6db53082fa..8d3bc30624 100644 --- a/src/quick/doc/src/examples.qdoc +++ b/src/quick/doc/src/examples.qdoc @@ -130,7 +130,7 @@ code using the \l{Qt QML} module. \li \l{external: Qt Mobility QML Plugins}{QML Plugins} \li \l{external: Qt Quick Components for Symbian}{Symbian Components} \li MeeGo Components - \li \l{QtWebKit QML Module} + \li \l{Qt WebKit QML Types} \endlist \enddiv \div {class="threecolumn_piece"} diff --git a/src/quick/doc/src/qmltypereference.qdoc b/src/quick/doc/src/qmltypereference.qdoc index 14f0151a3b..43d6b952cb 100644 --- a/src/quick/doc/src/qmltypereference.qdoc +++ b/src/quick/doc/src/qmltypereference.qdoc @@ -36,19 +36,19 @@ interfaces and applications with QML. This page lists every QML type provided by this module, organized according to category and purpose. -\section1 Importing QtQuick +\section1 Importing \c QtQuick -The types provided by the QtQuick module are only available in a QML document +The types provided by the \l {Qt Quick} module are only available in a QML document if that document imports the \c QtQuick namespace. -The current version of the QtQuick module is version 2.0, and thus it may be +The current version of the \c QtQuick module is version 2.0, and thus it may be imported via the following statement: \qml import QtQuick 2.0 \endqml -See the QtQuick module documentation for more +See the \l {Qt Quick} module documentation for more information about the concepts which are central to \c QtQuick. \section2 Submodules @@ -72,12 +72,12 @@ There are a number of basic types that are \l{qtqml-typesystem-basictypes.html#basic-types-provided-by-the-qml-language} {supported by default in the QML language}. -In addition, the QtQuick module provides the following basic types: +In addition, the \c QtQuick module provides the following basic types: \annotatedlist qtquickbasictypes \section1 Object Types -All of the object types provided by QtQuick are based on the \l{Item} type, +All of the object types provided by \c QtQuick are based on the \l{Item} type, which itself derives from \l{QML::QtObject}. \l{qtqml-typereference-topic.html#object-types} {QML object types} provided by the Qt QML module (such as \l{QML::QtObject} and \l{QML::Component}) are also available when @@ -259,7 +259,7 @@ Data Storage \li \l {ShaderEffect} - Allows GLSL shaders to be used as graphical effects \li \l {ShaderEffectSource} - Usable as a texture in ShaderEffect \li \l {GridMesh} - Generates a grid mesh of vertices for use by ShaderEffect -\li The \l{QtQuick.Particles 2} module provides a set of Particle System types for QtQuick 2 +\li The \l{QtQuick.Particles 2} module provides a set of Particle System types for Qt Quick 2 \endlist \section2 Convenience Types @@ -286,14 +286,14 @@ Data Storage /*! \qmlmodule QtQuick 2 -\brief The QtQuick 2 module provides graphical primitives for use in QML. +\brief The \c {QtQuick 2} module provides graphical primitives for use in QML. -The QtQuick 2 module provides graphical primitive types. They can be used with the following import +The \c {QtQuick 2} module provides graphical primitive types. They can be used with the following import \code import QtQuick 2.1 \endcode -For a more detailed listing of types in the \c QtQuick 2 import, see the \l{Qt Quick QML Types} page. +For a more detailed listing of types in the \c {QtQuick 2} import, see the \l{Qt Quick QML Types} page. For more details about the module itself, see the \l{Qt Quick} module page. */ diff --git a/src/quick/doc/src/qtquick.qdoc b/src/quick/doc/src/qtquick.qdoc index c570da531c..9fba663a1c 100644 --- a/src/quick/doc/src/qtquick.qdoc +++ b/src/quick/doc/src/qtquick.qdoc @@ -38,11 +38,9 @@ provides a visual canvas and includes types for creating and animating visual components, receiving user input, creating data models and views and delayed object instantiation. -The Qt Quick module provides both the \c QtQuick QML module, which supplies -\l{Qt Quick QML Types}{a set of QML types} for creating user -interfaces with the QML language, and the \c QtQuick C++ module, which supplies -\l{Qt Quick C++ Classes}{a set of C++ APIs} for integrating with user interfaces and -applications built with QML and the \c QtQuick QML module. +The Qt Quick module provides both a \l{Qt Quick QML Types}{QML API} which supplies +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} diff --git a/src/quick/doc/src/whatsnew.qdoc b/src/quick/doc/src/whatsnew.qdoc index 7651fceaaa..baa0312aa4 100644 --- a/src/quick/doc/src/whatsnew.qdoc +++ b/src/quick/doc/src/whatsnew.qdoc @@ -29,13 +29,13 @@ \title Qt Quick Release Notes \page qtquick-releasenotes.html -\section1 Qt 5.0 - QtQuick C++ Module +\section1 Qt Quick in Qt 5 -The QtQuick C++ module is new in Qt 5. It provides the visual canvas and scenegraph back-end -as well as the QtQuick QML module for QML application development. +The \l {Qt Quick} module is new in Qt 5. It provides the visual canvas and scenegraph back-end +as well as the \c QtQuick QML module for QML application development. -As of Qt 5, the QtQuick module is based on an OpenGL scenegraph. Many of the classes in -the QtQuick module have been ported from the \c QtDeclarative module from Qt 4.8 to use +As of Qt 5, the \l {Qt Quick} module is based on an OpenGL scenegraph. Many of the classes in +the \l {Qt Quick} module have been ported from the \l {Qt Quick 1}{QtDeclarative} module from Qt 4.8 to use the scenegraph architecture; these classes have been renamed to use a \c QQuick* prefix. (See the \l {Porting QML Applications to Qt 5} for porting information.) @@ -76,10 +76,10 @@ Custom rendering can be performed on the scenegraph using the following new clas \section1 Qt 5.0 - QtQuick QML Module -The QtQuick 2.0 QML module is a major update. +The \c {QtQuick 2.0} QML module is a major update. -Below are the additions in QtQuick 2.0. For a list of behavioral changes which may affect -applications ported from QtQuick 1.x, see the \l {Porting QML Applications to Qt 5}. +Below are the additions in \c {QtQuick 2.0}. For a list of behavioral changes which may affect +applications ported from \c {QtQuick 1.x}, see the \l {Porting QML Applications to Qt 5}. \section2 Visual types, Graphical Effects and Sprites @@ -344,11 +344,11 @@ the window loses focus. \section2 Property types Support for various math and geometry-related value types, including QVector2D, QVector3D, QVector4D, -QMatrix4x4 and QQuaternion, as well as QColor and QFont, are now provided by QtQuick. Properties of +QMatrix4x4 and QQuaternion, as well as QColor and QFont, are now provided by \l {Qt Quick}. Properties of these types can be declared in QML documents via the property syntax where the type name is \c vector2d, \c vector3d, \c vector4d, \c matrix4x4, \c quaternion, \c color and \c font respectively. -QtQuick also provides implementation for the various value type factory or utility functions of the +\l {Qt Quick} also provides implementation for the various value type factory or utility functions of the \c Qt object which return or operate on values of the above types. The functions are: \table \header @@ -385,8 +385,8 @@ QtQuick also provides implementation for the various value type factory or utili \endtable The \c Qt.rgba(), \c Qt.hsla(), \c Qt.tint(), \c Qt.lighter(), \c Qt.darker() -and \c Qt.fontFamilies() functions already existed in \c QtDeclarative prior -to QtQuick 2.0; the other functions are all new in QtQuick 2.0. +and \c Qt.fontFamilies() functions already existed in \l {Qt Quick 1}{QtDeclarative} prior +to \l {Qt Quick}{Qt Quick 2}; the other functions are all new in \l {Qt Quick}{Qt Quick 2}. \section1 Qt 5.0 - Additional QML Modules @@ -405,7 +405,7 @@ documentation for comprehensive details. \section2 QtQuick.XmlListModel -This new module contains XmlListModel and associated types, which were previously in the QtQuick +This new module contains XmlListModel and associated types, which were previously in the \c QtQuick module. See the \l{QtQuick.XmlListModel 2}{QtQuick.XmlListModel} documentation for details. \section2 QtQuick.LocalStorage diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp index 9d9ddd6ef0..0c58b9b800 100644 --- a/src/quick/items/context2d/qquickcanvasitem.cpp +++ b/src/quick/items/context2d/qquickcanvasitem.cpp @@ -171,7 +171,6 @@ public: uint hasTileSize :1; uint hasCanvasWindow :1; uint available :1; - uint contextInitialized :1; QQuickCanvasItem::RenderTarget renderTarget; QQuickCanvasItem::RenderStrategy renderStrategy; QString contextType; @@ -189,7 +188,6 @@ QQuickCanvasItemPrivate::QQuickCanvasItemPrivate() , hasTileSize(false) , hasCanvasWindow(false) , available(false) - , contextInitialized(false) , renderTarget(QQuickCanvasItem::Image) , renderStrategy(QQuickCanvasItem::Cooperative) { @@ -339,7 +337,7 @@ void QQuickCanvasItem::setContextType(const QString &contextType) if (contextType.compare(d->contextType, Qt::CaseInsensitive) == 0) return; - if (d->contextInitialized) { + if (d->context) { qmlInfo(this) << "Canvas already initialized with a different context type"; return; } @@ -364,7 +362,7 @@ void QQuickCanvasItem::setContextType(const QString &contextType) QQmlV8Handle QQuickCanvasItem::context() const { Q_D(const QQuickCanvasItem); - if (d->contextInitialized) + if (d->context) return QQmlV8Handle::fromHandle(d->context->v8value()); return QQmlV8Handle::fromHandle(v8::Null()); @@ -398,7 +396,7 @@ void QQuickCanvasItem::setCanvasSize(const QSizeF & size) d->canvasSize = size; emit canvasSizeChanged(); - if (d->contextInitialized) + if (d->context) polish(); } } @@ -433,7 +431,7 @@ void QQuickCanvasItem::setTileSize(const QSize & size) emit tileSizeChanged(); - if (d->contextInitialized) + if (d->context) polish(); } } @@ -466,7 +464,7 @@ void QQuickCanvasItem::setCanvasWindow(const QRectF& rect) d->hasCanvasWindow = true; emit canvasWindowChanged(); - if (d->contextInitialized) + if (d->context) polish(); } } @@ -498,7 +496,7 @@ void QQuickCanvasItem::setRenderTarget(QQuickCanvasItem::RenderTarget target) { Q_D(QQuickCanvasItem); if (d->renderTarget != target) { - if (d->contextInitialized) { + if (d->context) { qmlInfo(this) << "Canvas:renderTarget not changeble once context is active."; return; } @@ -542,7 +540,7 @@ void QQuickCanvasItem::setRenderStrategy(QQuickCanvasItem::RenderStrategy strate { Q_D(QQuickCanvasItem); if (d->renderStrategy != strategy) { - if (d->contextInitialized) { + if (d->context) { qmlInfo(this) << "Canvas:renderStrategy not changeable once context is active."; return; } @@ -647,7 +645,7 @@ void QQuickCanvasItem::updatePolish() Q_D(QQuickCanvasItem); - if (d->contextInitialized) + if (d->context) d->context->prepare(d->canvasSize.toSize(), d->tileSize, d->canvasWindow.toRect(), d->dirtyRect.toRect(), d->smooth, d->antialiasing); if (d->animationCallbacks.size() > 0 && isVisible()) { @@ -673,7 +671,7 @@ void QQuickCanvasItem::updatePolish() } } - if (d->contextInitialized) { + if (d->context) { if (d->renderStrategy == QQuickCanvasItem::Cooperative) update(); else @@ -685,8 +683,10 @@ QSGNode *QQuickCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData { Q_D(QQuickCanvasItem); - if (!d->contextInitialized) + if (!d->context) { + delete oldNode; return 0; + } QSGSimpleTextureNode *node = static_cast<QSGSimpleTextureNode*>(oldNode); if (!node) @@ -701,6 +701,7 @@ QSGNode *QQuickCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData d->context->flush(); node->setTexture(d->context->texture()); + node->markDirty(QSGNode::DirtyMaterial); node->setRect(QRectF(QPoint(0, 0), d->canvasWindow.size())); return node; } @@ -760,7 +761,7 @@ void QQuickCanvasItem::getContext(QQmlV8Function *args) /*! \qmlmethod long QtQuick2::Canvas::requestAnimationFrame(callback) - This function schedules callback to be invoked before composing the QtQuick + This function schedules callback to be invoked before composing the Qt Quick scene. */ @@ -967,7 +968,7 @@ bool QQuickCanvasItem::isImageLoaded(const QUrl& url) const QImage QQuickCanvasItem::toImage(const QRectF& rect) const { Q_D(const QQuickCanvasItem); - if (d->contextInitialized) { + if (d->context) { if (rect.isEmpty()) return d->context->toImage(canvasWindow()); else @@ -1023,7 +1024,7 @@ void QQuickCanvasItem::delayedCreate() { Q_D(QQuickCanvasItem); - if (!d->contextInitialized && !d->contextType.isNull()) + if (!d->context && !d->contextType.isNull()) createContext(d->contextType); requestPaint(); @@ -1052,7 +1053,6 @@ void QQuickCanvasItem::initializeContext(QQuickCanvasContext *context, const QVa d->context = context; d->context->init(this, args); d->context->setV8Engine(QQmlEnginePrivate::getV8Engine(qmlEngine(this))); - d->contextInitialized = true; connect(d->context, SIGNAL(textureChanged()), SLOT(update())); connect(d->context, SIGNAL(textureChanged()), SIGNAL(painted())); emit contextChanged(); diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index 2859388e0b..b366775c03 100644 --- a/src/quick/items/context2d/qquickcontext2d.cpp +++ b/src/quick/items/context2d/qquickcontext2d.cpp @@ -282,7 +282,7 @@ QImage qt_image_convolute_filter(const QImage& src, const QVector<qreal>& weight for (int cx=0; cx<sides; cx++) { int scy = sy + cy - half; int scx = sx + cx - half; - if (scy >= 0 && scy < w && scx >= 0 && scx < h) { + if (scy >= 0 && scy < h && scx >= 0 && scx < w) { const QRgb *sr = (const QRgb*)(src.constScanLine(scy)); const unsigned char* sRgb = ((const unsigned char*)&sr[scx]); qreal wt = radius ? weights[0] : weights[cy*sides+cx]; diff --git a/src/quick/items/qquickaccessibleattached.cpp b/src/quick/items/qquickaccessibleattached.cpp index 0a0fac307c..2025db4fc8 100644 --- a/src/quick/items/qquickaccessibleattached.cpp +++ b/src/quick/items/qquickaccessibleattached.cpp @@ -156,6 +156,9 @@ QQuickAccessibleAttached::QQuickAccessibleAttached(QObject *parent) if (!parent->property("value").isNull()) { connect(parent, SIGNAL(valueChanged()), this, SLOT(valueChanged())); } + if (!parent->property("cursorPosition").isNull()) { + connect(parent, SIGNAL(cursorPositionChanged()), this, SLOT(cursorPositionChanged())); + } } QQuickAccessibleAttached::~QQuickAccessibleAttached() diff --git a/src/quick/items/qquickaccessibleattached_p.h b/src/quick/items/qquickaccessibleattached_p.h index 2124356a70..131b379a07 100644 --- a/src/quick/items/qquickaccessibleattached_p.h +++ b/src/quick/items/qquickaccessibleattached_p.h @@ -142,6 +142,10 @@ public Q_SLOTS: QAccessibleValueChangeEvent ev(parent(), parent()->property("value")); QAccessible::updateAccessibility(&ev); } + void cursorPositionChanged() { + QAccessibleTextCursorEvent ev(parent(), parent()->property("cursorPosition").toInt()); + QAccessible::updateAccessibility(&ev); + } Q_SIGNALS: void roleChanged(); diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h index 469ae9d0e4..6f1b152ad3 100644 --- a/src/quick/items/qquickevents_p_p.h +++ b/src/quick/items/qquickevents_p_p.h @@ -93,7 +93,7 @@ private: QKeyEvent event; }; -// used in QtLocation +// used in Qt Location class Q_QUICK_PRIVATE_EXPORT QQuickMouseEvent : public QObject { Q_OBJECT diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h index 513a26e747..0186029fa0 100644 --- a/src/quick/items/qquickflickable_p_p.h +++ b/src/quick/items/qquickflickable_p_p.h @@ -101,7 +101,7 @@ public: AxisData(QQuickFlickablePrivate *fp, void (QQuickFlickablePrivate::*func)(qreal)) : move(fp, func) , transitionToBounds(0) - , viewSize(-1), startMargin(0), endMargin(0) + , viewSize(-1), lastPos(0), startMargin(0), endMargin(0) , origin(0) , transitionTo(0) , continuousFlickVelocity(0), velocityTime(), vTime(0) diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp index e40d21b498..f4e34da318 100644 --- a/src/quick/items/qquickgridview.cpp +++ b/src/quick/items/qquickgridview.cpp @@ -2564,6 +2564,22 @@ bool QQuickGridViewPrivate::needsRefillForAddedOrRemovedIndex(int modelIndex) co \b Note: methods should only be called after the Component has completed. */ + +/*! + \qmlmethod QtQuick2::GridView::forceLayout() + + Responding to changes in the model is usually batched to happen only once + per frame. This means that inside script blocks it is possible for the + underlying model to have changed, but the GridView has not caught up yet. + + This method forces the GridView to immediately respond to any outstanding + changes in the model. + + \since 5.1 + + \b Note: methods should only be called after the Component has completed. +*/ + QQuickGridViewAttached *QQuickGridView::qmlAttachedProperties(QObject *obj) { return new QQuickGridViewAttached(obj); diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 59ab56dc66..111e74eeff 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -1570,7 +1570,7 @@ void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus) /*! \class QQuickItem - \brief The QQuickItem class provides the most basic of all visual items in QtQuick. + \brief The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}. \inmodule QtQuick All visual items in Qt Quick inherit from QQuickItem. Although a QQuickItem @@ -2044,6 +2044,18 @@ QQuickItem::~QQuickItem() */ bool QQuickItemPrivate::focusNextPrev(QQuickItem *item, bool forward) { + QQuickItem *next = QQuickItemPrivate::nextPrevItemInTabFocusChain(item, forward); + + if (next == item) + return false; + + next->forceActiveFocus(forward ? Qt::TabFocusReason : Qt::BacktabFocusReason); + + return true; +} + +QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, bool forward) +{ Q_ASSERT(item); Q_ASSERT(item->activeFocusOnTab()); @@ -2111,12 +2123,7 @@ bool QQuickItemPrivate::focusNextPrev(QQuickItem *item, bool forward) from = last; } while (skip || !current->activeFocusOnTab() || !current->isEnabled() || !current->isVisible()); - if (current == item) - return false; - - current->forceActiveFocus(forward ? Qt::TabFocusReason : Qt::BacktabFocusReason); - - return true; + return current; } /*! @@ -2339,13 +2346,16 @@ void QQuickItem::stackAfter(const QQuickItem *sibling) QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged(); } +/*! \fn void QQuickItem::windowChanged(QQuickWindow *window) + This signal is emitted when the item's \a window changes. +*/ + /*! Returns the window in which this item is rendered. - The item does not have a window until it has been assigned into a scene. To - get notification about this, reimplement the itemChange() function and - listen for the ItemSceneChange change. The itemChange() function is called - both when the item is entered into a scene and when it is removed from a scene. + The item does not have a window until it has been assigned into a scene. The + \l windowChanged signal provides a notification both when the item is entered + into a scene and when it is removed from a scene. */ QQuickWindow *QQuickItem::window() const { @@ -3928,6 +3938,28 @@ void QQuickItem::forceActiveFocus(Qt::FocusReason reason) } /*! + \qmlmethod QtQuick2::Item::nextItemInFocusChain(bool forward) + + \since QtQuick 2.1 + + Returns the item in the focus chain which is next to this item. + If \a forward is \c true, or not supplied, it is the next item in + the forwards direction. If \a forward is \c false, it is the next + item in the backwards direction. +*/ +/*! + Returns the item in the focus chain which is next to this item. + If \a forward is \c true, or not supplied, it is the next item in + the forwards direction. If \a forward is \c false, it is the next + item in the backwards direction. +*/ + +QQuickItem *QQuickItem::nextItemInFocusChain(bool forward) +{ + return QQuickItemPrivate::nextPrevItemInTabFocusChain(this, forward); +} + +/*! \qmlmethod QtQuick2::Item::childAt(real x, real y) Returns the first visible child item found at point (\a x, \a y) within @@ -4428,6 +4460,13 @@ void QQuickItemPrivate::deliverDragEvent(QEvent *e) \a value contains extra information relating to the change, when applicable. + + If you re-implement this method in a subclass, be sure to call + \code + QQuickItem::itemChange(change, value); + \endcode + typically at the end of your implementation, to ensure the + \l windowChanged signal will be emitted. */ void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value) { diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h index 5dea86296f..078df2ea84 100644 --- a/src/quick/items/qquickitem.h +++ b/src/quick/items/qquickitem.h @@ -324,6 +324,7 @@ public: Q_INVOKABLE void mapToItem(QQmlV8Function*) const; Q_INVOKABLE void forceActiveFocus(); Q_INVOKABLE void forceActiveFocus(Qt::FocusReason reason); + Q_INVOKABLE QQuickItem *nextItemInFocusChain(bool forward = true); Q_INVOKABLE QQuickItem *childAt(qreal x, qreal y) const; #ifndef QT_NO_IM diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index 4bd9d82c20..3602b578e2 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -485,6 +485,7 @@ public: void itemToParentTransform(QTransform &) const; static bool focusNextPrev(QQuickItem *item, bool forward); + static QQuickItem *nextPrevItemInTabFocusChain(QQuickItem *item, bool forward); qreal x; qreal y; diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp index 741583a95d..f5bcf3596f 100644 --- a/src/quick/items/qquickitemsmodule.cpp +++ b/src/quick/items/qquickitemsmodule.cpp @@ -230,6 +230,9 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor) qmlRegisterType<QQuickItem, 1>(uri, 2, 1,"Item"); qmlRegisterType<QQuickGrid, 1>(uri, 2, 1, "Grid"); + qmlRegisterUncreatableType<QQuickItemView, 1>(uri, 2, 1, "ItemView", QQuickItemView::tr("ItemView is an abstract base class")); + qmlRegisterType<QQuickListView, 1>(uri, 2, 1, "ListView"); + qmlRegisterType<QQuickGridView, 1>(uri, 2, 1, "GridView"); qmlRegisterType<QQuickTextEdit, 1>(uri, 2, 1, "TextEdit"); } diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index 72f892178f..d774091ef5 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -249,7 +249,6 @@ QQuickItemView::~QQuickItemView() QQuickItem *QQuickItemView::currentItem() const { Q_D(const QQuickItemView); - const_cast<QQuickItemViewPrivate*>(d)->applyPendingChanges(); return d->currentItem ? d->currentItem->item : 0; } @@ -379,14 +378,12 @@ int QQuickItemView::count() const Q_D(const QQuickItemView); if (!d->model) return 0; - const_cast<QQuickItemViewPrivate*>(d)->applyPendingChanges(); return d->model->count(); } int QQuickItemView::currentIndex() const { Q_D(const QQuickItemView); - const_cast<QQuickItemViewPrivate*>(d)->applyPendingChanges(); return d->currentIndex; } @@ -496,7 +493,6 @@ QQmlComponent *QQuickItemView::header() const QQuickItem *QQuickItemView::headerItem() const { Q_D(const QQuickItemView); - const_cast<QQuickItemViewPrivate*>(d)->applyPendingChanges(); return d->header ? d->header->item : 0; } @@ -532,7 +528,6 @@ QQmlComponent *QQuickItemView::footer() const QQuickItem *QQuickItemView::footerItem() const { Q_D(const QQuickItemView); - const_cast<QQuickItemViewPrivate*>(d)->applyPendingChanges(); return d->footer ? d->footer->item : 0; } @@ -559,7 +554,6 @@ void QQuickItemView::setFooter(QQmlComponent *footerComponent) QQmlComponent *QQuickItemView::highlight() const { Q_D(const QQuickItemView); - const_cast<QQuickItemViewPrivate*>(d)->applyPendingChanges(); return d->highlightComponent; } @@ -579,7 +573,6 @@ void QQuickItemView::setHighlight(QQmlComponent *highlightComponent) QQuickItem *QQuickItemView::highlightItem() const { Q_D(const QQuickItemView); - const_cast<QQuickItemViewPrivate*>(d)->applyPendingChanges(); return d->highlight ? d->highlight->item : 0; } @@ -965,6 +958,12 @@ QQuickItem *QQuickItemView::itemAt(qreal x, qreal y) const return 0; } +void QQuickItemView::forceLayout() +{ + Q_D(QQuickItemView); + d->applyPendingChanges(); +} + void QQuickItemViewPrivate::applyPendingChanges() { Q_Q(QQuickItemView); @@ -2205,7 +2204,7 @@ FxViewItem *QQuickItemViewPrivate::createItem(int modelIndex, bool asynchronous) if (!delegateValidated) { delegateValidated = true; QObject* delegate = q->delegate(); - qmlInfo(delegate ? delegate : q) << q->tr("Delegate must be of Item type"); + qmlInfo(delegate ? delegate : q) << QQuickItemView::tr("Delegate must be of Item type"); } } inRequest = false; diff --git a/src/quick/items/qquickitemview_p.h b/src/quick/items/qquickitemview_p.h index b0f910680a..d7812bcdad 100644 --- a/src/quick/items/qquickitemview_p.h +++ b/src/quick/items/qquickitemview_p.h @@ -202,6 +202,7 @@ public: Q_INVOKABLE QQuickItem *itemAt(qreal x, qreal y) const; Q_INVOKABLE void positionViewAtBeginning(); Q_INVOKABLE void positionViewAtEnd(); + Q_REVISION(1) Q_INVOKABLE void forceLayout(); virtual void setContentX(qreal pos); virtual void setContentY(qreal pos); diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index 53dc715469..b99fba4e4c 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -3108,6 +3108,21 @@ void QQuickListViewPrivate::translateAndTransitionItemsAfter(int afterModelIndex \b Note: methods should only be called after the Component has completed. */ +/*! + \qmlmethod QtQuick2::ListView::forceLayout() + + Responding to changes in the model is usually batched to happen only once + per frame. This means that inside script blocks it is possible for the + underlying model to have changed, but the ListView has not caught up yet. + + This method forces the ListView to immediately respond to any outstanding + changes in the model. + + \since 5.1 + + \b Note: methods should only be called after the Component has completed. +*/ + QQuickListViewAttached *QQuickListView::qmlAttachedProperties(QObject *obj) { return new QQuickListViewAttached(obj); diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp index 0d14f3e266..e53d402ade 100644 --- a/src/quick/items/qquickloader.cpp +++ b/src/quick/items/qquickloader.cpp @@ -266,7 +266,7 @@ qreal QQuickLoaderPrivate::getImplicitHeight() const \c event.accepted to \c true so that the event is not propagated to the parent \l Rectangle. - Since QtQuick 2.0 Loader can also load non-visual components. + Since \c {QtQuick 2.0}, Loader can also load non-visual components. \section2 Using a Loader within a view delegate @@ -378,7 +378,7 @@ void QQuickLoader::setActive(bool newVal) \qmlproperty url QtQuick2::Loader::source This property holds the URL of the QML component to instantiate. - Since QtQuick 2.0 Loader is able to load any type of object; it + Since \c {QtQuick 2.0}, Loader is able to load any type of object; it is not restricted to Item types. To unload the currently loaded object, set this property to an empty string, @@ -453,7 +453,7 @@ void QQuickLoader::loadFromSource() To unload the currently loaded object, set this property to an empty string or \c undefined. - Since QtQuick 2.0 Loader is able to load any type of object; it + Since \c {QtQuick 2.0}, Loader is able to load any type of object; it is not restricted to Item types. \sa source, progress @@ -909,7 +909,7 @@ void QQuickLoaderPrivate::_q_updateSize(bool loaderGeometryChanged) \qmlproperty object QtQuick2::Loader::item This property holds the top-level object that is currently loaded. - Since QtQuick 2.0 Loader can load any object type. + Since \c {QtQuick 2.0}, Loader can load any object type. */ QObject *QQuickLoader::item() const { diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp index ad0a265035..a8786585da 100644 --- a/src/quick/items/qquickmousearea.cpp +++ b/src/quick/items/qquickmousearea.cpp @@ -773,11 +773,7 @@ void QQuickMouseArea::mouseMoveEvent(QMouseEvent *event) // ### we should skip this if these signals aren't used // ### can GV handle this for us? - const bool isInside = contains(d->lastPos); - if (d->hovered && !isInside) - setHovered(false); - else if (!d->hovered && isInside) - setHovered(true); + setHovered(contains(d->lastPos)); #ifndef QT_NO_DRAGANDDROP if (d->drag && d->drag->target()) { @@ -958,7 +954,8 @@ void QQuickMouseArea::ungrabMouse() emit canceled(); emit pressedChanged(); emit pressedButtonsChanged(); - if (d->hovered) { + + if (d->hovered && !isUnderMouse()) { d->hovered = false; emit hoveredChanged(); } diff --git a/src/quick/items/qquickmousearea_p.h b/src/quick/items/qquickmousearea_p.h index ad15167b10..fa32f32b65 100644 --- a/src/quick/items/qquickmousearea_p.h +++ b/src/quick/items/qquickmousearea_p.h @@ -123,7 +123,7 @@ private: class QQuickMouseAreaPrivate; class QQuickWheelEvent; -// used in QtLocation +// used in Qt Location class Q_QUICK_PRIVATE_EXPORT QQuickMouseArea : public QQuickItem { Q_OBJECT diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index e9aa6985fc..7798641fcd 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -159,7 +159,7 @@ QQuickItem *QQuickPathViewPrivate::getItem(int modelIndex, qreal z, bool async) if (!delegateValidated) { delegateValidated = true; QObject* delegate = q->delegate(); - qmlInfo(delegate ? delegate : q) << q->tr("Delegate must be of Item type"); + qmlInfo(delegate ? delegate : q) << QQuickPathView::tr("Delegate must be of Item type"); } } } else { diff --git a/src/quick/items/qquickpositioners.cpp b/src/quick/items/qquickpositioners.cpp index d8dc0f1856..66f4b44857 100644 --- a/src/quick/items/qquickpositioners.cpp +++ b/src/quick/items/qquickpositioners.cpp @@ -700,8 +700,8 @@ void QQuickPositionerAttached::setIsLastItem(bool isLastItem) cases, these lists will be empty. See the \l ViewTransition documentation for more details and examples on using these transitions. - \note In QtQuick 1, this transition was applied to all items that were part of the - positioner at the time of its creation. From QtQuick 2 onwards, positioners apply the + \note In \l {Qt Quick 1}, this transition was applied to all items that were part of the + positioner at the time of its creation. From \l {Qt Quick}{Qt Quick 2} onwards, positioners apply the \l populate transition to these items instead. \sa add, ViewTransition, {qml/positioners}{Positioners example} @@ -854,8 +854,8 @@ void QQuickColumn::reportConflictingAnchors() cases, these lists will be empty. See the \l ViewTransition documentation for more details and examples on using these transitions. - \note In QtQuick 1, this transition was applied to all items that were part of the - positioner at the time of its creation. From QtQuick 2 onwards, positioners apply the + \note In \l {Qt Quick 1}, this transition was applied to all items that were part of the + positioner at the time of its creation. From \l {Qt Quick}{QtQuick 2} onwards, positioners apply the \l populate transition to these items instead. \sa add, ViewTransition, {qml/positioners}{Positioners example} @@ -1087,8 +1087,8 @@ void QQuickRow::reportConflictingAnchors() cases, these lists will be empty. See the \l ViewTransition documentation for more details and examples on using these transitions. - \note In QtQuick 1, this transition was applied to all items that were part of the - positioner at the time of its creation. From QtQuick 2 onwards, positioners apply the + \note In \l {Qt Quick 1}, this transition was applied to all items that were part of the + positioner at the time of its creation. From \l {Qt Quick}{QtQuick 2} onwards, positioners apply the \l populate transition to these items instead. \sa add, ViewTransition, {qml/positioners}{Positioners example} @@ -1628,8 +1628,8 @@ void QQuickGrid::reportConflictingAnchors() cases, these lists will be empty. See the \l ViewTransition documentation for more details and examples on using these transitions. - \note In QtQuick 1, this transition was applied to all items that were part of the - positioner at the time of its creation. From QtQuick 2 onwards, positioners apply the + \note In \l {Qt Quick 1}, this transition was applied to all items that were part of the + positioner at the time of its creation. From \l {Qt Quick}{QtQuick 2} onwards, positioners apply the \l populate transition to these items instead. \sa add, ViewTransition, {qml/positioners}{Positioners example} diff --git a/src/quick/items/qquickrepeater.cpp b/src/quick/items/qquickrepeater.cpp index bf6d3c495b..62ce78a644 100644 --- a/src/quick/items/qquickrepeater.cpp +++ b/src/quick/items/qquickrepeater.cpp @@ -395,7 +395,7 @@ void QQuickRepeaterPrivate::createItems() if (!delegateValidated) { delegateValidated = true; QObject* delegate = q->delegate(); - qmlInfo(delegate ? delegate : q) << q->tr("Delegate must be of Item type"); + qmlInfo(delegate ? delegate : q) << QQuickRepeater::tr("Delegate must be of Item type"); } } createFrom = ii; diff --git a/src/quick/items/qquickscreen.cpp b/src/quick/items/qquickscreen.cpp index 33a831acad..91638d448e 100644 --- a/src/quick/items/qquickscreen.cpp +++ b/src/quick/items/qquickscreen.cpp @@ -70,7 +70,7 @@ QT_BEGIN_NAMESPACE To use this type, you will need to import the module with the following line: \code - import QtQuick.Window 2.0 + import QtQuick.Window 2.1 \endcode It is a separate import in order to allow you to have a QML environment without access to window system features. @@ -80,6 +80,13 @@ QT_BEGIN_NAMESPACE */ /*! + \qmlattachedproperty String QtQuick.Window2::Screen::name + \readonly + \since Qt 5.1 + + The name of the screen. +*/ +/*! \qmlattachedproperty int QtQuick.Window2::Screen::width \readonly @@ -92,6 +99,43 @@ QT_BEGIN_NAMESPACE This contains the height of the screen in pixels. */ /*! + \qmlattachedproperty int QtQuick.Window2::Screen::desktopAvailableWidth + \readonly + \since Qt 5.1 + + This contains the available width of the collection of screens which make + up the virtual desktop, in pixels, excluding window manager reserved areas + such as task bars and system menus. If you want to position a Window at + the right of the desktop, you can bind to it like this: + + \qml + x: Screen.desktopAvailableWidth - width + \endqml +*/ +/*! + \qmlattachedproperty int QtQuick.Window2::Screen::desktopAvailableHeight + \readonly + \since Qt 5.1 + + This contains the available height of the collection of screens which make + up the virtual desktop, in pixels, excluding window manager reserved areas + such as task bars and system menus. If you want to position a Window at + the bottom of the desktop, you can bind to it like this: + + \qml + y: Screen.desktopAvailableHeight - height + \endqml +*/ +/*! + \qmlattachedproperty real QtQuick.Window2::Screen::logicalPixelDensity + \readonly + \since Qt 5.1 + + The number of logical pixels per millimeter. Logical pixels are the + usual units in QML; on some systems they may be different than physical + pixels. +*/ +/*! \qmlattachedproperty Qt::ScreenOrientation QtQuick.Window2::Screen::primaryOrientation \readonly @@ -147,6 +191,13 @@ QQuickScreenAttached::QQuickScreenAttached(QObject* attachee) } } +QString QQuickScreenAttached::name() const +{ + if (!m_screen) + return QString(); + return m_screen->name(); +} + int QQuickScreenAttached::width() const { if (!m_screen) @@ -161,6 +212,27 @@ int QQuickScreenAttached::height() const return m_screen->size().height(); } +int QQuickScreenAttached::desktopAvailableWidth() const +{ + if (!m_screen) + return 0; + return m_screen->availableVirtualSize().width(); +} + +int QQuickScreenAttached::desktopAvailableHeight() const +{ + if (!m_screen) + return 0; + return m_screen->availableVirtualSize().height(); +} + +qreal QQuickScreenAttached::logicalPixelDensity() const +{ + if (!m_screen) + return 0.0; + return m_screen->logicalDotsPerInch() / 25.4; +} + Qt::ScreenOrientation QQuickScreenAttached::primaryOrientation() const { if (!m_screen) @@ -209,12 +281,14 @@ void QQuickScreenAttached::screenChanged(QScreen *screen) emit widthChanged(); emit heightChanged(); } - if (!oldScreen || screen->orientation() != oldScreen->orientation()) emit orientationChanged(); if (!oldScreen || screen->primaryOrientation() != oldScreen->primaryOrientation()) emit primaryOrientationChanged(); - + if (!oldScreen || screen->availableVirtualGeometry() != oldScreen->availableVirtualGeometry()) + emit desktopGeometryChanged(); + if (!oldScreen || screen->logicalDotsPerInch() != oldScreen->logicalDotsPerInch()) + emit logicalPixelDensityChanged(); connect(screen, SIGNAL(geometryChanged(QRect)), this, SIGNAL(widthChanged())); @@ -224,6 +298,10 @@ void QQuickScreenAttached::screenChanged(QScreen *screen) this, SIGNAL(orientationChanged())); connect(screen, SIGNAL(primaryOrientationChanged(Qt::ScreenOrientation)), this, SIGNAL(primaryOrientationChanged())); + connect(screen, SIGNAL(virtualGeometryChanged(const QRect &)), + this, SIGNAL(desktopGeometryChanged())); + connect(screen, SIGNAL(logicalDotsPerInchChanged(qreal)), + this, SIGNAL(logicalPixelDensityChanged())); } } diff --git a/src/quick/items/qquickscreen_p.h b/src/quick/items/qquickscreen_p.h index 98f38b7154..7ce035a93d 100644 --- a/src/quick/items/qquickscreen_p.h +++ b/src/quick/items/qquickscreen_p.h @@ -58,16 +58,24 @@ class Q_AUTOTEST_EXPORT QQuickScreenAttached : public QObject { Q_OBJECT + Q_PROPERTY(QString name READ name CONSTANT REVISION 1); Q_PROPERTY(int width READ width NOTIFY widthChanged) Q_PROPERTY(int height READ height NOTIFY heightChanged) + Q_PROPERTY(int desktopAvailableWidth READ desktopAvailableWidth NOTIFY desktopGeometryChanged REVISION 1) + Q_PROPERTY(int desktopAvailableHeight READ desktopAvailableHeight NOTIFY desktopGeometryChanged REVISION 1) + Q_PROPERTY(qreal logicalPixelDensity READ logicalPixelDensity NOTIFY logicalPixelDensityChanged REVISION 1) Q_PROPERTY(Qt::ScreenOrientation primaryOrientation READ primaryOrientation NOTIFY primaryOrientationChanged) Q_PROPERTY(Qt::ScreenOrientation orientation READ orientation NOTIFY orientationChanged) public: QQuickScreenAttached(QObject* attachee); + QString name() const; int width() const; int height() const; + int desktopAvailableWidth() const; + int desktopAvailableHeight() const; + qreal logicalPixelDensity() const; Qt::ScreenOrientation primaryOrientation() const; Qt::ScreenOrientation orientation() const; @@ -79,6 +87,8 @@ public: Q_SIGNALS: void widthChanged(); void heightChanged(); + Q_REVISION(1) void desktopGeometryChanged(); + Q_REVISION(1) void logicalPixelDensityChanged(); void primaryOrientationChanged(); void orientationChanged(); diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp index 59b788643a..bd0bb2348e 100644 --- a/src/quick/items/qquickshadereffectsource.cpp +++ b/src/quick/items/qquickshadereffectsource.cpp @@ -468,7 +468,7 @@ QImage QQuickShaderEffectTexture::toImage() const \since QtQuick 2.0 \inherits Item \ingroup qtquick-effects - \brief Renders a QtQuick item into a texture and displays it + \brief Renders a \l {Qt Quick} item into a texture and displays it The ShaderEffectSource type renders \l sourceItem into a texture and displays it in the scene. \l sourceItem is drawn into the texture as though @@ -478,7 +478,7 @@ QImage QQuickShaderEffectTexture::toImage() const ShaderEffectSource can be used as: \list \li a texture source in a \l ShaderEffect. - This allows you to apply custom shader effects to any QtQuick item. + This allows you to apply custom shader effects to any \l {Qt Quick} item. \li a cache for a complex item. The complex item can be rendered once into the texture, which can then be animated freely without the need to render the complex item diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index 9a90b408c3..5fe0b528fa 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -313,7 +313,8 @@ qreal QQuickTextPrivate::getImplicitHeight() const combination with the NativeRendering render type will lend poor and sometimes pixelated results. - On HighDpi "retina" displays this property is ignored and QtRendering is always used. + On HighDpi "retina" displays and mobile and embedded platforms, this property is ignored + and QtRendering is always used. */ QQuickText::RenderType QQuickText::renderType() const { @@ -1334,10 +1335,10 @@ QQuickText::~QQuickText() \snippet qml/text/onLinkActivated.qml 0 The example code will display the text - "The main website is at \l{http://qt.nokia.com}{Nokia Qt DF}." + "See the \l{http://qt-project.org}{Qt Project website}." Clicking on the highlighted link will output - \tt{http://qt.nokia.com link activated} to the console. + \tt{http://qt-project.org link activated} to the console. */ /*! diff --git a/src/quick/items/qquicktextdocument.h b/src/quick/items/qquicktextdocument.h index 25d3bbeaf0..7c22c01d5a 100644 --- a/src/quick/items/qquicktextdocument.h +++ b/src/quick/items/qquicktextdocument.h @@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE The class has to be used from C++ directly, using the property of the \l TextEdit. - Warning: The QTextDocument provided is used internally by QtQuick elements to provide text manipulation primitives. + Warning: The QTextDocument provided is used internally by \l {Qt Quick} elements to provide text manipulation primitives. You are not allowed to perform any modification of the internal state of the QTextDocument. If you do, the element in question may stop functioning or crash. */ diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp index dde3587018..f4934e2400 100644 --- a/src/quick/items/qquicktextedit.cpp +++ b/src/quick/items/qquicktextedit.cpp @@ -380,7 +380,8 @@ void QQuickTextEdit::setTextFormat(TextFormat format) combination with the NativeRendering render type will lend poor and sometimes pixelated results. - On HighDpi "retina" displays this property is ignored and QtRendering is always used. + On HighDpi "retina" displays and mobile and embedded platforms, this property is ignored + and QtRendering is always used. */ QQuickTextEdit::RenderType QQuickTextEdit::renderType() const { @@ -1805,14 +1806,13 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * transformMatrix.translate(nodeOffset.x(), nodeOffset.y()); node->setMatrix(transformMatrix); } - node->m_engine->addTextBlock(d->document, block, basePosition - nodeOffset, d->color, QColor(), selectionStart(), selectionEnd() - 1); sizeCounter += block.length(); if ((it.atEnd() && frames.isEmpty()) || (firstCleanNode && block.next().position() >= firstCleanNode->startPos())) // last node that needed replacing or last block of the last frame break; - if (sizeCounter > nodeBreakingSize) { + if (sizeCounter > nodeBreakingSize || it.atEnd()) { // text block grouping across text frames might not be a good idea, split it. sizeCounter = 0; node->m_engine->addToSceneGraph(node, QQuickText::Normal, QColor()); nodeIterator = d->textNodeMap.insert(nodeIterator, new TextNode(prevBlockStart, node)); @@ -1848,6 +1848,10 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * } } + + // Since we iterate over blocks from different text frames that are potentially not sorted + // we need to ensure that our list of nodes is sorted again: + std::sort(d->textNodeMap.begin(), d->textNodeMap.end(), &comesBefore); } if (d->cursorComponent == 0 && !isReadOnly()) { diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index 0d0d0a17e0..9a311895f6 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -154,7 +154,8 @@ void QQuickTextInput::setText(const QString &s) combination with the NativeRendering render type will lend poor and sometimes pixelated results. - On HighDpi "retina" displays this property is ignored and QtRendering is always used. + On HighDpi "retina" displays and mobile and embedded platforms, this property is ignored + and QtRendering is always used. */ QQuickTextInput::RenderType QQuickTextInput::renderType() const { @@ -1229,10 +1230,11 @@ Qt::InputMethodHints QQuickTextInputPrivate::effectiveInputMethodHints() const Specifies how the text should be displayed in the TextInput. \list \li TextInput.Normal - Displays the text as it is. (Default) - \li TextInput.Password - Displays asterisks instead of characters. + \li TextInput.Password - Displays platform-dependent password mask + characters instead of the actual characters. \li TextInput.NoEcho - Displays nothing. \li TextInput.PasswordEchoOnEdit - Displays characters as they are entered - while editing, otherwise displays asterisks. + while editing, otherwise identical to \c TextInput.Password. \endlist */ QQuickTextInput::EchoMode QQuickTextInput::echoMode() const @@ -1470,7 +1472,7 @@ void QQuickTextInput::keyPressEvent(QKeyEvent* ev) int cursorPosition = d->m_cursor; if (cursorPosition == 0) ignore = ev->key() == (d->layoutDirection() == Qt::LeftToRight ? Qt::Key_Left : Qt::Key_Right); - if (!ignore && cursorPosition == text().length()) + if (!ignore && cursorPosition == d->m_text.length()) ignore = ev->key() == (d->layoutDirection() == Qt::LeftToRight ? Qt::Key_Right : Qt::Key_Left); } if (ignore) { @@ -2199,7 +2201,8 @@ void QQuickTextInput::selectWord() \qmlproperty string QtQuick2::TextInput::passwordCharacter This is the character displayed when echoMode is set to Password or - PasswordEchoOnEdit. By default it is an asterisk. + PasswordEchoOnEdit. By default it is the password character used by + the platform theme. If this property is set to a string with more than one character, the first character is used. If the string is empty, the value diff --git a/src/quick/items/qquicktextinput_p_p.h b/src/quick/items/qquicktextinput_p_p.h index 57eff175a2..11096cfa1d 100644 --- a/src/quick/items/qquicktextinput_p_p.h +++ b/src/quick/items/qquicktextinput_p_p.h @@ -110,7 +110,7 @@ public: , updateType(UpdatePaintNode) , mouseSelectionMode(QQuickTextInput::SelectCharacters) , m_layoutDirection(Qt::LayoutDirectionAuto) - , m_passwordCharacter(QLatin1Char('*')) + , m_passwordCharacter(qApp->styleHints()->passwordMaskCharacter()) , focusOnPress(true) , cursorVisible(false) , cursorPending(false) diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp index 65343cdc52..cc32c40aa3 100644 --- a/src/quick/items/qquickview.cpp +++ b/src/quick/items/qquickview.cpp @@ -494,7 +494,7 @@ void QQuickViewPrivate::setRootObject(QObject *obj) << "loaded has 'import QtQuick 1.0' or 'import Qt 4.7', this error will occur." << endl << endl << "To load files with 'import QtQuick 1.0' or 'import Qt 4.7', use the" << endl - << "QDeclarativeView class in the qtquick1 module." << endl; + << "QDeclarativeView class in the Qt Quick 1 module." << endl; delete obj; root = 0; } diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index abd325e153..a4dff969f4 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -72,6 +72,8 @@ QT_BEGIN_NAMESPACE +extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha); + void QQuickWindowPrivate::updateFocusItemTransform() { Q_Q(QQuickWindow); @@ -815,8 +817,8 @@ void QQuickWindowPrivate::cleanup(QSGNode *n) \ingroup qtquick-visual \brief Creates a new top-level window - The Window object creates a new top-level window for a QtQuick scene. It automatically sets up the - window for use with QtQuick 2.x graphical types. + The Window object creates a new top-level window for a Qt Quick scene. It automatically sets up the + window for use with \c {QtQuick 2.x} graphical types. To use this type, you will need to import the module with the following line: \code @@ -2653,7 +2655,10 @@ QOpenGLFramebufferObject *QQuickWindow::renderTarget() const /*! Grabs the contents of the window and returns it as an image. - This function might not work if the window is not visible. + It is possible to call the grabWindow() function when the window is not + visible. This requires that the window is \l{QWindow::create} {created} + and has a valid size and that no other QQuickWindow instances are rendering + in the same process. \warning Calling this function will cause performance problems. @@ -2662,6 +2667,36 @@ QOpenGLFramebufferObject *QQuickWindow::renderTarget() const QImage QQuickWindow::grabWindow() { Q_D(QQuickWindow); + if (!isVisible()) { + + if (d->context->isReady()) { + qWarning("QQuickWindow::grabWindow: scene graph already in use"); + return QImage(); + } + + if (!handle() || !size().isValid()) { + qWarning("QQuickWindow::grabWindow: window must be created and have a valid size"); + return QImage(); + } + + QOpenGLContext context; + context.setFormat(requestedFormat()); + context.create(); + context.makeCurrent(this); + d->context->initialize(&context); + + d->polishItems(); + d->syncSceneGraph(); + d->renderSceneGraph(size()); + + QImage image = qt_gl_read_framebuffer(size(), false, false); + d->cleanupNodesOnShutdown(); + d->context->invalidate(); + context.doneCurrent(); + + return image; + } + return d->windowManager->grab(this); } diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index 8d36fce481..5d894e5236 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -354,7 +354,11 @@ QSGDistanceFieldGlyphCache *QSGContext::distanceFieldGlyphCache(const QRawFont & */ QSGGlyphNode *QSGContext::createNativeGlyphNode() { +#if defined(QT_OPENGL_ES) && !defined(QT_OPENGL_ES_2_ANGLE) + return createGlyphNode(); +#else return new QSGDefaultGlyphNode; +#endif } /*! diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index 04981b54e7..f71ccea294 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -41,6 +41,7 @@ #include "qsgrenderloop_p.h" #include "qsgthreadedrenderloop_p.h" +#include "qsgwindowsrenderloop_p.h" #include <QtCore/QCoreApplication> #include <QtCore/QTime> @@ -130,15 +131,6 @@ QSGRenderLoop *QSGRenderLoop::instance() s_instance = QSGContext::createWindowManager(); bool bufferQueuing = QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::BufferQueueingOpenGL); -#ifdef Q_OS_WIN - bool fancy = false; // QTBUG-28037 -#else - bool fancy = QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL); -#endif - if (qmlNoThreadedRenderer()) - fancy = false; - else if (qmlForceThreadedRenderer()) - fancy = true; // Enable fixed animation steps... QByteArray fixed = qgetenv("QML_FIXED_ANIMATION_STEP"); @@ -151,9 +143,45 @@ QSGRenderLoop *QSGRenderLoop::instance() QUnifiedTimer::instance(true)->setConsistentTiming(true); if (!s_instance) { - s_instance = fancy - ? (QSGRenderLoop*) new QSGThreadedRenderLoop - : (QSGRenderLoop*) new QSGGuiThreadRenderLoop; + + enum RenderLoopType { + BasicRenderLoop, + ThreadedRenderLoop, + WindowsRenderLoop + }; + + RenderLoopType loopType = BasicRenderLoop; + +#ifdef Q_OS_WIN + loopType = WindowsRenderLoop; +#else + if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL)) + loopType = ThreadedRenderLoop; +#endif + if (qmlNoThreadedRenderer()) + loopType = BasicRenderLoop; + else if (qmlForceThreadedRenderer()) + loopType = ThreadedRenderLoop; + + const QByteArray loopName = qgetenv("QSG_RENDER_LOOP"); + if (loopName == QByteArrayLiteral("windows")) + loopType = WindowsRenderLoop; + else if (loopName == QByteArrayLiteral("basic")) + loopType = BasicRenderLoop; + else if (loopName == QByteArrayLiteral("threaded")) + loopType = ThreadedRenderLoop; + + switch (loopType) { + case ThreadedRenderLoop: + s_instance = new QSGThreadedRenderLoop(); + break; + case WindowsRenderLoop: + s_instance = new QSGWindowsRenderLoop(); + break; + default: + s_instance = new QSGGuiThreadRenderLoop(); + break; + } } } return s_instance; diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index 4cca87e990..de1e2517db 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -515,7 +515,6 @@ void QSGRenderThread::sync() mutex.lock(); Q_ASSERT_X(guiIsLocked, "QSGRenderThread::sync()", "sync triggered on bad terms as gui is not already locked..."); - pendingUpdate = 0; for (int i=0; i<m_windows.size(); ++i) { Window &w = const_cast<Window &>(m_windows.at(i)); @@ -557,8 +556,10 @@ void QSGRenderThread::syncAndRender() syncResultedInChanges = false; bool repaintRequested = pendingUpdate & RepaintRequest; + bool syncRequested = pendingUpdate & SyncRequest; + pendingUpdate = 0; - if (pendingUpdate & SyncRequest) { + if (syncRequested) { RLDEBUG(" Render: - update pending, doing sync"); sync(); } diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp new file mode 100644 index 0000000000..3e21af6ac0 --- /dev/null +++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp @@ -0,0 +1,435 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgwindowsrenderloop_p.h" + +#include <QtCore/QCoreApplication> + +#include <QtGui/QScreen> +#include <QtGui/QGuiApplication> + +#include <QtQuick/private/qsgcontext_p.h> +#include <QtQuick/private/qquickwindow_p.h> + +#include <QtQuick/QQuickWindow> + +QT_BEGIN_NAMESPACE + +extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha); + +// #define QSG_RENDER_LOOP_DEBUG + +#ifdef QSG_RENDER_LOOP_DEBUG +static QElapsedTimer qsg_debug_timer; +# define RLDEBUG(x) printf("(%6d) %s : %4d - %s\n", (int) qsg_debug_timer.elapsed(), __FILE__, __LINE__, x) +#else +# define RLDEBUG(x) +#endif + +#ifndef QSG_NO_RENDER_TIMING +static bool qsg_render_timing = !qgetenv("QSG_RENDER_TIMING").isEmpty(); +static QElapsedTimer qsg_render_timer; +#define QSG_RENDER_TIMING_SAMPLE(sampleName) int sampleName = 0; if (qsg_render_timing) sampleName = qsg_render_timer.elapsed() +#else +#define QSG_RENDER_TIMING_SAMPLE(sampleName) +#endif + + +QSGWindowsRenderLoop::QSGWindowsRenderLoop() + : m_gl(0) + , m_sg(QSGContext::createDefaultContext()) + , m_updateTimer(0) + , m_animationTimer(0) +{ +#ifdef QSG_RENDER_LOOP_DEBUG + qsg_debug_timer.start(); +#endif + + m_animationDriver = m_sg->createAnimationDriver(m_sg); + m_animationDriver->install(); + + connect(m_animationDriver, SIGNAL(started()), this, SLOT(started())); + connect(m_animationDriver, SIGNAL(stopped()), this, SLOT(stopped())); + + m_vsyncDelta = 1000 / QGuiApplication::primaryScreen()->refreshRate(); + if (m_vsyncDelta <= 0) + m_vsyncDelta = 16; + + RLDEBUG("Windows Render Loop created"); + +#ifndef QSG_NO_RENDER_TIMIMG + qsg_render_timer.start(); +#endif +} + +QSGWindowsRenderLoop::WindowData *QSGWindowsRenderLoop::windowData(QQuickWindow *window) +{ + for (int i=0; i<m_windows.size(); ++i) { + WindowData &wd = m_windows[i]; + if (wd.window == window) + return &wd; + } + return 0; +} + +void QSGWindowsRenderLoop::maybePostUpdateTimer() +{ + if (!m_updateTimer) { + RLDEBUG(" - posting event"); + m_updateTimer = startTimer(m_vsyncDelta / 3); + } +} + +/* + * If no windows are showing, start ticking animations using a timer, + * otherwise, start rendering + */ +void QSGWindowsRenderLoop::started() +{ + RLDEBUG("Animations started..."); + if (!anyoneShowing()) { + if (m_animationTimer == 0) { + RLDEBUG(" - starting non-visual animation timer"); + m_animationTimer = startTimer(m_vsyncDelta); + } + } else { + maybePostUpdateTimer(); + } +} + +void QSGWindowsRenderLoop::stopped() +{ + RLDEBUG("Animations stopped..."); + if (m_animationTimer) { + RLDEBUG(" - stopping non-visual animation timer"); + killTimer(m_animationTimer); + m_animationTimer = 0; + } +} + +void QSGWindowsRenderLoop::show(QQuickWindow *window) +{ + RLDEBUG("show"); + if (windowData(window) != 0) + return; + + // This happens before the platform window is shown, but after + // it is created. Creating the GL context takes a lot of time + // (hundreds of milliseconds) and will prevent us from rendering + // the first frame in time for the initial show on screen. + // By preparing the GL context here, it is feasible (if the app + // is quick enough) to have a perfect first frame. + if (!m_gl) { + QSG_RENDER_TIMING_SAMPLE(time_start); + + RLDEBUG(" - creating GL context"); + m_gl = new QOpenGLContext(); + m_gl->setFormat(window->requestedFormat()); + m_gl->create(); + QSG_RENDER_TIMING_SAMPLE(time_created); + RLDEBUG(" - making current"); + m_gl->makeCurrent(window); + RLDEBUG(" - initializing SG"); + QSG_RENDER_TIMING_SAMPLE(time_current); + m_sg->initialize(m_gl); + +#ifndef QSG_NO_RENDER_TIMING + if (qsg_render_timing) { + qDebug("WindowsRenderLoop: GL=%d ms, makeCurrent=%d ms, SG=%d ms", + int(time_created - time_start), + int(time_current - time_created), + int(qsg_render_timer.elapsed() - time_current)); + } +#endif + + } + + WindowData data; + data.window = window; + data.pendingUpdate = false; + m_windows << data; + + RLDEBUG(" - done with show"); +} + +void QSGWindowsRenderLoop::hide(QQuickWindow *window) +{ + RLDEBUG("hide"); + + for (int i=0; i<m_windows.size(); ++i) { + if (m_windows.at(i).window == window) { + m_windows.removeAt(i); + break; + } + } + + // The expose event is queued while hide is sent synchronously, so + // the value might not be updated yet. (plus that the windows plugin + // sends exposed=true when it goes to hidden, so it is doubly broken) + // The check is made here, after the removal from m_windows, so + // anyoneShowing will report the right value. + if (window->isExposed()) + handleObscurity(); + + QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window); + cd->cleanupNodesOnShutdown(); + + // If this is the last tracked window, check for persistent SG and GL and + // potentially clean up. + if (m_windows.size() == 0) { + if (!cd->persistentSceneGraph) { + m_sg->invalidate(); + if (!cd->persistentGLContext) { + delete m_gl; + m_gl = 0; + } + } + } +} + +void QSGWindowsRenderLoop::windowDestroyed(QQuickWindow *window) +{ + RLDEBUG("windowDestroyed"); + hide(window); + + // If this is the last tracked window, clean up SG and GL. + if (m_windows.size() == 0) { + m_sg->invalidate(); + delete m_gl; + m_gl = 0; + } +} + +bool QSGWindowsRenderLoop::anyoneShowing() const +{ + foreach (const WindowData &wd, m_windows) + if (wd.window->isExposed() && wd.window->size().isValid()) + return true; + return false; +} + +void QSGWindowsRenderLoop::exposureChanged(QQuickWindow *window) +{ + + if (windowData(window) == 0) + return; + + if (window->isExposed()) { + + // Stop non-visual animation timer as we now have a window rendering + if (m_animationTimer && anyoneShowing()) { + RLDEBUG(" - stopping non-visual animation timer"); + killTimer(m_animationTimer); + m_animationTimer = 0; + } + + RLDEBUG("exposureChanged - exposed"); + WindowData *wd = windowData(window); + wd->pendingUpdate = true; + + // If we have a pending timer and we get an expose, we need to stop it. + // Otherwise we get two frames and two animation ticks in the same time-interval. + if (m_updateTimer) { + RLDEBUG(" - killing pending update timer"); + killTimer(m_updateTimer); + m_updateTimer = 0; + } + render(); + } else { + handleObscurity(); + } +} + +void QSGWindowsRenderLoop::handleObscurity() +{ + RLDEBUG("handleObscurity"); + // Potentially start the non-visual animation timer if nobody is rendering + if (m_animationDriver->isRunning() && !anyoneShowing() && !m_animationTimer) { + RLDEBUG(" - starting non-visual animation timer"); + m_animationTimer = startTimer(m_vsyncDelta); + } +} + +QImage QSGWindowsRenderLoop::grab(QQuickWindow *window) +{ + RLDEBUG("grab"); + if (!m_gl) + return QImage(); + + m_gl->makeCurrent(window); + + QQuickWindowPrivate *d = QQuickWindowPrivate::get(window); + d->polishItems(); + d->syncSceneGraph(); + d->renderSceneGraph(window->size()); + + QImage image = qt_gl_read_framebuffer(window->size(), false, false); + return image; +} + +void QSGWindowsRenderLoop::update(QQuickWindow *window) +{ + RLDEBUG("update"); + maybeUpdate(window); +} + +void QSGWindowsRenderLoop::maybeUpdate(QQuickWindow *window) +{ + RLDEBUG("maybeUpdate"); + + WindowData *wd = windowData(window); + if (!wd || !anyoneShowing()) + return; + + wd->pendingUpdate = true; + maybePostUpdateTimer(); +} + +bool QSGWindowsRenderLoop::event(QEvent *event) +{ + switch (event->type()) { + case QEvent::Timer: { + QTimerEvent *te = static_cast<QTimerEvent *>(event); + if (te->timerId() == m_animationTimer) { + RLDEBUG("event : animation tick while nothing is showing"); + m_animationDriver->advance(); + } else if (te->timerId() == m_updateTimer) { + RLDEBUG("event : update"); + killTimer(m_updateTimer); + m_updateTimer = 0; + render(); + } + return true; } + default: + break; + } + + return QObject::event(event); +} + +/* + * Go through all windows we control and render them in turn. + * Then tick animations if active. + */ +void QSGWindowsRenderLoop::render() +{ + RLDEBUG("render"); + foreach (const WindowData &wd, m_windows) { + if (wd.pendingUpdate) { + const_cast<WindowData &>(wd).pendingUpdate = false; + renderWindow(wd.window); + } + } + + if (m_animationDriver->isRunning()) { + RLDEBUG("advancing animations"); + QSG_RENDER_TIMING_SAMPLE(time_start); + m_animationDriver->advance(); + RLDEBUG("animations advanced"); + +#ifndef QSG_NO_RENDER_TIMING + if (qsg_render_timing) { + qDebug("WindowsRenderLoop: animations=%d ms", + int(qsg_render_timer.elapsed() - time_start)); + } +#endif + + // It is not given that animations triggered another maybeUpdate() + // and thus another render pass, so to keep things running, + // make sure there is another frame pending. + maybePostUpdateTimer(); + } +} + +/* + * Render the contents of this window. First polish, then sync, render + * then finally swap. + * + * Note: This render function does not implement aborting + * the render call when sync step results in no scene graph changes, + * like the threaded renderer does. + */ +void QSGWindowsRenderLoop::renderWindow(QQuickWindow *window) +{ + RLDEBUG("renderWindow"); + QQuickWindowPrivate *d = QQuickWindowPrivate::get(window); + + if (!d->isRenderable()) + return; + + if (!m_gl->makeCurrent(window)) + return; + + QSG_RENDER_TIMING_SAMPLE(time_start); + + RLDEBUG(" - polishing"); + d->polishItems(); + QSG_RENDER_TIMING_SAMPLE(time_polished); + + RLDEBUG(" - syncing"); + d->syncSceneGraph(); + QSG_RENDER_TIMING_SAMPLE(time_synced); + + RLDEBUG(" - rendering"); + d->renderSceneGraph(window->size()); + QSG_RENDER_TIMING_SAMPLE(time_rendered); + + RLDEBUG(" - swapping"); + m_gl->swapBuffers(window); + QSG_RENDER_TIMING_SAMPLE(time_swapped); + + RLDEBUG(" - frameDone"); + d->fireFrameSwapped(); + +#ifndef QSG_NO_RENDER_TIMING + if (qsg_render_timing) { + qDebug("WindowsRenderLoop(t=%d): window=%p, polish=%d ms, sync=%d ms, render=%d ms, swap=%d ms", + int(qsg_render_timer.elapsed()), + window, + int(time_polished - time_start), + int(time_synced - time_polished), + int(time_rendered - time_synced), + int(time_swapped - time_rendered)); + } +#endif +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgwindowsrenderloop_p.h b/src/quick/scenegraph/qsgwindowsrenderloop_p.h new file mode 100644 index 0000000000..dc3a409cd5 --- /dev/null +++ b/src/quick/scenegraph/qsgwindowsrenderloop_p.h @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGWINDOWSRENDERLOOP_P_H +#define QSGWINDOWSRENDERLOOP_P_H + +#include <QtCore/QObject> +#include <QtCore/QElapsedTimer> + +#include <QtGui/QOpenGLContext> + +#include "qsgrenderloop_p.h" + +QT_BEGIN_NAMESPACE + +class QSGWindowsRenderLoop : public QObject, public QSGRenderLoop +{ + Q_OBJECT +public: + explicit QSGWindowsRenderLoop(); + + void show(QQuickWindow *window); + void hide(QQuickWindow *window); + + void windowDestroyed(QQuickWindow *window); + + void exposureChanged(QQuickWindow *window); + QImage grab(QQuickWindow *window); + + void update(QQuickWindow *window); + void maybeUpdate(QQuickWindow *window); + + QAnimationDriver *animationDriver() const { return m_animationDriver; } + + QSGContext *sceneGraphContext() const { return m_sg; } + + void releaseResources(QQuickWindow *) { } + + void render(); + void renderWindow(QQuickWindow *window); + + void resize(QQuickWindow *, const QSize &) { } + + bool event(QEvent *event); + +public slots: + void started(); + void stopped(); + +private: + struct WindowData { + QQuickWindow *window; + bool pendingUpdate; + }; + + void handleObscurity(); + void maybePostUpdateTimer(); + bool anyoneShowing() const; + WindowData *windowData(QQuickWindow *window); + + QList<WindowData> m_windows; + + QOpenGLContext *m_gl; + QSGContext *m_sg; + + QAnimationDriver *m_animationDriver; + + int m_updateTimer; + int m_animationTimer; + + int m_vsyncDelta; +}; + +QT_END_NAMESPACE + +#endif // QSGWINDOWSRENDERLOOP_P_H diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri index ebf886dace..34432ffd9c 100644 --- a/src/quick/scenegraph/scenegraph.pri +++ b/src/quick/scenegraph/scenegraph.pri @@ -52,7 +52,6 @@ SOURCES += \ $$PWD/util/qsgpainternode.cpp \ $$PWD/util/qsgdistancefieldutil.cpp - # QML / Adaptations API HEADERS += \ $$PWD/qsgadaptationlayer_p.h \ @@ -68,8 +67,8 @@ HEADERS += \ $$PWD/qsgflashnode_p.h \ $$PWD/qsgshareddistancefieldglyphcache_p.h \ $$PWD/qsgrenderloop_p.h \ - $$PWD/qsgthreadedrenderloop_p.h - + $$PWD/qsgthreadedrenderloop_p.h \ + $$PWD/qsgwindowsrenderloop_p.h SOURCES += \ $$PWD/qsgadaptationlayer.cpp \ @@ -85,12 +84,5 @@ SOURCES += \ $$PWD/qsgflashnode.cpp \ $$PWD/qsgshareddistancefieldglyphcache.cpp \ $$PWD/qsgrenderloop.cpp \ - $$PWD/qsgthreadedrenderloop.cpp - - - - - - - - + $$PWD/qsgthreadedrenderloop.cpp \ + $$PWD/qsgwindowsrenderloop.cpp diff --git a/src/quick/util/qquickimageprovider.cpp b/src/quick/util/qquickimageprovider.cpp index abdadaa5d3..4906645f6c 100644 --- a/src/quick/util/qquickimageprovider.cpp +++ b/src/quick/util/qquickimageprovider.cpp @@ -242,7 +242,7 @@ QImage QQuickTextureFactory::image() const \c cache property to \c false for the relevant \l Image, \l BorderImage or \l AnimatedImage object. - The QtQuick 1 version of this class is named QDeclarativeImageProvider. + The \l {Qt Quick 1} version of this class is named QDeclarativeImageProvider. \sa QQmlEngine::addImageProvider() */ diff --git a/src/quick/util/qquickpath.cpp b/src/quick/util/qquickpath.cpp index 3aea724983..fc33f8f1f8 100644 --- a/src/quick/util/qquickpath.cpp +++ b/src/quick/util/qquickpath.cpp @@ -188,8 +188,67 @@ bool QQuickPath::hasEnd() const QQmlListProperty<QQuickPathElement> QQuickPath::pathElements() { - Q_D(QQuickPath); - return QQmlListProperty<QQuickPathElement>(this, d->_pathElements); + return QQmlListProperty<QQuickPathElement>(this, + 0, + pathElements_append, + pathElements_count, + pathElements_at, + pathElements_clear); +} + +static QQuickPathPrivate *privatePath(QObject *object) +{ + QQuickPath *path = static_cast<QQuickPath*>(object); + + return QQuickPathPrivate::get(path); +} + +QQuickPathElement *QQuickPath::pathElements_at(QQmlListProperty<QQuickPathElement> *property, int index) +{ + QQuickPathPrivate *d = privatePath(property->object); + + return d->_pathElements.at(index); +} + +void QQuickPath::pathElements_append(QQmlListProperty<QQuickPathElement> *property, QQuickPathElement *pathElement) +{ + QQuickPathPrivate *d = privatePath(property->object); + QQuickPath *path = static_cast<QQuickPath*>(property->object); + + d->_pathElements.append(pathElement); + + if (d->componentComplete) { + QQuickCurve *curve = qobject_cast<QQuickCurve *>(pathElement); + if (curve) + d->_pathCurves.append(curve); + else { + QQuickPathAttribute *attribute = qobject_cast<QQuickPathAttribute *>(pathElement); + if (attribute && !d->_attributes.contains(attribute->name())) + d->_attributes.append(attribute->name()); + } + + path->processPath(); + + connect(pathElement, SIGNAL(changed()), path, SLOT(processPath())); + } +} + +int QQuickPath::pathElements_count(QQmlListProperty<QQuickPathElement> *property) +{ + QQuickPathPrivate *d = privatePath(property->object); + + return d->_pathElements.count(); +} + +void QQuickPath::pathElements_clear(QQmlListProperty<QQuickPathElement> *property) +{ + QQuickPathPrivate *d = privatePath(property->object); + QQuickPath *path = static_cast<QQuickPath*>(property->object); + + path->disconnectPathElements(); + d->_pathElements.clear(); + d->_pathCurves.clear(); + d->_pointCache.clear(); } void QQuickPath::interpolate(int idx, const QString &name, qreal value) @@ -373,27 +432,49 @@ void QQuickPath::classBegin() d->componentComplete = false; } -void QQuickPath::componentComplete() +void QQuickPath::disconnectPathElements() +{ + Q_D(QQuickPath); + + foreach (QQuickPathElement *pathElement, d->_pathElements) + disconnect(pathElement, SIGNAL(changed()), this, SLOT(processPath())); +} + +void QQuickPath::connectPathElements() { Q_D(QQuickPath); - QSet<QString> attrs; - d->componentComplete = true; + + foreach (QQuickPathElement *pathElement, d->_pathElements) + connect(pathElement, SIGNAL(changed()), this, SLOT(processPath())); +} + +void QQuickPath::gatherAttributes() +{ + Q_D(QQuickPath); + + QSet<QString> attributes; // First gather up all the attributes foreach (QQuickPathElement *pathElement, d->_pathElements) { - if (QQuickCurve *curve = - qobject_cast<QQuickCurve *>(pathElement)) + if (QQuickCurve *curve = qobject_cast<QQuickCurve *>(pathElement)) d->_pathCurves.append(curve); - else if (QQuickPathAttribute *attribute = - qobject_cast<QQuickPathAttribute *>(pathElement)) - attrs.insert(attribute->name()); + else if (QQuickPathAttribute *attribute = qobject_cast<QQuickPathAttribute *>(pathElement)) + attributes.insert(attribute->name()); } - d->_attributes = attrs.toList(); + + d->_attributes = attributes.toList(); +} + +void QQuickPath::componentComplete() +{ + Q_D(QQuickPath); + d->componentComplete = true; + + gatherAttributes(); processPath(); - foreach (QQuickPathElement *pathElement, d->_pathElements) - connect(pathElement, SIGNAL(changed()), this, SLOT(processPath())); + connectPathElements(); } QPainterPath QQuickPath::path() const diff --git a/src/quick/util/qquickpath_p.h b/src/quick/util/qquickpath_p.h index 71545851e4..1a9be7c82a 100644 --- a/src/quick/util/qquickpath_p.h +++ b/src/quick/util/qquickpath_p.h @@ -393,6 +393,15 @@ Q_SIGNALS: protected: virtual void componentComplete(); virtual void classBegin(); + void disconnectPathElements(); + void connectPathElements(); + void gatherAttributes(); + + // pathElements property + static QQuickPathElement *pathElements_at(QQmlListProperty<QQuickPathElement> *, int); + static void pathElements_append(QQmlListProperty<QQuickPathElement> *, QQuickPathElement *); + static int pathElements_count(QQmlListProperty<QQuickPathElement> *); + static void pathElements_clear(QQmlListProperty<QQuickPathElement> *); private Q_SLOTS: void processPath(); diff --git a/src/quick/util/qquickpath_p_p.h b/src/quick/util/qquickpath_p_p.h index b4227e64f3..e376925f21 100644 --- a/src/quick/util/qquickpath_p_p.h +++ b/src/quick/util/qquickpath_p_p.h @@ -67,6 +67,9 @@ class QQuickPathPrivate : public QObjectPrivate Q_DECLARE_PUBLIC(QQuickPath) public: + static QQuickPathPrivate* get(QQuickPath *path) { return path->d_func(); } + static const QQuickPathPrivate* get(const QQuickPath *path) { return path->d_func(); } + QQuickPathPrivate() : pathLength(0), closed(false), componentComplete(true) { } QPainterPath _path; diff --git a/src/quick/util/qquicksvgparser.cpp b/src/quick/util/qquicksvgparser.cpp index 760b4b0e2f..ece6d24ee1 100644 --- a/src/quick/util/qquicksvgparser.cpp +++ b/src/quick/util/qquicksvgparser.cpp @@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE static const double Q_PI = 3.14159265358979323846; // pi -//copied from QtSvg (qsvghandler.cpp). +//copied from Qt SVG (qsvghandler.cpp). Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok); // '0' is 0x30 and '9' is 0x39 static inline bool isDigit(ushort ch) diff --git a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp index 9c2ba5bcde..424a3b36ac 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp +++ b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp @@ -53,6 +53,11 @@ #include "qqmldebugclient.h" #include "../../../shared/util.h" +#if defined (Q_OS_WINCE) +#undef IN +#undef OUT +#endif + const char *V8REQUEST = "v8request"; const char *V8MESSAGE = "v8message"; const char *SEQ = "seq"; diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp index 70b718c4d8..23c32c163f 100644 --- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp +++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp @@ -246,7 +246,7 @@ void tst_QJSEngine::newArray_HooliganTask233836() } { QJSValue ret = eng.newArray(0xFFFFFFFF); - QEXPECT_FAIL("", "The maximum length of arrays is defined by v8 currently and differs from QtScript", Abort); + QEXPECT_FAIL("", "The maximum length of arrays is defined by v8 currently and differs from Qt Script", Abort); QCOMPARE(ret.property("length").toUInt(), uint(0xFFFFFFFF)); ret.setProperty(0xFFFFFFFF, 123); QCOMPARE(ret.property("length").toUInt(), uint(0xFFFFFFFF)); @@ -1917,7 +1917,7 @@ void tst_QJSEngine::jsFunctionDeclarationAsStatement() // at the beginning of chapter 12 in ECMA-262 5th edition, where it's // recommended that implementations either disallow this usage or issue // a warning. - // Since we had a bug report long ago about QtScript not supporting this + // Since we had a bug report long ago about Qt Script not supporting this // "feature" (and thus deviating from other implementations), we still // check this behavior. @@ -2625,7 +2625,7 @@ void tst_QJSEngine::qRegExpInport() } // QScriptValue::toDateTime() returns a local time, whereas JS dates -// are always stored as UTC. QtScript must respect the current time +// are always stored as UTC. Qt Script must respect the current time // zone, and correctly adjust for daylight saving time that may be in // effect at a given date (QTBUG-9770). void tst_QJSEngine::dateRoundtripJSQtJS() diff --git a/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp b/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp index a8bb887158..9230608622 100644 --- a/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp +++ b/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp @@ -73,7 +73,8 @@ private slots: void basicProperties(); void resetFiltering(); void refresh(); -#if defined (Q_OS_WIN) +#if defined (Q_OS_WIN) && !defined (Q_OS_WINCE) + // WinCE does not have drive concept, so lets execute this test only on desktop Windows. void changeDrive(); #endif @@ -181,7 +182,7 @@ void tst_qquickfolderlistmodel::refresh() QTRY_COMPARE(removeEnd, count-1); // wait for refresh } -#if defined (Q_OS_WIN) +#if defined (Q_OS_WIN) && !defined (Q_OS_WINCE) void tst_qquickfolderlistmodel::changeDrive() { QSKIP("QTBUG-26728"); diff --git a/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp b/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp index a2bf06c2ba..ed8fb9f56f 100644 --- a/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp +++ b/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp @@ -138,7 +138,7 @@ void tst_QQuickWorkerScript::messaging_data() QTest::newRow("variant list") << qVariantFromValue((QVariantList() << "a" << "b" << "c")); QTest::newRow("date time") << qVariantFromValue(QDateTime::currentDateTime()); #ifndef QT_NO_REGEXP - // QtScript's QScriptValue -> QRegExp uses RegExp2 pattern syntax + // Qt Script's QScriptValue -> QRegExp uses RegExp2 pattern syntax QTest::newRow("regexp") << qVariantFromValue(QRegExp("^\\d\\d?$", Qt::CaseInsensitive, QRegExp::RegExp2)); #endif } diff --git a/tests/auto/qmltest/listview/tst_listview.qml b/tests/auto/qmltest/listview/tst_listview.qml index cbace624c3..52384fe242 100644 --- a/tests/auto/qmltest/listview/tst_listview.qml +++ b/tests/auto/qmltest/listview/tst_listview.qml @@ -38,7 +38,7 @@ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick 2.1 import QtTest 1.0 Item { @@ -168,6 +168,7 @@ Item { modelalter.currentIndex = 1; compare(modelalter.currentItem.text, "AlterModelElement1") altermodel.clear() + modelalter.forceLayout() tryCompare(modelalter.count, 0) compare(modelalter.currentItem, null) } diff --git a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp index 0c9788ab8e..d0ffba9435 100644 --- a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp +++ b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp @@ -532,6 +532,7 @@ void tst_QQuickGridView::inserted_defaultLayout(QQuickGridView::Flow flow, for (int i=0; i<insertCount; i++) newData << qMakePair(QString("value %1").arg(i), QString::number(i)); model.insertItems(insertIndex, newData); + gridview->forceLayout(); QTRY_COMPARE(gridview->property("count").toInt(), model.count()); // check visibleItems.first() is in correct position @@ -728,6 +729,7 @@ void tst_QQuickGridView::insertBeforeVisible() for (int i=0; i<insertCount; i++) newData << qMakePair(QString("value %1").arg(i), QString::number(i)); model.insertItems(insertIndex, newData); + gridview->forceLayout(); QTRY_COMPARE(gridview->property("count").toInt(), model.count()); // now, moving to the top of the view should position the inserted items correctly @@ -958,6 +960,7 @@ void tst_QQuickGridView::removed_defaultLayout(QQuickGridView::Flow flow, QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); model.removeItems(removeIndex, removeCount); + gridview->forceLayout(); QTRY_COMPARE(gridview->property("count").toInt(), model.count()); QString firstName; @@ -1245,6 +1248,7 @@ void tst_QQuickGridView::clear() QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); model.clear(); + gridview->forceLayout(); QVERIFY(gridview->count() == 0); QVERIFY(gridview->currentItem() == 0); @@ -1254,6 +1258,7 @@ void tst_QQuickGridView::clear() // confirm sanity when adding an item to cleared list model.addItem("New", "1"); + gridview->forceLayout(); QTRY_COMPARE(gridview->count(), 1); QVERIFY(gridview->currentItem() != 0); QVERIFY(gridview->currentIndex() == 0); @@ -3483,6 +3488,7 @@ void tst_QQuickGridView::extents() QCOMPARE(gridview->originY(), origin_empty.y()); for (int i=0; i<30; i++) model.addItem("Item" + QString::number(i), ""); + gridview->forceLayout(); QTRY_COMPARE(gridview->count(), model.count()); QCOMPARE(gridview->originX(), origin_nonEmpty.x()); QCOMPARE(gridview->originY(), origin_nonEmpty.y()); @@ -3942,9 +3948,9 @@ void tst_QQuickGridView::onAdd() ctxt->setContextProperty("delegateHeight", delegateHeight); window->setSource(testFileUrl("attachedSignals.qml")); - QObject *object = window->rootObject(); - object->setProperty("width", window->width()); - object->setProperty("height", window->height()); + QQuickGridView *gridview = qobject_cast<QQuickGridView*>(window->rootObject()); + gridview->setProperty("width", window->width()); + gridview->setProperty("height", window->height()); qApp->processEvents(); QList<QPair<QString, QString> > items; @@ -3952,10 +3958,11 @@ void tst_QQuickGridView::onAdd() items << qMakePair(QString("value %1").arg(i), QString::number(i)); model.addItems(items); - QTRY_COMPARE(model.count(), qobject_cast<QQuickGridView*>(window->rootObject())->count()); + gridview->forceLayout(); + QTRY_COMPARE(model.count(), gridview->count()); qApp->processEvents(); - QVariantList result = object->property("addedDelegates").toList(); + QVariantList result = gridview->property("addedDelegates").toList(); QTRY_COMPARE(result.count(), items.count()); for (int i=0; i<items.count(); i++) QCOMPARE(result[i].toString(), items[i].first); @@ -3999,11 +4006,12 @@ void tst_QQuickGridView::onRemove() ctxt->setContextProperty("delegateWidth", delegateWidth); ctxt->setContextProperty("delegateHeight", delegateHeight); window->setSource(testFileUrl("attachedSignals.qml")); - QObject *object = window->rootObject(); + QQuickGridView *gridview = qobject_cast<QQuickGridView*>(window->rootObject()); model.removeItems(indexToRemove, removeCount); - QTRY_COMPARE(model.count(), qobject_cast<QQuickGridView*>(window->rootObject())->count()); - QCOMPARE(object->property("removedDelegateCount"), QVariant(removeCount)); + gridview->forceLayout(); + QTRY_COMPARE(model.count(), gridview->count()); + QCOMPARE(gridview->property("removedDelegateCount"), QVariant(removeCount)); releaseView(window); } @@ -4151,6 +4159,7 @@ void tst_QQuickGridView::margins() gridview->setContentX(-400); QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); model.removeItems(0, 4); + gridview->forceLayout(); QTRY_COMPARE(model.count(), gridview->count()); gridview->setContentX(-240+50); gridview->returnToBounds(); @@ -4458,6 +4467,7 @@ void tst_QQuickGridView::unaligned() // removing model.removeItems(7, 10); + gridview->forceLayout(); QTRY_COMPARE(model.count(), gridview->count()); for (int i = 0; i < 18; ++i) { QQuickItem *item = 0; @@ -4663,6 +4673,7 @@ void tst_QQuickGridView::addTransitions() // start animation if (!newData.isEmpty()) { model.insertItems(insertionIndex, newData); + gridview->forceLayout(); QTRY_COMPARE(model.count(), gridview->count()); } @@ -4866,6 +4877,7 @@ void tst_QQuickGridView::moveTransitions() // start animation model.moveItems(moveFrom, moveTo, moveCount); + gridview->forceLayout(); QTRY_COMPARE(gridview->property("targetTransitionsDone").toInt(), expectedTargetData.count()); QTRY_COMPARE(gridview->property("displaceTransitionsDone").toInt(), @@ -5114,6 +5126,7 @@ void tst_QQuickGridView::removeTransitions() // start animation model.removeItems(removalIndex, removalCount); + gridview->forceLayout(); QTRY_COMPARE(model.count(), gridview->count()); if (shouldAnimateTargets || expectedDisplacedIndexes.isValid()) { @@ -5327,6 +5340,7 @@ void tst_QQuickGridView::displacedTransitions() case ListChange::Polish: break; } + gridview->forceLayout(); QVariantList resultTargetIndexes = gridview->property("displacedTargetIndexes").toList(); QVariantList resultTargetItems = gridview->property("displacedTargetItems").toList(); @@ -5534,6 +5548,7 @@ void tst_QQuickGridView::multipleTransitions() for (int j=changes[i].index; j<changes[i].index + changes[i].count; ++j) targetItems << qMakePair(QString("new item %1").arg(j), QString::number(j)); model.insertItems(changes[i].index, targetItems); + gridview->forceLayout(); QTRY_COMPARE(model.count(), gridview->count()); if (i == changes.count() - 1) { QTRY_VERIFY(!gridview->property("runningAddTargets").toBool()); @@ -5545,6 +5560,7 @@ void tst_QQuickGridView::multipleTransitions() } case ListChange::Removed: model.removeItems(changes[i].index, changes[i].count); + gridview->forceLayout(); QTRY_COMPARE(model.count(), gridview->count()); if (i == changes.count() - 1) { QTRY_VERIFY(!gridview->property("runningRemoveTargets").toBool()); @@ -5555,6 +5571,7 @@ void tst_QQuickGridView::multipleTransitions() break; case ListChange::Moved: model.moveItems(changes[i].index, changes[i].to, changes[i].count); + gridview->forceLayout(); QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); if (i == changes.count() - 1) { QTRY_VERIFY(!gridview->property("runningMoveTargets").toBool()); @@ -5566,16 +5583,17 @@ void tst_QQuickGridView::multipleTransitions() case ListChange::SetCurrent: gridview->setCurrentIndex(changes[i].index); QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + gridview->forceLayout(); break; case ListChange::SetContentY: gridview->setContentY(changes[i].pos); QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + gridview->forceLayout(); break; case ListChange::Polish: break; } } - QCOMPARE(gridview->count(), model.count()); QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper"); int firstVisibleIndex = -1; @@ -5586,6 +5604,7 @@ void tst_QQuickGridView::multipleTransitions() break; } } + QTRY_COMPARE(gridview->count(), model.count()); QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex)); // verify all items moved to the correct final positions diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp index f2d25e81ed..3ec77ce950 100644 --- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp @@ -70,6 +70,8 @@ private slots: void activeFocusOnTab4(); void activeFocusOnTab5(); + void nextItemInFocusChain(); + void keys(); void keysProcessingOrder(); void keysim(); @@ -664,6 +666,79 @@ void tst_QQuickItem::activeFocusOnTab5() delete window; } +void tst_QQuickItem::nextItemInFocusChain() +{ + QQuickView *window = new QQuickView(0); + window->setBaseSize(QSize(800,600)); + + window->setSource(testFileUrl("activeFocusOnTab.qml")); + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + QVERIFY(QGuiApplication::focusWindow() == window); + + QQuickItem *button11 = findItem<QQuickItem>(window->rootObject(), "button11"); + QVERIFY(button11); + QQuickItem *button12 = findItem<QQuickItem>(window->rootObject(), "button12"); + QVERIFY(button12); + + QQuickItem *sub2 = findItem<QQuickItem>(window->rootObject(), "sub2"); + QVERIFY(sub2); + QQuickItem *button21 = findItem<QQuickItem>(window->rootObject(), "button21"); + QVERIFY(button21); + QQuickItem *button22 = findItem<QQuickItem>(window->rootObject(), "button22"); + QVERIFY(button22); + + QQuickItem *edit = findItem<QQuickItem>(window->rootObject(), "edit"); + QVERIFY(edit); + + QQuickItem *next, *prev; + + next = button11->nextItemInFocusChain(true); + QVERIFY(next); + QCOMPARE(next, button12); + prev = button11->nextItemInFocusChain(false); + QVERIFY(prev); + QCOMPARE(prev, edit); + + next = button12->nextItemInFocusChain(); + QVERIFY(next); + QCOMPARE(next, sub2); + prev = button12->nextItemInFocusChain(false); + QVERIFY(prev); + QCOMPARE(prev, button11); + + next = sub2->nextItemInFocusChain(true); + QVERIFY(next); + QCOMPARE(next, button21); + prev = sub2->nextItemInFocusChain(false); + QVERIFY(prev); + QCOMPARE(prev, button12); + + next = button21->nextItemInFocusChain(); + QVERIFY(next); + QCOMPARE(next, button22); + prev = button21->nextItemInFocusChain(false); + QVERIFY(prev); + QCOMPARE(prev, sub2); + + next = button22->nextItemInFocusChain(true); + QVERIFY(next); + QCOMPARE(next, edit); + prev = button22->nextItemInFocusChain(false); + QVERIFY(prev); + QCOMPARE(prev, button21); + + next = edit->nextItemInFocusChain(); + QVERIFY(next); + QCOMPARE(next, button11); + prev = edit->nextItemInFocusChain(false); + QVERIFY(prev); + QCOMPARE(prev, button22); + + delete window; +} + void tst_QQuickItem::keys() { QQuickView *window = new QQuickView(0); diff --git a/tests/auto/quick/qquicklistview/data/delayedChanges.qml b/tests/auto/quick/qquicklistview/data/delayedChanges.qml new file mode 100644 index 0000000000..590af39c02 --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/delayedChanges.qml @@ -0,0 +1,39 @@ +import QtQuick 2.1 + +Item { + width: 400 + height: 400 + function takeTwo() + { + listView.model.remove(0); + listView.model.remove(0); + } + function takeTwo_sync() + { + listView.model.remove(0); + listView.forceLayout(); + listView.model.remove(0); + listView.forceLayout(); + } + + ListView { + id: listView + height: parent.height + width: 400 + model: ListModel { + ListElement { name: "A" } + ListElement { name: "B" } + ListElement { name: "C" } + ListElement { name: "D" } + ListElement { name: "E" } + ListElement { name: "F" } + ListElement { name: "G" } + ListElement { name: "H" } + ListElement { name: "I" } + ListElement { name: "J" } + } + delegate: Text { + text: index + listView.count + } + } +} diff --git a/tests/auto/quick/qquicklistview/data/emptymodel.qml b/tests/auto/quick/qquicklistview/data/emptymodel.qml index 16bcd3f9ae..3feec691cf 100644 --- a/tests/auto/quick/qquicklistview/data/emptymodel.qml +++ b/tests/auto/quick/qquicklistview/data/emptymodel.qml @@ -1,4 +1,4 @@ -import QtQuick 2.0 +import QtQuick 2.1 Rectangle { ListModel { id: model @@ -12,11 +12,13 @@ Rectangle { } function remove() { model.remove(0) + list.forceLayout() isCurrentItemNull = list.currentItem === null //check no seg fault } function add() { model.append({name: "hello"}) + list.forceLayout() isCurrentItemNull = list.currentItem === null } property bool isCurrentItemNull diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index f8c7de6635..bec61eaccb 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -208,10 +208,11 @@ private slots: void parentBinding(); void defaultHighlightMoveDuration(); void accessEmptyCurrentItem_QTBUG_30227(); + void delayedChanges_QTBUG_30555(); private: - template <class T> void items(const QUrl &source, bool forceLayout); - template <class T> void changed(const QUrl &source, bool forceLayout); + template <class T> void items(const QUrl &source); + template <class T> void changed(const QUrl &source); template <class T> void inserted(const QUrl &source); template <class T> void inserted_more(QQuickItemView::VerticalLayoutDirection verticalLayoutDirection = QQuickItemView::TopToBottom); template <class T> void removed(const QUrl &source, bool animated); @@ -329,7 +330,7 @@ void tst_QQuickListView::cleanupTestCase() } template <class T> -void tst_QQuickListView::items(const QUrl &source, bool forceLayout) +void tst_QQuickListView::items(const QUrl &source) { QQuickView *window = createView(); @@ -349,6 +350,7 @@ void tst_QQuickListView::items(const QUrl &source, bool forceLayout) QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list"); QTRY_VERIFY(listview != 0); + listview->forceLayout(); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != 0); @@ -359,6 +361,7 @@ void tst_QQuickListView::items(const QUrl &source, bool forceLayout) QTRY_VERIFY(listview->highlightItem() != 0); QTRY_COMPARE(listview->count(), model.count()); QTRY_COMPARE(window->rootObject()->property("count").toInt(), model.count()); + listview->forceLayout(); QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item // current item should be first item @@ -398,8 +401,7 @@ void tst_QQuickListView::items(const QUrl &source, bool forceLayout) ctxt->setContextProperty("testModel", &model2); // Force a layout, necessary if ListView is completed before VisualDataModel. - if (forceLayout) - QCOMPARE(listview->property("count").toInt(), 0); + listview->forceLayout(); int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count(); QTRY_VERIFY(itemCount == 0); @@ -413,7 +415,7 @@ void tst_QQuickListView::items(const QUrl &source, bool forceLayout) template <class T> -void tst_QQuickListView::changed(const QUrl &source, bool forceLayout) +void tst_QQuickListView::changed(const QUrl &source) { QQuickView *window = createView(); @@ -431,15 +433,15 @@ void tst_QQuickListView::changed(const QUrl &source, bool forceLayout) window->setSource(source); qApp->processEvents(); - QQuickFlickable *listview = findItem<QQuickFlickable>(window->rootObject(), "list"); + QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list"); QTRY_VERIFY(listview != 0); + listview->forceLayout(); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != 0); // Force a layout, necessary if ListView is completed before VisualDataModel. - if (forceLayout) - QCOMPARE(listview->property("count").toInt(), model.count()); + listview->forceLayout(); model.modifyItem(1, "Will", "9876"); QQuickText *name = findItem<QQuickText>(contentItem, "textName", 1); @@ -579,22 +581,24 @@ void tst_QQuickListView::inserted_more(QQuickItemView::VerticalLayoutDirection v QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != 0); - bool waitForPolish = (contentY != 0); if (verticalLayoutDirection == QQuickItemView::BottomToTop) { listview->setVerticalLayoutDirection(verticalLayoutDirection); QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); contentY = -listview->height() - contentY; } listview->setContentY(contentY); - if (waitForPolish) - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); QList<QPair<QString, QString> > newData; for (int i=0; i<insertCount; i++) newData << qMakePair(QString("value %1").arg(i), QString::number(i)); model.insertItems(insertIndex, newData); + + //Wait for polish (updates list to the model changes) + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QTRY_COMPARE(listview->property("count").toInt(), model.count()); + // check visibleItems.first() is in correct position QQuickItem *item0 = findItem<QQuickItem>(contentItem, "wrapper", 0); QVERIFY(item0); @@ -1019,17 +1023,17 @@ void tst_QQuickListView::removed_more(const QUrl &source, QQuickItemView::Vertic QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != 0); - bool waitForPolish = (contentY != 0); if (verticalLayoutDirection == QQuickItemView::BottomToTop) { listview->setVerticalLayoutDirection(verticalLayoutDirection); QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); contentY = -listview->height() - contentY; } listview->setContentY(contentY); - if (waitForPolish) - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); model.removeItems(removeIndex, removeCount); + //Wait for polish (updates list to the model changes) + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QTRY_COMPARE(listview->property("count").toInt(), model.count()); // check visibleItems.first() is in correct position @@ -1219,6 +1223,7 @@ void tst_QQuickListView::clear(const QUrl &source, QQuickItemView::VerticalLayou // confirm sanity when adding an item to cleared list model.addItem("New", "1"); + listview->forceLayout(); QTRY_VERIFY(listview->count() == 1); QVERIFY(listview->currentItem() != 0); QVERIFY(listview->currentIndex() == 0); @@ -1945,6 +1950,7 @@ void tst_QQuickListView::sections(const QUrl &source) // Remove section boundary model.removeItem(5); + listview->forceLayout(); QTRY_COMPARE(listview->count(), model.count()); // New section header created @@ -1953,6 +1959,7 @@ void tst_QQuickListView::sections(const QUrl &source) QTRY_COMPARE(item->height(), 40.0); model.insertItem(3, "New Item", "0"); + listview->forceLayout(); QTRY_COMPARE(listview->count(), model.count()); // Section header moved @@ -1966,6 +1973,7 @@ void tst_QQuickListView::sections(const QUrl &source) // insert item which will become a section header model.insertItem(6, "Replace header", "1"); + listview->forceLayout(); QTRY_COMPARE(listview->count(), model.count()); item = findItem<QQuickItem>(contentItem, "wrapper", 6); @@ -2061,6 +2069,7 @@ void tst_QQuickListView::sectionsDelegate() // remove section boundary model.removeItem(5); + listview->forceLayout(); QTRY_COMPARE(listview->count(), model.count()); for (int i = 0; i < 3; ++i) { QQuickItem *item = findItem<QQuickItem>(contentItem, @@ -2288,6 +2297,7 @@ void tst_QQuickListView::sectionsPositioning() listview->setContentY(120); QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); model.removeItem(5); + listview->forceLayout(); QTRY_COMPARE(listview->count(), model.count()); for (int i = 1; i < 3; ++i) { QQuickItem *item = findVisibleChild(contentItem, @@ -2485,7 +2495,8 @@ void tst_QQuickListView::currentIndex_delayedItemCreation() QTRY_VERIFY(contentItem != 0); QSignalSpy spy(listview, SIGNAL(currentItemChanged())); - QCOMPARE(listview->currentIndex(), 0); + //QCOMPARE(listview->currentIndex(), 0); + listview->forceLayout(); QTRY_COMPARE(spy.count(), 1); releaseView(window); @@ -2536,6 +2547,7 @@ void tst_QQuickListView::currentIndex() for (int i = 0; i < 30; i++) model.addItem("Item" + QString::number(i), QString::number(i)); ctxt->setContextProperty("testModel", &model); + listview->forceLayout(); QCOMPARE(listview->currentIndex(), 0); QCOMPARE(listview->currentItem(), findItem<QQuickItem>(contentItem, "wrapper", 0)); @@ -2679,6 +2691,7 @@ void tst_QQuickListView::keyNavigation() QTRY_COMPARE(listview->currentIndex(), i+1); } QTest::keyRelease(window, forwardsKey); + listview->forceLayout(); QTRY_COMPARE(listview->currentIndex(), model.count()-1); QTRY_COMPARE(listview->contentX(), contentPosAtLastItem.x()); QTRY_COMPARE(listview->contentY(), contentPosAtLastItem.y()); @@ -2689,6 +2702,7 @@ void tst_QQuickListView::keyNavigation() QTRY_COMPARE(listview->currentIndex(), i-1); } QTest::keyRelease(window, backwardsKey); + listview->forceLayout(); QTRY_COMPARE(listview->currentIndex(), 0); QTRY_COMPARE(listview->contentX(), contentPosAtFirstItem.x()); QTRY_COMPARE(listview->contentY(), contentPosAtFirstItem.y()); @@ -3123,6 +3137,7 @@ void tst_QQuickListView::resetModel() strings << "four" << "five" << "six" << "seven"; model.setStringList(strings); + listview->forceLayout(); QTRY_COMPARE(listview->count(), model.rowCount()); for (int i = 0; i < model.rowCount(); ++i) { @@ -3470,6 +3485,7 @@ void tst_QQuickListView::header() QCOMPARE(item->position(), firstDelegatePos); model.clear(); + listview->forceLayout(); QTRY_COMPARE(listview->count(), model.count()); QCOMPARE(header->position(), initialHeaderPos); // header should stay where it is if (orientation == QQuickListView::Vertical) @@ -3865,6 +3881,7 @@ void tst_QQuickListView::extents() QCOMPARE(listview->originY(), origin_empty.y()); for (int i=0; i<30; i++) model.addItem("Item" + QString::number(i), ""); + listview->forceLayout(); QTRY_COMPARE(listview->count(), model.count()); QCOMPARE(listview->originX(), origin_nonEmpty.x()); QCOMPARE(listview->originY(), origin_nonEmpty.y()); @@ -4262,6 +4279,7 @@ void tst_QQuickListView::resizeFirstDelegate() for (int i = 0; i < 10; i++) model.addItem("Item" + QString::number(i), ""); + listview->forceLayout(); QTRY_COMPARE(listview->count(), model.count()); item = findItem<QQuickItem>(contentItem, "wrapper", 1); @@ -4461,6 +4479,7 @@ void tst_QQuickListView::indexAt_itemAt() void tst_QQuickListView::incrementalModel() { QQuickView *window = createView(); + QSKIP("QTBUG-30716"); IncrementalModel model; QQmlContext *ctxt = window->rootContext(); @@ -4471,14 +4490,17 @@ void tst_QQuickListView::incrementalModel() QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list"); QTRY_VERIFY(listview != 0); + listview->forceLayout(); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != 0); + listview->forceLayout(); QTRY_COMPARE(listview->count(), 20); listview->positionViewAtIndex(10, QQuickListView::Beginning); + listview->forceLayout(); QTRY_COMPARE(listview->count(), 25); delete window; @@ -4503,18 +4525,19 @@ void tst_QQuickListView::onAdd() ctxt->setContextProperty("delegateHeight", delegateHeight); window->setSource(testFileUrl("attachedSignals.qml")); - QObject *object = window->rootObject(); - object->setProperty("width", window->width()); - object->setProperty("height", window->height()); + QQuickListView* listview = qobject_cast<QQuickListView*>(window->rootObject()); + listview->setProperty("width", window->width()); + listview->setProperty("height", window->height()); qApp->processEvents(); QList<QPair<QString, QString> > items; for (int i=0; i<itemsToAdd; i++) items << qMakePair(QString("value %1").arg(i), QString::number(i)); model.addItems(items); - QTRY_COMPARE(window->rootObject()->property("count").toInt(), model.count()); + listview->forceLayout(); + QTRY_COMPARE(listview->property("count").toInt(), model.count()); - QVariantList result = object->property("addedDelegates").toList(); + QVariantList result = listview->property("addedDelegates").toList(); QCOMPARE(result.count(), items.count()); for (int i=0; i<items.count(); i++) QCOMPARE(result[i].toString(), items[i].first); @@ -4557,12 +4580,13 @@ void tst_QQuickListView::onRemove() ctxt->setContextProperty("delegateHeight", delegateHeight); window->setSource(testFileUrl("attachedSignals.qml")); - QObject *object = window->rootObject(); + QQuickListView *listview = qobject_cast<QQuickListView *>(window->rootObject()); model.removeItems(indexToRemove, removeCount); - QTRY_COMPARE(window->rootObject()->property("count").toInt(), model.count()); + listview->forceLayout(); + QTRY_COMPARE(listview->property("count").toInt(), model.count()); - QCOMPARE(object->property("removedDelegateCount"), QVariant(removeCount)); + QCOMPARE(listview->property("removedDelegateCount"), QVariant(removeCount)); releaseView(window); } @@ -4741,6 +4765,7 @@ void tst_QQuickListView::margins() // and originY is updated listview->setContentY(100); model.removeItem(1); + listview->forceLayout(); QTRY_COMPARE(listview->count(), model.count()); listview->setContentY(-50); QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); @@ -4979,22 +5004,22 @@ void tst_QQuickListView::snapToItem() void tst_QQuickListView::qAbstractItemModel_package_items() { - items<QaimModel>(testFileUrl("listviewtest-package.qml"), true); + items<QaimModel>(testFileUrl("listviewtest-package.qml")); } void tst_QQuickListView::qAbstractItemModel_items() { - items<QaimModel>(testFileUrl("listviewtest.qml"), false); + items<QaimModel>(testFileUrl("listviewtest.qml")); } void tst_QQuickListView::qAbstractItemModel_package_changed() { - changed<QaimModel>(testFileUrl("listviewtest-package.qml"), true); + changed<QaimModel>(testFileUrl("listviewtest-package.qml")); } void tst_QQuickListView::qAbstractItemModel_changed() { - changed<QaimModel>(testFileUrl("listviewtest.qml"), false); + changed<QaimModel>(testFileUrl("listviewtest.qml")); } void tst_QQuickListView::qAbstractItemModel_package_inserted() @@ -5555,6 +5580,7 @@ void tst_QQuickListView::populateTransitions() // clear the model window->rootContext()->setContextProperty("testModel", QVariant()); + listview->forceLayout(); QTRY_COMPARE(listview->count(), 0); QTRY_COMPARE(findItems<QQuickItem>(contentItem, "wrapper").count(), 0); listview->setProperty("countPopulateTransitions", 0); @@ -5683,6 +5709,7 @@ void tst_QQuickListView::addTransitions() if (!newData.isEmpty()) { model.insertItems(insertionIndex, newData); QTRY_COMPARE(model.count(), listview->count()); + listview->forceLayout(); } QList<QQuickItem *> targetItems = findItems<QQuickItem>(contentItem, "wrapper", targetIndexes); @@ -6291,6 +6318,7 @@ void tst_QQuickListView::displacedTransitions() case ListChange::Polish: break; } + listview->forceLayout(); QVariantList resultTargetIndexes = listview->property("displacedTargetIndexes").toList(); QVariantList resultTargetItems = listview->property("displacedTargetItems").toList(); @@ -6539,6 +6567,7 @@ void tst_QQuickListView::multipleTransitions() break; } } + listview->forceLayout(); QCOMPARE(listview->count(), model.count()); // verify all items moved to the correct final positions @@ -6822,6 +6851,7 @@ void tst_QQuickListView::accessEmptyCurrentItem_QTBUG_30227() QQuickListView *listview = window->rootObject()->findChild<QQuickListView*>(); QTRY_VERIFY(listview != 0); + listview->forceLayout(); QMetaObject::invokeMethod(window->rootObject(), "remove"); QVERIFY(window->rootObject()->property("isCurrentItemNull").toBool()); @@ -6830,6 +6860,26 @@ void tst_QQuickListView::accessEmptyCurrentItem_QTBUG_30227() QVERIFY(!window->rootObject()->property("isCurrentItemNull").toBool()); } +void tst_QQuickListView::delayedChanges_QTBUG_30555() +{ + QQuickView *window = createView(); + window->setSource(testFileUrl("delayedChanges.qml")); + + QQuickListView *listview = window->rootObject()->findChild<QQuickListView*>(); + QTRY_VERIFY(listview != 0); + + QCOMPARE(listview->count(), 10); + + //Takes two just like in the bug report + QMetaObject::invokeMethod(window->rootObject(), "takeTwo"); + QTRY_COMPARE(listview->count(), 8); + + QMetaObject::invokeMethod(window->rootObject(), "takeTwo_sync"); + QCOMPARE(listview->count(), 6); + + delete window; +} + QTEST_MAIN(tst_QQuickListView) #include "tst_qquicklistview.moc" diff --git a/tests/auto/quick/qquickmousearea/data/hoverAfterPress.qml b/tests/auto/quick/qquickmousearea/data/hoverAfterPress.qml new file mode 100644 index 0000000000..69ec8fbd47 --- /dev/null +++ b/tests/auto/quick/qquickmousearea/data/hoverAfterPress.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 + +Item { + width: 500 + height: 500 + + Rectangle { + width: 300 + height: 300 + color: "grey" + x: 100 + y: 100 + + MouseArea { + id: mouseArea + objectName: "mouseArea" + anchors.fill: parent + hoverEnabled: true + onPressed: mouse.accepted = false + //onContainsMouseChanged: print("containsMouse changed =", containsMouse) + + Rectangle { + visible: parent.containsMouse + color: "red" + width: 10; height: 10 + } + } + } +} diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp index a959a60acf..a582c62701 100644 --- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp +++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp @@ -78,6 +78,7 @@ private slots: void hoverPosition(); void hoverPropagation(); void hoverVisible(); + void hoverAfterPress(); void disableAfterPress(); void onWheel(); void transformedMouseArea_data(); @@ -1007,6 +1008,33 @@ void tst_QQuickMouseArea::hoverVisible() delete window; } +void tst_QQuickMouseArea::hoverAfterPress() +{ + QQuickView *window = createView(); + window->setSource(testFileUrl("hoverAfterPress.qml")); + + QQuickItem *root = window->rootObject(); + QVERIFY(root != 0); + + QQuickMouseArea *mouseArea = window->rootObject()->findChild<QQuickMouseArea*>("mouseArea"); + QVERIFY(mouseArea != 0); + QTest::mouseMove(window, QPoint(22,33)); + QCOMPARE(mouseArea->hovered(), false); + QTest::mouseMove(window, QPoint(200,200)); + QCOMPARE(mouseArea->hovered(), true); + QTest::mouseMove(window, QPoint(22,33)); + QCOMPARE(mouseArea->hovered(), false); + QTest::mouseMove(window, QPoint(200,200)); + QCOMPARE(mouseArea->hovered(), true); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(200,200)); + QCOMPARE(mouseArea->hovered(), true); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(200,200)); + QCOMPARE(mouseArea->hovered(), true); + QTest::mouseMove(window, QPoint(22,33)); + QCOMPARE(mouseArea->hovered(), false); + delete window; +} + void tst_QQuickMouseArea::disableAfterPress() { QQuickView *window = createView(); diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp index d1ed6dd05a..8c72be56a4 100644 --- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp +++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp @@ -3148,6 +3148,7 @@ void tst_qquicktextinput::echoMode() QCOMPARE(initial, QLatin1String("ABCDefgh")); QCOMPARE(input->echoMode(), QQuickTextInput::Normal); QCOMPARE(input->displayText(), input->text()); + const QString passwordMaskCharacter = qApp->styleHints()->passwordMaskCharacter(); //Normal ref &= ~Qt::ImhHiddenText; ref &= ~(Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText | Qt::ImhSensitiveData); @@ -3155,7 +3156,7 @@ void tst_qquicktextinput::echoMode() input->setEchoMode(QQuickTextInput::NoEcho); QCOMPARE(input->text(), initial); QCOMPARE(input->displayText(), QLatin1String("")); - QCOMPARE(input->passwordCharacter(), QLatin1String("*")); + QCOMPARE(input->passwordCharacter(), passwordMaskCharacter); //NoEcho ref |= Qt::ImhHiddenText; ref |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText | Qt::ImhSensitiveData); @@ -3165,7 +3166,7 @@ void tst_qquicktextinput::echoMode() ref |= Qt::ImhHiddenText; ref |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText | Qt::ImhSensitiveData); QCOMPARE(input->text(), initial); - QCOMPARE(input->displayText(), QLatin1String("********")); + QCOMPARE(input->displayText(), QString(8, passwordMaskCharacter.at(0))); QCOMPARE((Qt::InputMethodHints) input->inputMethodQuery(Qt::ImHints).toInt(), ref); // clearing input hints do not clear bits set by echo mode input->setInputMethodHints(Qt::ImhNone); @@ -3220,7 +3221,7 @@ void tst_qquicktextinput::passwordEchoDelay() QQuickItem *cursor = input->findChild<QQuickItem *>("cursor"); QVERIFY(cursor); - QChar fillChar = QLatin1Char('*'); + QChar fillChar = qApp->styleHints()->passwordMaskCharacter(); input->setEchoMode(QQuickTextInput::Password); QCOMPARE(input->displayText(), QString(8, fillChar)); @@ -6123,6 +6124,12 @@ void tst_qquicktextinput::keypress_inputMask_data() keys << Qt::Key_Home << "12ab"; QTest::newRow("uppercase") << QString("9999 >AA;_") << keys << QString("12 AB") << QString("12__ AB"); } + { + KeyList keys; + // inserting '12ab' + keys << Qt::Key_Right << Qt::Key_Right << "1"; + QTest::newRow("Move in mask") << QString("#0:00;*") << keys << QString(":1") << QString("**:1*"); + } } void tst_qquicktextinput::keypress_inputMask() diff --git a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp index d16bf81d88..d374d71280 100644 --- a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp +++ b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp @@ -615,6 +615,7 @@ void tst_qquickvisualdatamodel::childChanged() vdm->setRootIndex(QVariant::fromValue(model.indexFromItem(model.item(1,0)))); QCOMPARE(listview->count(), 1); + listview->forceLayout(); QQuickText *name = findItem<QQuickText>(contentItem, "display", 0); QVERIFY(name); QCOMPARE(name->text(), QString("Row 2 Child Item")); @@ -628,6 +629,7 @@ void tst_qquickvisualdatamodel::childChanged() model.item(1,0)->appendRow(new QStandardItem(QLatin1String("Row 2 Child Item 2"))); QCOMPARE(listview->count(), 2); + listview->forceLayout(); name = findItem<QQuickText>(contentItem, "display", 1); QVERIFY(name != 0); QCOMPARE(name->text(), QString("Row 2 Child Item 2")); @@ -638,6 +640,8 @@ void tst_qquickvisualdatamodel::childChanged() vdm->setRootIndex(QVariant::fromValue(QModelIndex())); QCOMPARE(listview->count(), 3); + + listview->forceLayout(); name = findItem<QQuickText>(contentItem, "display", 0); QVERIFY(name); QCOMPARE(name->text(), QString("Row 1 Item")); @@ -989,6 +993,8 @@ void tst_qquickvisualdatamodel::packagesDestroyed() QQuickItem *rightContent = rightview->contentItem(); QTRY_VERIFY(rightContent != 0); + leftview->forceLayout(); + rightview->forceLayout(); QCOMPARE(leftview->currentIndex(), 0); QCOMPARE(rightview->currentIndex(), 0); @@ -3548,6 +3554,7 @@ void tst_qquickvisualdatamodel::resolve() evaluate<void>(visualModel, setupExpression); QCOMPARE(evaluate<int>(listView, "count"), unresolvedCount); + listView->forceLayout(); evaluate<void>(visualModel, resolveExpression); QCOMPARE(evaluate<int>(listView, "count"), inItems ? visualCount : modelCount); diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp index 2d3c8f7ca7..dbf0086a3e 100644 --- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp +++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp @@ -304,6 +304,7 @@ private slots: void qmlCreation(); void clearColor(); + void grab_data(); void grab(); void multipleWindows(); @@ -929,15 +930,28 @@ void tst_qquickwindow::clearColor() QCOMPARE(window->color(), QColor(Qt::blue)); } +void tst_qquickwindow::grab_data() +{ + QTest::addColumn<bool>("visible"); + QTest::newRow("visible") << true; + QTest::newRow("invisible") << false; +} + void tst_qquickwindow::grab() { + QFETCH(bool, visible); + QQuickWindow window; window.setColor(Qt::red); window.resize(250, 250); - window.show(); - QVERIFY(QTest::qWaitForWindowExposed(&window)); + if (visible) { + window.show(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + } else { + window.create(); + } QImage content = window.grabWindow(); QCOMPARE(content.width(), window.width()); diff --git a/tests/testapplications/elements/content/Help.qml b/tests/testapplications/elements/content/Help.qml index 1e1e26e26c..cb534108b1 100644 --- a/tests/testapplications/elements/content/Help.qml +++ b/tests/testapplications/elements/content/Help.qml @@ -45,7 +45,7 @@ Item { anchors.fill: parent Text { textFormat: Text.RichText; anchors.fill: parent; anchors.margins: 5; wrapMode: Text.WordWrap - text: "<b>QtQuick 2 System Testing</b><br><br>"+ + text: "<b>Qt Quick 2 System Testing</b><br><br>"+ "Each system test qml \"application\" provides a basic visual element affected by one or more non-visual (functional) elements.<br>"+ "Simply select the element you wish to test, and follow the instructions. Use the arrow to advance the test.<br>" } diff --git a/tests/testapplications/text/textedit.qml b/tests/testapplications/text/textedit.qml index e0d7dbdde4..6546abfe91 100644 --- a/tests/testapplications/text/textedit.qml +++ b/tests/testapplications/text/textedit.qml @@ -144,7 +144,7 @@ Rectangle { "and a language runtime. "+ "A collection of C++ APIs is used to integrate these high level features with classic Qt applications."}); textmodel.append({ "name": "Links", - "value": "This is a link - <a href=\"http://doc.qt.nokia.com\">Qt Docs</a>"}); + "value": "This is a link - <a href=\"http://qt-project.org/doc\">Qt Docs</a>"}); } } ControlView { diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp index 3d816e562d..9d5cd1db15 100644 --- a/tools/qmlplugindump/main.cpp +++ b/tools/qmlplugindump/main.cpp @@ -540,7 +540,7 @@ void sigSegvHandler(int) { void printUsage(const QString &appName) { qWarning() << qPrintable(QString( - "Usage: %1 [-v] [-notrelocatable] module.uri version [module/import/path]\n" + "Usage: %1 [-v] [-[non]relocatable] module.uri version [module/import/path]\n" " %1 [-v] -path path/to/qmldir/directory [version]\n" " %1 [-v] -builtins\n" "Example: %1 Qt.labs.folderlistmodel 2.0 /home/user/dev/qt-install/imports").arg( @@ -562,7 +562,7 @@ int main(int argc, char *argv[]) #endif #ifdef QT_SIMULATOR - // Running this application would bring up the Qt Simulator (since it links QtGui), avoid that! + // Running this application would bring up the Qt Simulator (since it links Qt GUI), avoid that! QtSimulatorPrivate::SimulatorConnection::createStubInstance(); #endif @@ -591,8 +591,13 @@ int main(int argc, char *argv[]) } if (arg == QLatin1String("--notrelocatable") - || arg == QLatin1String("-notrelocatable")) { + || arg == QLatin1String("-notrelocatable") + || arg == QLatin1String("--nonrelocatable") + || arg == QLatin1String("-nonrelocatable")) { relocatable = false; + } else if (arg == QLatin1String("--relocatable") + || arg == QLatin1String("-relocatable")) { + relocatable = true; } else if (arg == QLatin1String("--path") || arg == QLatin1String("-path")) { action = Path; |