summaryrefslogtreecommitdiffstats
path: root/src/declarative
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative')
-rw-r--r--src/declarative/debugger/qdeclarativedebugservice.cpp2
-rw-r--r--src/declarative/graphicsitems/qdeclarativeanchors.cpp9
-rw-r--r--src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp62
-rw-r--r--src/declarative/graphicsitems/qdeclarativeborderimage.cpp135
-rw-r--r--src/declarative/graphicsitems/qdeclarativeevents.cpp5
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable.cpp71
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable_p_p.h1
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflipable.cpp38
-rw-r--r--src/declarative/graphicsitems/qdeclarativefocuspanel.cpp5
-rw-r--r--src/declarative/graphicsitems/qdeclarativefocusscope.cpp5
-rw-r--r--src/declarative/graphicsitems/qdeclarativegraphicswidget.cpp19
-rw-r--r--src/declarative/graphicsitems/qdeclarativegridview.cpp14
-rw-r--r--src/declarative/graphicsitems/qdeclarativegridview_p.h12
-rw-r--r--src/declarative/graphicsitems/qdeclarativeimage.cpp59
-rw-r--r--src/declarative/graphicsitems/qdeclarativeimagebase.cpp38
-rw-r--r--src/declarative/graphicsitems/qdeclarativeimagebase_p.h3
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitem.cpp98
-rw-r--r--src/declarative/graphicsitems/qdeclarativelayoutitem.cpp7
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview.cpp107
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview_p.h13
-rw-r--r--src/declarative/graphicsitems/qdeclarativeloader.cpp11
-rw-r--r--src/declarative/graphicsitems/qdeclarativemousearea.cpp21
-rw-r--r--src/declarative/graphicsitems/qdeclarativepath.cpp58
-rw-r--r--src/declarative/graphicsitems/qdeclarativepathview.cpp285
-rw-r--r--src/declarative/graphicsitems/qdeclarativepathview_p.h1
-rw-r--r--src/declarative/graphicsitems/qdeclarativepathview_p_p.h12
-rw-r--r--src/declarative/graphicsitems/qdeclarativepositioners.cpp503
-rw-r--r--src/declarative/graphicsitems/qdeclarativerectangle.cpp5
-rw-r--r--src/declarative/graphicsitems/qdeclarativerepeater.cpp31
-rw-r--r--src/declarative/graphicsitems/qdeclarativetext.cpp44
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextedit.cpp21
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput.cpp2
-rw-r--r--src/declarative/graphicsitems/qdeclarativetranslate.cpp3
-rw-r--r--src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp23
-rw-r--r--src/declarative/graphicsitems/qdeclarativevisualitemmodel_p.h1
-rw-r--r--src/declarative/qml/parser/qdeclarativejslexer.cpp8
-rw-r--r--src/declarative/qml/qdeclarativecompiledbindings.cpp2
-rw-r--r--src/declarative/qml/qdeclarativecompiler.cpp124
-rw-r--r--src/declarative/qml/qdeclarativecompiler_p.h6
-rw-r--r--src/declarative/qml/qdeclarativecomponent.cpp65
-rw-r--r--src/declarative/qml/qdeclarativecomponent.h1
-rw-r--r--src/declarative/qml/qdeclarativecomponent_p.h12
-rw-r--r--src/declarative/qml/qdeclarativecompositetypedata_p.h161
-rw-r--r--src/declarative/qml/qdeclarativecompositetypemanager.cpp776
-rw-r--r--src/declarative/qml/qdeclarativecompositetypemanager_p.h120
-rw-r--r--src/declarative/qml/qdeclarativecontext.cpp8
-rw-r--r--src/declarative/qml/qdeclarativedom.cpp35
-rw-r--r--src/declarative/qml/qdeclarativeengine.cpp13
-rw-r--r--src/declarative/qml/qdeclarativeengine_p.h4
-rw-r--r--src/declarative/qml/qdeclarativeimport.cpp157
-rw-r--r--src/declarative/qml/qdeclarativeimport_p.h37
-rw-r--r--src/declarative/qml/qdeclarativeinclude.cpp2
-rw-r--r--src/declarative/qml/qdeclarativeobjectscriptclass.cpp18
-rw-r--r--src/declarative/qml/qdeclarativeparser_p.h7
-rw-r--r--src/declarative/qml/qdeclarativeproperty.cpp1
-rw-r--r--src/declarative/qml/qdeclarativepropertycache.cpp42
-rw-r--r--src/declarative/qml/qdeclarativescriptparser.cpp217
-rw-r--r--src/declarative/qml/qdeclarativescriptparser_p.h13
-rw-r--r--src/declarative/qml/qdeclarativetypeloader.cpp1079
-rw-r--r--src/declarative/qml/qdeclarativetypeloader_p.h321
-rw-r--r--src/declarative/qml/qdeclarativevaluetypescriptclass.cpp2
-rw-r--r--src/declarative/qml/qdeclarativevmemetaobject.cpp14
-rw-r--r--src/declarative/qml/qmetaobjectbuilder.cpp4
-rw-r--r--src/declarative/qml/qml.pri5
-rw-r--r--src/declarative/util/qdeclarativeanimation.cpp60
-rw-r--r--src/declarative/util/qdeclarativeanimation_p_p.h3
-rw-r--r--src/declarative/util/qdeclarativebind.cpp15
-rw-r--r--src/declarative/util/qdeclarativeconnections.cpp7
-rw-r--r--src/declarative/util/qdeclarativelistmodel.cpp6
-rw-r--r--src/declarative/util/qdeclarativelistmodelworkeragent.cpp2
-rw-r--r--src/declarative/util/qdeclarativepixmapcache.cpp16
-rw-r--r--src/declarative/util/qdeclarativepropertychanges.cpp6
-rw-r--r--src/declarative/util/qdeclarativesmoothedanimation.cpp33
-rw-r--r--src/declarative/util/qdeclarativesmoothedanimation_p_p.h1
-rw-r--r--src/declarative/util/qdeclarativespringanimation.cpp37
-rw-r--r--src/declarative/util/qdeclarativestate.cpp17
-rw-r--r--src/declarative/util/qdeclarativestateoperations.cpp17
-rw-r--r--src/declarative/util/qdeclarativetransition.cpp6
-rw-r--r--src/declarative/util/qdeclarativetransitionmanager.cpp2
-rw-r--r--src/declarative/util/qdeclarativeview.cpp17
-rw-r--r--src/declarative/util/qdeclarativexmllistmodel.cpp7
81 files changed, 2896 insertions, 2334 deletions
diff --git a/src/declarative/debugger/qdeclarativedebugservice.cpp b/src/declarative/debugger/qdeclarativedebugservice.cpp
index dca2695..1bbfcf4 100644
--- a/src/declarative/debugger/qdeclarativedebugservice.cpp
+++ b/src/declarative/debugger/qdeclarativedebugservice.cpp
@@ -128,6 +128,8 @@ void QDeclarativeDebugServer::newConnection()
if (d->connection) {
qWarning("QDeclarativeDebugServer error: another client is already connected");
+ QTcpSocket *faultyConnection = d->tcpServer->nextPendingConnection();
+ delete faultyConnection;
return;
}
diff --git a/src/declarative/graphicsitems/qdeclarativeanchors.cpp b/src/declarative/graphicsitems/qdeclarativeanchors.cpp
index 7ac2b17..26fb97f 100644
--- a/src/declarative/graphicsitems/qdeclarativeanchors.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeanchors.cpp
@@ -148,15 +148,6 @@ static qreal adjustedPosition(QGraphicsObject *item, QDeclarativeAnchorLine::Anc
return ret;
}
-/*!
- \internal
- \class QDeclarativeAnchors
- \since 4.7
- \brief The QDeclarativeAnchors class provides a way to lay out items relative to other items.
-
- \warning Currently, only anchoring to siblings or parent is supported.
-*/
-
QDeclarativeAnchors::QDeclarativeAnchors(QObject *parent)
: QObject(*new QDeclarativeAnchorsPrivate(0), parent)
{
diff --git a/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp b/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp
index e0a2149..12a820f 100644
--- a/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp
@@ -54,44 +54,36 @@
QT_BEGIN_NAMESPACE
/*!
- \class QDeclarativeAnimatedImage
- \internal
-*/
-
-/*!
\qmlclass AnimatedImage QDeclarativeAnimatedImage
\inherits Image
\since 4.7
\ingroup basic-visual-elements
-
- The AnimatedImage element provides for playing animations stored as images containing a series of frames,
- such as GIF files.
-
+
+ The AnimatedImage element extends the features of the \l Image element, providing
+ a way to play animations stored as images containing a series of frames,
+ such as those stored in GIF files.
+
+ Information about the current frame and totla length of the animation can be
+ obtained using the \l currentFrame and \l frameCount properties. You can
+ start, pause and stop the animation by changing the values of the \l playing
+ and \l paused properties.
+
The full list of supported formats can be determined with QMovie::supportedFormats().
- \table
- \row
- \o \image animatedimageitem.gif
- \o
- \qml
- import Qt 4.7
+ \section1 Example Usage
- Rectangle {
- width: animation.width; height: animation.height + 8
+ \beginfloatleft
+ \image animatedimageitem.gif
+ \endfloat
- AnimatedImage { id: animation; source: "animation.gif" }
+ The following QML shows how to display an animated image and obtain information
+ about its state, such as the current frame and total number of frames.
+ The result is an animated image with a simple progress indicator underneath it.
- Rectangle {
- property int frames: animation.frameCount
+ \clearfloat
+ \snippet doc/src/snippets/declarative/animatedimage.qml document
- width: 4; height: 8
- x: (animation.width - width) * animation.currentFrame / frames
- y: animation.height
- color: "red"
- }
- }
- \endqml
- \endtable
+ \sa BorderImage, Image
*/
QDeclarativeAnimatedImage::QDeclarativeAnimatedImage(QDeclarativeItem *parent)
@@ -109,7 +101,8 @@ QDeclarativeAnimatedImage::~QDeclarativeAnimatedImage()
\qmlproperty bool AnimatedImage::paused
This property holds whether the animated image is paused.
- Defaults to false, and can be set to true when you want to pause.
+ By default, this property is false. Set it to true when you want to pause
+ the animation.
*/
bool QDeclarativeAnimatedImage::isPaused() const
{
@@ -133,7 +126,8 @@ void QDeclarativeAnimatedImage::setPaused(bool pause)
\qmlproperty bool AnimatedImage::playing
This property holds whether the animated image is playing.
- Defaults to true, so as to start playing immediately.
+ By defaults, this property is true, meaning that the animation
+ will start playing immediately.
*/
bool QDeclarativeAnimatedImage::isPlaying() const
{
@@ -161,9 +155,11 @@ void QDeclarativeAnimatedImage::setPlaying(bool play)
\qmlproperty int AnimatedImage::currentFrame
\qmlproperty int AnimatedImage::frameCount
- currentFrame is the frame that is currently visible. Watching when this changes can
- allow other things to animate at the same time as the image. frameCount is the number
- of frames in the animation. For some animation formats, frameCount is unknown and set to zero.
+ currentFrame is the frame that is currently visible. By monitoring this property
+ for changes, you can animate other items at the same time as the image.
+
+ frameCount is the number of frames in the animation. For some animation formats,
+ frameCount is unknown and has a value of zero.
*/
int QDeclarativeAnimatedImage::currentFrame() const
{
diff --git a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp
index e0c7fc2..c58a08d 100644
--- a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp
@@ -56,34 +56,98 @@ QT_BEGIN_NAMESPACE
\brief The BorderImage element provides an image that can be used as a border.
\inherits Item
\since 4.7
- \ingroup qm-basic-visual-elements
+ \ingroup qml-basic-visual-elements
- A BorderImage breaks an image into 9 sections, as shown below:
+ The BorderImage element is used to create borders out of images by scaling or tiling
+ parts of each image.
+
+ A BorderImage element breaks a source image, specified using the \l url property,
+ into 9 regions, as shown below:
\image declarative-scalegrid.png
- When the image is scaled:
+ When the image is scaled, regions of the source image are scaled or tiled to
+ create the displayed border image in the following way:
+
\list
- \i the corners (sections 1, 3, 7, and 9) are not scaled at all
- \i sections 2 and 8 are scaled according to \l{BorderImage::horizontalTileMode}{horizontalTileMode}
- \i sections 4 and 6 are scaled according to \l{BorderImage::verticalTileMode}{verticalTileMode}
- \i the middle (section 5) is scaled according to both \l{BorderImage::horizontalTileMode}{horizontalTileMode} and \l{BorderImage::verticalTileMode}{verticalTileMode}
+ \i The corners (regions 1, 3, 7, and 9) are not scaled at all.
+ \i Regions 2 and 8 are scaled according to
+ \l{BorderImage::horizontalTileMode}{horizontalTileMode}.
+ \i Regions 4 and 6 are scaled according to
+ \l{BorderImage::verticalTileMode}{verticalTileMode}.
+ \i The middle (region 5) is scaled according to both
+ \l{BorderImage::horizontalTileMode}{horizontalTileMode} and
+ \l{BorderImage::verticalTileMode}{verticalTileMode}.
\endlist
- Examples:
- \snippet snippets/declarative/borderimage.qml 0
+ The regions of the image are defined using the \l border property group, which
+ describes the distance from each edge of the source image to use as a border.
- \image BorderImage.png
+ \section1 Example Usage
- The \l{declarative/imageelements/borderimage}{BorderImage example} shows how a BorderImage can be used to simulate a shadow effect on a
- rectangular item.
- */
+ The following examples show the effects of the different modes on an image.
+ Guide lines are overlaid onto the image to show the different regions of the
+ image as described above.
-/*!
- \class QDeclarativeBorderImage BorderImage
- \internal
- \brief The QDeclarativeBorderImage class provides an image item that you can add to a QDeclarativeView.
-*/
+ \beginfloatleft
+ \image qml-borderimage-normal-image.png
+ \endfloat
+
+ An unscaled image is displayed using an Image element. The \l border property is
+ used to determine the parts of the image that will lie inside the unscaled corner
+ areas and the parts that will be stretched horizontally and vertically.
+
+ \snippet doc/src/snippets/declarative/borderimage/normal-image.qml normal image
+
+ \clearfloat
+ \beginfloatleft
+ \image qml-borderimage-scaled.png
+ \endfloat
+
+ A BorderImage element is used to display the image, and it is given a size that is
+ larger than the original image. Since the \l horizontalTileMode property is set to
+ \l{BorderImage::horizontalTileMode}{BorderImage.Stretch}, the parts of image in
+ regions 2 and 8 are stretched horizontally. Since the \l verticalTileMode property
+ is set to \l{BorderImage::verticalTileMode}{BorderImage.Stretch}, the parts of image
+ in regions 4 and 6 are stretched vertically.
+
+ \snippet doc/src/snippets/declarative/borderimage/borderimage-scaled.qml scaled border image
+
+ \clearfloat
+ \beginfloatleft
+ \image qml-borderimage-tiled.png
+ \endfloat
+
+ Again, a large BorderImage element is used to display the image. With the
+ \l horizontalTileMode property set to \l{BorderImage::horizontalTileMode}{BorderImage.Repeat},
+ the parts of image in regions 2 and 8 are tiled so that they fill the space at the
+ top and bottom of the element. Similarly, the \l verticalTileMode property is set to
+ \l{BorderImage::verticalTileMode}{BorderImage.Repeat}, the parts of image in regions
+ 4 and 6 are tiled so that they fill the space at the left and right of the element.
+
+ \snippet doc/src/snippets/declarative/borderimage/borderimage-tiled.qml tiled border image
+
+ \clearfloat
+ In some situations, the width of regions 2 and 8 may not be an exact multiple of the width
+ of the corresponding regions in the source image. Similarly, the height of regions 4 and 6
+ may not be an exact multiple of the height of the corresponding regions. It can be useful
+ to use \l{BorderImage::horizontalTileMode}{BorderImage.Round} instead of
+ \l{BorderImage::horizontalTileMode}{BorderImage.Repeat} in cases like these.
+
+ The \l{declarative/imageelements/borderimage}{BorderImage example} shows how a BorderImage
+ can be used to simulate a shadow effect on a rectangular item.
+
+ \section1 Quality and Performance
+
+ By default, any scaled regions of the image are rendered without smoothing to improve
+ rendering speed. Setting the \l smooth property improves rendering quality of scaled
+ regions, but may slow down rendering.
+
+ The source image may not be loaded instantaneously, depending on its original location.
+ Loading progress can be monitored with the \l progress property.
+
+ \sa Image, AnimatedImage
+ */
QDeclarativeBorderImage::QDeclarativeBorderImage(QDeclarativeItem *parent)
: QDeclarativeImageBase(*(new QDeclarativeBorderImagePrivate), parent)
@@ -99,7 +163,8 @@ QDeclarativeBorderImage::~QDeclarativeBorderImage()
/*!
\qmlproperty enumeration BorderImage::status
- This property holds the status of image loading. It can be one of:
+ This property describes the status of image loading. It can be one of:
+
\list
\o BorderImage.Null - no image has been set
\o BorderImage.Ready - the image has been loaded
@@ -127,20 +192,28 @@ QDeclarativeBorderImage::~QDeclarativeBorderImage()
the image is displayed at its natural size, this property has no visual or
performance effect.
+ By default, this property is set to false.
+
\note Generally scaling artifacts are only visible if the image is stationary on
the screen. A common pattern when animating an image is to disable smooth
- filtering at the beginning of the animation and reenable it at the conclusion.
+ filtering at the beginning of the animation and enable it at the conclusion.
*/
/*!
\qmlproperty url BorderImage::source
- BorderImage can handle any image format supported by Qt, loaded from any URL scheme supported by Qt.
+ This property holds the URL that refers to the source image.
- It can also handle .sci files, which are a QML-specific format. A .sci file uses a simple text-based format that specifies
- the borders, the image file and the tile rules.
+ BorderImage can handle any image format supported by Qt, loaded from any
+ URL scheme supported by Qt.
+
+ It can also handle .sci files, which are a QML-specific format. A .sci
+ file uses a simple text-based format that specifies the borders, the
+ image file and the tile rules.
+
+ The following .sci file sets the borders to 10 on each side for the
+ image \c picture.png:
- The following .sci file sets the borders to 10 on each side for the image \c picture.png:
\qml
border.left: 10
border.top: 10
@@ -251,17 +324,21 @@ void QDeclarativeBorderImage::load()
\qmlproperty int BorderImage::border.top
\qmlproperty int BorderImage::border.bottom
- The 4 border lines (2 horizontal and 2 vertical) break the image into 9 sections, as shown below:
+ The 4 border lines (2 horizontal and 2 vertical) break the image into 9 sections,
+ as shown below:
\image declarative-scalegrid.png
- Each border line (left, right, top, and bottom) specifies an offset in pixels from the respective side.
+ Each border line (left, right, top, and bottom) specifies an offset in pixels
+ from the respective edge of the source image. By default, each border line has
+ a value of 0.
+
+ For example, the following definition sets the bottom line 10 pixels up from
+ the bottom of the image:
- For example:
\qml
border.bottom: 10
\endqml
- sets the bottom line 10 pixels up from the bottom of the image.
The border lines can also be specified using a
\l {BorderImage::source}{.sci file}.
@@ -280,7 +357,7 @@ QDeclarativeScaleGrid *QDeclarativeBorderImage::border()
This property describes how to repeat or stretch the middle parts of the border image.
\list
- \o BorderImage.Stretch - Scale the image to fit to the available area.
+ \o BorderImage.Stretch - Scales the image to fit to the available area.
\o BorderImage.Repeat - Tile the image until there is no more space. May crop the last image.
\o BorderImage.Round - Like Repeat, but scales the images down to ensure that the last image is not cropped.
\endlist
diff --git a/src/declarative/graphicsitems/qdeclarativeevents.cpp b/src/declarative/graphicsitems/qdeclarativeevents.cpp
index 0a35a3f..dbfb3fb 100644
--- a/src/declarative/graphicsitems/qdeclarativeevents.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeevents.cpp
@@ -60,11 +60,6 @@ Item {
*/
/*!
- \internal
- \class QDeclarativeKeyEvent
-*/
-
-/*!
\qmlproperty int KeyEvent::key
This property holds the code of the key that was pressed or released.
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
index 1e862cc..d4c65ae 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
@@ -350,24 +350,34 @@ void QDeclarativeFlickablePrivate::updateBeginningEnd()
\brief The Flickable item provides a surface that can be "flicked".
\inherits Item
- Flickable places its children on a surface that can be dragged and flicked.
+ The Flickable item places its children on a surface that can be dragged
+ and flicked, causing the view onto the child items to scroll. This
+ behavior forms the basis of Items that are designed to show large numbers
+ of child items, such as \l ListView and \l GridView.
- \code
- import Qt 4.7
+ In traditional user interfaces, views can be scrolled using standard
+ controls, such as scroll bars and arrow buttons. In some situations, it
+ is also possible to drag the view directly by pressing and holding a
+ mouse button while moving the cursor. In touch-based user interfaces,
+ this dragging action is often complemented with a flicking action, where
+ scrolling continues after the user has stopped touching the view.
- Flickable {
- width: 200; height: 200
- contentWidth: image.width; contentHeight: image.height
+ Flickable does not automatically clip its contents. If it is not used as
+ a full-screen item, you should consider setting the \l{Item::}{clip} property
+ to true.
- Image { id: image; source: "bigImage.png" }
- }
- \endcode
+ \section1 Example Usage
+
+ \beginfloatright
+ \inlineimage flickable.gif
+ \endfloat
- \image flickable.gif
+ The following example shows a large
- Flickable does not automatically clip its contents. If
- it is not full-screen it is likely that \l {Item::clip}{clip} should be set
- to \c true.
+ \clearfloat
+ \snippet doc/src/snippets/declarative/flickable.qml document
+
+ \section1 Limitations
\note Due to an implementation detail, items placed inside a Flickable cannot anchor to it by
\c id. Use \c parent instead.
@@ -491,12 +501,15 @@ void QDeclarativeFlickable::setContentY(qreal pos)
/*!
\qmlproperty bool Flickable::interactive
- This property holds whether the user can interact with the Flickable. A user
- cannot drag or flick a Flickable that is not interactive.
+ This property describes whether the user can interact with the Flickable.
+ A user cannot drag or flick a Flickable that is not interactive.
+
+ By default, this property is true.
This property is useful for temporarily disabling flicking. This allows
- special interaction with Flickable's children: for example, you might want to
- freeze a flickable map while scrolling through a pop-up dialog that is a child of the Flickable.
+ special interaction with Flickable's children; for example, you might want
+ to freeze a flickable map while scrolling through a pop-up dialog that
+ is a child of the Flickable.
*/
bool QDeclarativeFlickable::isInteractive() const
{
@@ -653,6 +666,8 @@ void QDeclarativeFlickablePrivate::handleMousePressEvent(QGraphicsSceneMouseEven
timeline.clear();
hData.velocity = 0;
vData.velocity = 0;
+ hData.dragStartOffset = 0;
+ vData.dragStartOffset = 0;
lastPos = QPoint();
QDeclarativeItemPrivate::start(lastPosTime);
pressPos = event->pos();
@@ -675,7 +690,9 @@ void QDeclarativeFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent
if (q->yflick()) {
int dy = int(event->pos().y() - pressPos.y());
if (qAbs(dy) > QApplication::startDragDistance() || QDeclarativeItemPrivate::elapsed(pressTime) > 200) {
- qreal newY = dy + vData.pressPos;
+ if (!vMoved)
+ vData.dragStartOffset = dy;
+ qreal newY = dy + vData.pressPos - vData.dragStartOffset;
const qreal minY = q->minYExtent();
const qreal maxY = q->maxYExtent();
if (newY > minY)
@@ -705,7 +722,9 @@ void QDeclarativeFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent
if (q->xflick()) {
int dx = int(event->pos().x() - pressPos.x());
if (qAbs(dx) > QApplication::startDragDistance() || QDeclarativeItemPrivate::elapsed(pressTime) > 200) {
- qreal newX = dx + hData.pressPos;
+ if (!hMoved)
+ hData.dragStartOffset = dx;
+ qreal newX = dx + hData.pressPos - hData.dragStartOffset;
const qreal minX = q->minXExtent();
const qreal maxX = q->maxXExtent();
if (newX > minX)
@@ -995,12 +1014,16 @@ void QDeclarativeFlickable::geometryChanged(const QRectF &newGeometry,
bool changed = false;
if (newGeometry.width() != oldGeometry.width()) {
+ if (xflick())
+ changed = true;
if (d->hData.viewSize < 0) {
d->contentItem->setWidth(width());
emit contentWidthChanged();
}
}
if (newGeometry.height() != oldGeometry.height()) {
+ if (yflick())
+ changed = true;
if (d->vData.viewSize < 0) {
d->contentItem->setHeight(height());
emit contentHeightChanged();
@@ -1288,6 +1311,7 @@ bool QDeclarativeFlickable::sendMouseEvent(QGraphicsSceneMouseEvent *event)
if (mouseEvent.type() == QEvent::GraphicsSceneMouseRelease) {
d->clearDelayedPress();
d->stealMouse = false;
+ d->pressed = false;
}
return false;
}
@@ -1362,8 +1386,8 @@ bool QDeclarativeFlickable::isFlicking() const
\qmlproperty bool Flickable::flickingHorizontally
\qmlproperty bool Flickable::flickingVertically
- These properties hold whether the view is currently moving horizontally
- or vertically due to the user flicking the view.
+ These properties describe whether the view is currently moving horizontally,
+ vertically or in either direction, due to the user flicking the view.
*/
bool QDeclarativeFlickable::isFlickingHorizontally() const
{
@@ -1415,8 +1439,9 @@ bool QDeclarativeFlickable::isMoving() const
\qmlproperty bool Flickable::movingHorizontally
\qmlproperty bool Flickable::movingVertically
- These properties hold whether the view is currently moving horizontally
- or vertically due to the user either dragging or flicking the view.
+ These properties describe whether the view is currently moving horizontally,
+ vertically or in either direction, due to the user either dragging or
+ flicking the view.
*/
bool QDeclarativeFlickable::isMovingHorizontally() const
{
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h
index 1bde021..261b271 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h
@@ -96,6 +96,7 @@ public:
QDeclarativeTimeLineValueProxy<QDeclarativeFlickablePrivate> move;
qreal viewSize;
qreal pressPos;
+ qreal dragStartOffset;
qreal velocity;
qreal flickTarget;
QDeclarativeFlickablePrivate::Velocity smoothVelocity;
diff --git a/src/declarative/graphicsitems/qdeclarativeflipable.cpp b/src/declarative/graphicsitems/qdeclarativeflipable.cpp
index 6ce0fa6..4ecf87b 100644
--- a/src/declarative/graphicsitems/qdeclarativeflipable.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeflipable.cpp
@@ -71,41 +71,41 @@ public:
\qmlclass Flipable QDeclarativeFlipable
\since 4.7
\ingroup qml-basic-interaction-elements
-
\brief The Flipable item provides a surface that can be flipped.
\inherits Item
Flipable is an item that can be visibly "flipped" between its front and
- back sides. It is used together with \l Rotation and \l {State}/\l {Transition} to
- produce a flipping effect.
+ back sides, like a card. It is used together with \l Rotation, \l State
+ and \l Transition elements to produce a flipping effect.
+
+ The \l front and \l back properties are used to hold the items that are
+ shown respectively on the front and back sides of the flipable item.
- Here is a Flipable that flips whenever it is clicked:
+ \section1 Example Usage
- \snippet doc/src/snippets/declarative/flipable.qml 0
+ \beginfloatright
+ \inlineimage flipable.gif
+ \endfloat
- \image flipable.gif
+ The following example shows a Flipable item that flips whenever it is
+ clicked, rotating about the y-axis.
The \l Rotation element is used to specify the angle and axis of the flip.
- When \c flipped is \c true, the item changes to the "back" state, where
+ When \c flipped is true, the item changes to the "back" state, where
the angle is changed to 180 degrees to produce the flipping effect.
- Finally, the \l Transition creates the animation that changes the
- angle over one second: when the item changes between its "back" and
+
+ \clearfloat
+ \snippet doc/src/snippets/declarative/flipable/flipable-snippet.qml 0
+
+ The \l Transition creates the animation that changes the angle over the
+ duration of one second. When the item changes between its "back" and
default states, the NumberAnimation animates the angle between
its old and new values.
See the \l {QML States} and \l {QML Animation} documentation for more
details on state changes and how animations work within transitions.
-
- \sa {declarative/ui-components/flipable}{Flipable example}
-*/
-/*!
- \internal
- \class QDeclarativeFlipable
- \brief The Flipable item provides a surface that can be flipped.
-
- Flipable is an item that can be visibly "flipped" between its front and
- back sides.
+ \sa {declarative/ui-components/flipable}{Flipable example}
*/
QDeclarativeFlipable::QDeclarativeFlipable(QDeclarativeItem *parent)
diff --git a/src/declarative/graphicsitems/qdeclarativefocuspanel.cpp b/src/declarative/graphicsitems/qdeclarativefocuspanel.cpp
index 5c7959a..f345a14 100644
--- a/src/declarative/graphicsitems/qdeclarativefocuspanel.cpp
+++ b/src/declarative/graphicsitems/qdeclarativefocuspanel.cpp
@@ -61,11 +61,6 @@ QT_BEGIN_NAMESPACE
\l {qmlfocus}{keyboard focus documentation}.
*/
-/*!
- \internal
- \class QDeclarativeFocusPanel
-*/
-
QDeclarativeFocusPanel::QDeclarativeFocusPanel(QDeclarativeItem *parent) :
QDeclarativeItem(parent)
{
diff --git a/src/declarative/graphicsitems/qdeclarativefocusscope.cpp b/src/declarative/graphicsitems/qdeclarativefocusscope.cpp
index 4498275..da97a46 100644
--- a/src/declarative/graphicsitems/qdeclarativefocusscope.cpp
+++ b/src/declarative/graphicsitems/qdeclarativefocusscope.cpp
@@ -60,11 +60,6 @@ QT_BEGIN_NAMESPACE
\sa {declarative/keyinteraction/focus}{Keyboard focus example}
*/
-/*!
- \internal
- \class QDeclarativeFocusScope
-*/
-
QDeclarativeFocusScope::QDeclarativeFocusScope(QDeclarativeItem *parent) :
QDeclarativeItem(parent)
{
diff --git a/src/declarative/graphicsitems/qdeclarativegraphicswidget.cpp b/src/declarative/graphicsitems/qdeclarativegraphicswidget.cpp
index ee45406..d45fe83 100644
--- a/src/declarative/graphicsitems/qdeclarativegraphicswidget.cpp
+++ b/src/declarative/graphicsitems/qdeclarativegraphicswidget.cpp
@@ -68,7 +68,6 @@ QDeclarativeGraphicsWidget::~QDeclarativeGraphicsWidget()
delete d->_anchors; d->_anchors = 0;
}
-/*! \internal */
QDeclarativeAnchors *QDeclarativeGraphicsWidget::anchors()
{
Q_D(QDeclarativeGraphicsWidget);
@@ -85,54 +84,36 @@ QDeclarativeItemPrivate::AnchorLines *QDeclarativeGraphicsWidgetPrivate::anchorL
return _anchorLines;
}
-/*!
- \internal
-*/
QDeclarativeAnchorLine QDeclarativeGraphicsWidget::left() const
{
Q_D(const QDeclarativeGraphicsWidget);
return d->anchorLines()->left;
}
-/*!
- \internal
-*/
QDeclarativeAnchorLine QDeclarativeGraphicsWidget::right() const
{
Q_D(const QDeclarativeGraphicsWidget);
return d->anchorLines()->right;
}
-/*!
- \internal
-*/
QDeclarativeAnchorLine QDeclarativeGraphicsWidget::horizontalCenter() const
{
Q_D(const QDeclarativeGraphicsWidget);
return d->anchorLines()->hCenter;
}
-/*!
- \internal
-*/
QDeclarativeAnchorLine QDeclarativeGraphicsWidget::top() const
{
Q_D(const QDeclarativeGraphicsWidget);
return d->anchorLines()->top;
}
-/*!
- \internal
-*/
QDeclarativeAnchorLine QDeclarativeGraphicsWidget::bottom() const
{
Q_D(const QDeclarativeGraphicsWidget);
return d->anchorLines()->bottom;
}
-/*!
- \internal
-*/
QDeclarativeAnchorLine QDeclarativeGraphicsWidget::verticalCenter() const
{
Q_D(const QDeclarativeGraphicsWidget);
diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp
index d67e69a..a0faf14 100644
--- a/src/declarative/graphicsitems/qdeclarativegridview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp
@@ -64,7 +64,7 @@ public:
FxGridItem(QDeclarativeItem *i, QDeclarativeGridView *v) : item(i), view(v) {
attached = static_cast<QDeclarativeGridViewAttached*>(qmlAttachedPropertiesObject<QDeclarativeGridView>(item));
if (attached)
- attached->m_view = view;
+ attached->setView(view);
}
~FxGridItem() {}
@@ -2212,7 +2212,7 @@ void QDeclarativeGridView::trackedPositionChanged()
if (trackedPos < d->startPosition() + d->highlightRangeStart) {
pos = d->startPosition();
} else if (d->trackedItem->endRowPos() > d->endPosition() - d->size() + d->highlightRangeEnd) {
- pos = d->endPosition() - d->size();
+ pos = d->endPosition() - d->size() + 1;
if (pos < d->startPosition())
pos = d->startPosition();
} else {
@@ -2226,14 +2226,14 @@ void QDeclarativeGridView::trackedPositionChanged()
} else {
if (trackedPos < viewPos && d->currentItem->rowPos() < viewPos) {
pos = d->currentItem->rowPos() < trackedPos ? trackedPos : d->currentItem->rowPos();
- } else if (d->trackedItem->endRowPos() > viewPos + d->size()
- && d->currentItem->endRowPos() > viewPos + d->size()) {
- if (d->trackedItem->endRowPos() < d->currentItem->endRowPos()) {
- pos = d->trackedItem->endRowPos() - d->size();
+ } else if (d->trackedItem->endRowPos() >= viewPos + d->size()
+ && d->currentItem->endRowPos() >= viewPos + d->size()) {
+ if (d->trackedItem->endRowPos() <= d->currentItem->endRowPos()) {
+ pos = d->trackedItem->endRowPos() - d->size() + 1;
if (d->rowSize() > d->size())
pos = trackedPos;
} else {
- pos = d->currentItem->endRowPos() - d->size();
+ pos = d->currentItem->endRowPos() - d->size() + 1;
if (d->rowSize() > d->size())
pos = d->currentItem->rowPos();
}
diff --git a/src/declarative/graphicsitems/qdeclarativegridview_p.h b/src/declarative/graphicsitems/qdeclarativegridview_p.h
index d6bbaf3..ee632b1 100644
--- a/src/declarative/graphicsitems/qdeclarativegridview_p.h
+++ b/src/declarative/graphicsitems/qdeclarativegridview_p.h
@@ -43,6 +43,7 @@
#define QDECLARATIVEGRIDVIEW_H
#include "private/qdeclarativeflickable_p.h"
+#include "private/qdeclarativeguard_p.h"
QT_BEGIN_HEADER
@@ -220,8 +221,14 @@ public:
: QObject(parent), m_view(0), m_isCurrent(false), m_delayRemove(false) {}
~QDeclarativeGridViewAttached() {}
- Q_PROPERTY(QDeclarativeGridView *view READ view CONSTANT)
+ Q_PROPERTY(QDeclarativeGridView *view READ view NOTIFY viewChanged)
QDeclarativeGridView *view() { return m_view; }
+ void setView(QDeclarativeGridView *view) {
+ if (view != m_view) {
+ m_view = view;
+ emit viewChanged();
+ }
+ }
Q_PROPERTY(bool isCurrentItem READ isCurrentItem NOTIFY currentItemChanged)
bool isCurrentItem() const { return m_isCurrent; }
@@ -249,9 +256,10 @@ Q_SIGNALS:
void delayRemoveChanged();
void add();
void remove();
+ void viewChanged();
public:
- QDeclarativeGridView *m_view;
+ QDeclarativeGuard<QDeclarativeGridView> m_view;
bool m_isCurrent : 1;
bool m_delayRemove : 1;
};
diff --git a/src/declarative/graphicsitems/qdeclarativeimage.cpp b/src/declarative/graphicsitems/qdeclarativeimage.cpp
index 1cc5f81..9cd9ad6 100644
--- a/src/declarative/graphicsitems/qdeclarativeimage.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeimage.cpp
@@ -51,34 +51,46 @@ QT_BEGIN_NAMESPACE
/*!
\qmlclass Image QDeclarativeImage
\since 4.7
- \ingroup qml-vasic-visual-elements
-
- \brief The Image element allows you to add bitmaps to a scene.
+ \ingroup qml-basic-visual-elements
+ \brief The Image element displays an image in a declarative user interface
\inherits Item
- An Image element displays a specified \l source image:
+ The Image element is used to display images in a declarative user interface.
- \table
- \row
- \o \image declarative-qtlogo.png
- \o \qml
- import Qt 4.7
+ The source of the image is specified as a URL using the \l source property.
+ Images can be supplied in any of the standard image formats supported by Qt,
+ including bitmap formats such as PNG and JPEG, and vector graphics formats
+ such as SVG. If you need to display animated images, use the \l AnimatedImage
+ element.
- Image { source: "qtlogo.png" }
- \endqml
- \endtable
+ If the \l{Item::width}{width} and \l{Item::height}{height} properties are not
+ specified, the Image element automatically uses the size of the loaded image.
+ By default, specifying the width and height of the element causes the image
+ to be scaled to that size. This behavior can be changed by setting the
+ \l fillMode property, allowing the image to be stretched and tiled instead.
+
+ \section1 Example Usage
+
+ The following example shows the simplest usage of the Image element.
+
+ \snippet doc/src/snippets/declarative/image.qml document
+
+ \beginfloatleft
+ \image declarative-qtlogo.png
+ \endfloat
- If the \l {Item::width}{width} and \l{Item::height}{height} properties are not specified,
- the Image element is automatically sized to the loaded image. Image elements can be
- stretched and tiled using the \l fillMode property.
+ \clearfloat
+
+ \section1 Performance
By default, locally available images are loaded immediately, and the user interface
is blocked until loading is complete. If a large image is to be loaded, it may be
preferable to load the image in a low priority thread, by enabling the \l asynchronous
property.
- If the image is from a network rather than a local resource, it is automatically loaded
- asynchronously, and the \l progress and \l status properties are updated as appropriate.
+ If the image is obtained from a network rather than a local resource, it is
+ automatically loaded asynchronously, and the \l progress and \l status properties
+ are updated as appropriate.
Images are cached and shared internally, so if several Image elements have the same \l source,
only one copy of the image will be loaded.
@@ -91,19 +103,6 @@ QT_BEGIN_NAMESPACE
\sa {declarative/imageelements/image}{Image example}, QDeclarativeImageProvider
*/
-/*!
- \internal
- \class QDeclarativeImage Image
- \brief The QDeclarativeImage class provides an image item that you can add to a QDeclarativeView.
-
- Example:
- \qml
- Image { source: "pics/star.png" }
- \endqml
-
- A QDeclarativeImage object can be instantiated in QML using the tag \l Image.
-*/
-
QDeclarativeImage::QDeclarativeImage(QDeclarativeItem *parent)
: QDeclarativeImageBase(*(new QDeclarativeImagePrivate), parent)
{
diff --git a/src/declarative/graphicsitems/qdeclarativeimagebase.cpp b/src/declarative/graphicsitems/qdeclarativeimagebase.cpp
index d6b935b..02b4807 100644
--- a/src/declarative/graphicsitems/qdeclarativeimagebase.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeimagebase.cpp
@@ -50,13 +50,6 @@
QT_BEGIN_NAMESPACE
-
-/*!
- \class QDeclarativeImageBase
- \internal
- \brief The base class for declarative images.
- */
-
QDeclarativeImageBase::QDeclarativeImageBase(QDeclarativeImageBasePrivate &dd, QDeclarativeItem *parent)
: QDeclarativeItem(dd, parent)
{
@@ -136,30 +129,25 @@ QSize QDeclarativeImageBase::sourceSize() const
void QDeclarativeImageBase::load()
{
Q_D(QDeclarativeImageBase);
- if (d->progress != 0.0) {
- d->progress = 0.0;
- emit progressChanged(d->progress);
- }
if (d->url.isEmpty()) {
d->pix.clear();
d->status = Null;
+ d->progress = 0.0;
setImplicitWidth(0);
setImplicitHeight(0);
+ emit progressChanged(d->progress);
emit statusChanged(d->status);
- d->sourcesize.setWidth(0);
- d->sourcesize.setHeight(0);
- emit sourceSizeChanged();
pixmapChange();
update();
} else {
-
- d->status = Loading;
- emit statusChanged(d->status);
-
d->pix.load(qmlEngine(this), d->url, d->sourcesize, d->async);
if (d->pix.isLoading()) {
+ d->progress = 0.0;
+ d->status = Loading;
+ emit progressChanged(d->progress);
+ emit statusChanged(d->status);
static int thisRequestProgress = -1;
static int thisRequestFinished = -1;
@@ -183,25 +171,31 @@ void QDeclarativeImageBase::requestFinished()
{
Q_D(QDeclarativeImageBase);
+ QDeclarativeImageBase::Status oldStatus = d->status;
+ qreal oldProgress = d->progress;
+
if (d->pix.isError()) {
d->status = Error;
qmlInfo(this) << d->pix.error();
} else {
d->status = Ready;
}
- emit statusChanged(d->status);
+
+ d->progress = 1.0;
setImplicitWidth(d->pix.width());
setImplicitHeight(d->pix.height());
- d->progress = 1.0;
- emit progressChanged(d->progress);
-
if (d->sourcesize.width() != d->pix.width() || d->sourcesize.height() != d->pix.height()) {
d->sourcesize.setWidth(d->pix.width());
d->sourcesize.setHeight(d->pix.height());
emit sourceSizeChanged();
}
+
+ if (d->status != oldStatus)
+ emit statusChanged(d->status);
+ if (d->progress != oldProgress)
+ emit progressChanged(d->progress);
pixmapChange();
update();
}
diff --git a/src/declarative/graphicsitems/qdeclarativeimagebase_p.h b/src/declarative/graphicsitems/qdeclarativeimagebase_p.h
index f5896b1..68eb8d0 100644
--- a/src/declarative/graphicsitems/qdeclarativeimagebase_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeimagebase_p.h
@@ -58,7 +58,6 @@ class Q_AUTOTEST_EXPORT QDeclarativeImageBase : public QDeclarativeItem
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged)
Q_PROPERTY(bool asynchronous READ asynchronous WRITE setAsynchronous NOTIFY asynchronousChanged)
-
Q_PROPERTY(QSize sourceSize READ sourceSize WRITE setSourceSize NOTIFY sourceSizeChanged)
public:
@@ -79,7 +78,7 @@ public:
Q_SIGNALS:
void sourceChanged(const QUrl &);
void sourceSizeChanged();
- void statusChanged(Status);
+ void statusChanged(QDeclarativeImageBase::Status);
void progressChanged(qreal progress);
void asynchronousChanged();
diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp
index 0f16a79..11f9179 100644
--- a/src/declarative/graphicsitems/qdeclarativeitem.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp
@@ -229,12 +229,6 @@ QT_BEGIN_NAMESPACE
The angle to rotate, in degrees clockwise.
*/
-/*!
- \internal
- \class QDeclarativeContents
- \brief The QDeclarativeContents class gives access to the height and width of an item's contents.
-
-*/
QDeclarativeContents::QDeclarativeContents(QDeclarativeItem *item) : m_item(item), m_x(0), m_y(0), m_width(0), m_height(0)
{
//### optimize
@@ -836,259 +830,259 @@ void QDeclarativeKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post)
*/
/*!
- \qmlsignal Keys::onPressed(event)
+ \qmlsignal Keys::onPressed(KeyEvent event)
This handler is called when a key has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onReleased(event)
+ \qmlsignal Keys::onReleased(KeyEvent event)
This handler is called when a key has been released. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onDigit0Pressed(event)
+ \qmlsignal Keys::onDigit0Pressed(KeyEvent event)
This handler is called when the digit '0' has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onDigit1Pressed(event)
+ \qmlsignal Keys::onDigit1Pressed(KeyEvent event)
This handler is called when the digit '1' has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onDigit2Pressed(event)
+ \qmlsignal Keys::onDigit2Pressed(KeyEvent event)
This handler is called when the digit '2' has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onDigit3Pressed(event)
+ \qmlsignal Keys::onDigit3Pressed(KeyEvent event)
This handler is called when the digit '3' has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onDigit4Pressed(event)
+ \qmlsignal Keys::onDigit4Pressed(KeyEvent event)
This handler is called when the digit '4' has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onDigit5Pressed(event)
+ \qmlsignal Keys::onDigit5Pressed(KeyEvent event)
This handler is called when the digit '5' has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onDigit6Pressed(event)
+ \qmlsignal Keys::onDigit6Pressed(KeyEvent event)
This handler is called when the digit '6' has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onDigit7Pressed(event)
+ \qmlsignal Keys::onDigit7Pressed(KeyEvent event)
This handler is called when the digit '7' has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onDigit8Pressed(event)
+ \qmlsignal Keys::onDigit8Pressed(KeyEvent event)
This handler is called when the digit '8' has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onDigit9Pressed(event)
+ \qmlsignal Keys::onDigit9Pressed(KeyEvent event)
This handler is called when the digit '9' has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onLeftPressed(event)
+ \qmlsignal Keys::onLeftPressed(KeyEvent event)
This handler is called when the Left arrow has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onRightPressed(event)
+ \qmlsignal Keys::onRightPressed(KeyEvent event)
This handler is called when the Right arrow has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onUpPressed(event)
+ \qmlsignal Keys::onUpPressed(KeyEvent event)
This handler is called when the Up arrow has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onDownPressed(event)
+ \qmlsignal Keys::onDownPressed(KeyEvent event)
This handler is called when the Down arrow has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onAsteriskPressed(event)
+ \qmlsignal Keys::onAsteriskPressed(KeyEvent event)
This handler is called when the Asterisk '*' has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onEscapePressed(event)
+ \qmlsignal Keys::onEscapePressed(KeyEvent event)
This handler is called when the Escape key has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onReturnPressed(event)
+ \qmlsignal Keys::onReturnPressed(KeyEvent event)
This handler is called when the Return key has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onEnterPressed(event)
+ \qmlsignal Keys::onEnterPressed(KeyEvent event)
This handler is called when the Enter key has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onDeletePressed(event)
+ \qmlsignal Keys::onDeletePressed(KeyEvent event)
This handler is called when the Delete key has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onSpacePressed(event)
+ \qmlsignal Keys::onSpacePressed(KeyEvent event)
This handler is called when the Space key has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onBackPressed(event)
+ \qmlsignal Keys::onBackPressed(KeyEvent event)
This handler is called when the Back key has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onCancelPressed(event)
+ \qmlsignal Keys::onCancelPressed(KeyEvent event)
This handler is called when the Cancel key has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onSelectPressed(event)
+ \qmlsignal Keys::onSelectPressed(KeyEvent event)
This handler is called when the Select key has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onYesPressed(event)
+ \qmlsignal Keys::onYesPressed(KeyEvent event)
This handler is called when the Yes key has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onNoPressed(event)
+ \qmlsignal Keys::onNoPressed(KeyEvent event)
This handler is called when the No key has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onContext1Pressed(event)
+ \qmlsignal Keys::onContext1Pressed(KeyEvent event)
This handler is called when the Context1 key has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onContext2Pressed(event)
+ \qmlsignal Keys::onContext2Pressed(KeyEvent event)
This handler is called when the Context2 key has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onContext3Pressed(event)
+ \qmlsignal Keys::onContext3Pressed(KeyEvent event)
This handler is called when the Context3 key has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onContext4Pressed(event)
+ \qmlsignal Keys::onContext4Pressed(KeyEvent event)
This handler is called when the Context4 key has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onCallPressed(event)
+ \qmlsignal Keys::onCallPressed(KeyEvent event)
This handler is called when the Call key has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onHangupPressed(event)
+ \qmlsignal Keys::onHangupPressed(KeyEvent event)
This handler is called when the Hangup key has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onFlipPressed(event)
+ \qmlsignal Keys::onFlipPressed(KeyEvent event)
This handler is called when the Flip key has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onMenuPressed(event)
+ \qmlsignal Keys::onMenuPressed(KeyEvent event)
This handler is called when the Menu key has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onVolumeUpPressed(event)
+ \qmlsignal Keys::onVolumeUpPressed(KeyEvent event)
This handler is called when the VolumeUp key has been pressed. The \a event
parameter provides information about the event.
*/
/*!
- \qmlsignal Keys::onVolumeDownPressed(event)
+ \qmlsignal Keys::onVolumeDownPressed(KeyEvent event)
This handler is called when the VolumeDown key has been pressed. The \a event
parameter provides information about the event.
@@ -1728,7 +1722,6 @@ void QDeclarativeItemPrivate::parentProperty(QObject *o, void *rv, QDeclarativeN
specify it.
*/
-/*! \internal */
QDeclarativeListProperty<QObject> QDeclarativeItemPrivate::data()
{
return QDeclarativeListProperty<QObject>(q_func(), 0, QDeclarativeItemPrivate::data_append);
@@ -1890,6 +1883,12 @@ void QDeclarativeItem::geometryChanged(const QRectF &newGeometry,
}
}
+ for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
+ const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
+ if (change.types & QDeclarativeItemPrivate::Geometry)
+ change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
+ }
+
if (newGeometry.x() != oldGeometry.x())
emit xChanged();
if (newGeometry.width() != oldGeometry.width())
@@ -1898,12 +1897,6 @@ void QDeclarativeItem::geometryChanged(const QRectF &newGeometry,
emit yChanged();
if (newGeometry.height() != oldGeometry.height())
emit heightChanged();
-
- for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
- const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
- if (change.types & QDeclarativeItemPrivate::Geometry)
- change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
- }
}
void QDeclarativeItemPrivate::removeItemChangeListener(QDeclarativeItemChangeListener *listener, ChangeTypes types)
@@ -2416,7 +2409,6 @@ void QDeclarativeItemPrivate::focusChanged(bool flag)
emit q->focusChanged(flag);
}
-/*! \internal */
QDeclarativeListProperty<QObject> QDeclarativeItemPrivate::resources()
{
return QDeclarativeListProperty<QObject>(q_func(), 0, QDeclarativeItemPrivate::resources_append,
@@ -2441,7 +2433,6 @@ QDeclarativeListProperty<QObject> QDeclarativeItemPrivate::resources()
\sa {qmlstate}{States}
*/
-/*! \internal */
QDeclarativeListProperty<QDeclarativeState> QDeclarativeItemPrivate::states()
{
return _states()->statesProperty();
@@ -2465,7 +2456,6 @@ QDeclarativeListProperty<QDeclarativeState> QDeclarativeItemPrivate::states()
*/
-/*! \internal */
QDeclarativeListProperty<QDeclarativeTransition> QDeclarativeItemPrivate::transitions()
{
return _states()->transitionsProperty();
@@ -2538,7 +2528,6 @@ QDeclarativeListProperty<QDeclarativeTransition> QDeclarativeItemPrivate::transi
\sa {qmlstates}{States}
*/
-/*! \internal */
QString QDeclarativeItemPrivate::state() const
{
if (!_stateGroup)
@@ -2547,7 +2536,6 @@ QString QDeclarativeItemPrivate::state() const
return _stateGroup->state();
}
-/*! \internal */
void QDeclarativeItemPrivate::setState(const QString &state)
{
_states()->setState(state);
diff --git a/src/declarative/graphicsitems/qdeclarativelayoutitem.cpp b/src/declarative/graphicsitems/qdeclarativelayoutitem.cpp
index 8509473..d71b2c5 100644
--- a/src/declarative/graphicsitems/qdeclarativelayoutitem.cpp
+++ b/src/declarative/graphicsitems/qdeclarativelayoutitem.cpp
@@ -66,13 +66,6 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \internal
- \class QDeclarativeLayoutItem
- \brief The QDeclarativeLayoutItem class allows you to place your QML UI elements inside Qt's Graphics View layouts.
-*/
-
-
-/*!
\qmlproperty QSizeF LayoutItem::maximumSize
The maximumSize property can be set to specify the maximum desired size of this LayoutItem
diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp
index 2e2e08c..177c5b3 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp
@@ -96,7 +96,7 @@ public:
FxListItem(QDeclarativeItem *i, QDeclarativeListView *v) : item(i), section(0), view(v) {
attached = static_cast<QDeclarativeListViewAttached*>(qmlAttachedPropertiesObject<QDeclarativeListView>(item));
if (attached)
- attached->m_view = view;
+ attached->setView(view);
}
~FxListItem() {}
qreal position() const {
@@ -105,12 +105,23 @@ public:
else
return (view->orientation() == QDeclarativeListView::Vertical ? item->y() : item->x());
}
+ qreal itemPosition() const {
+ return (view->orientation() == QDeclarativeListView::Vertical ? item->y() : item->x());
+ }
qreal size() const {
if (section)
- return (view->orientation() == QDeclarativeListView::Vertical ? item->height()+section->height() : item->width()+section->height());
+ return (view->orientation() == QDeclarativeListView::Vertical ? item->height()+section->height() : item->width()+section->width());
else
return (view->orientation() == QDeclarativeListView::Vertical ? item->height() : item->width());
}
+ qreal itemSize() const {
+ return (view->orientation() == QDeclarativeListView::Vertical ? item->height() : item->width());
+ }
+ qreal sectionSize() const {
+ if (section)
+ return (view->orientation() == QDeclarativeListView::Vertical ? section->height() : section->width());
+ return 0.0;
+ }
qreal endPosition() const {
return (view->orientation() == QDeclarativeListView::Vertical
? item->y() + (item->height() > 0 ? item->height() : 1)
@@ -131,6 +142,12 @@ public:
item->setX(pos);
}
}
+ void setSize(qreal size) {
+ if (view->orientation() == QDeclarativeListView::Vertical)
+ item->setHeight(size);
+ else
+ item->setWidth(size);
+ }
bool contains(int x, int y) const {
return (x >= item->x() && x < item->x() + item->width() &&
y >= item->y() && y < item->y() + item->height());
@@ -256,7 +273,12 @@ public:
if (!visibleItems.isEmpty()) {
if (modelIndex < visibleIndex) {
int count = visibleIndex - modelIndex;
- return (*visibleItems.constBegin())->position() - count * (averageSize + spacing);
+ qreal cs = 0;
+ if (modelIndex == currentIndex && currentItem) {
+ cs = currentItem->size() + spacing;
+ --count;
+ }
+ return (*visibleItems.constBegin())->position() - count * (averageSize + spacing) - cs;
} else {
int idx = visibleItems.count() - 1;
while (idx >= 0 && visibleItems.at(idx)->index == -1)
@@ -716,6 +738,11 @@ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer)
if (visibleItems.count())
visiblePos = (*visibleItems.constBegin())->position();
updateAverage();
+ if (currentIndex >= 0 && currentItem && !visibleItem(currentIndex)) {
+ currentItem->setPosition(positionAt(currentIndex));
+ updateHighlight();
+ }
+
if (sectionCriteria)
updateCurrentSection();
if (header)
@@ -885,8 +912,8 @@ void QDeclarativeListViewPrivate::updateHighlight()
createHighlight();
if (currentItem && autoHighlight && highlight && !movingHorizontally && !movingVertically) {
// auto-update highlight
- highlightPosAnimator->to = currentItem->position();
- highlightSizeAnimator->to = currentItem->size();
+ highlightPosAnimator->to = currentItem->itemPosition();
+ highlightSizeAnimator->to = currentItem->itemSize();
if (orient == QDeclarativeListView::Vertical) {
if (highlight->item->width() == 0)
highlight->item->setWidth(currentItem->item->width());
@@ -987,7 +1014,7 @@ void QDeclarativeListViewPrivate::updateCurrentSection()
return;
}
int index = 0;
- while (visibleItems.at(index)->endPosition() < position() && index < visibleItems.count())
+ while (index < visibleItems.count() && visibleItems.at(index)->endPosition() < position())
++index;
if (index < visibleItems.count())
@@ -1172,9 +1199,9 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m
}
if (currentItem && haveHighlightRange && highlightRange == QDeclarativeListView::StrictlyEnforceRange) {
updateHighlight();
- qreal currPos = currentItem->position();
- if (pos < currPos + currentItem->size() - highlightRangeEnd)
- pos = currPos + currentItem->size() - highlightRangeEnd;
+ qreal currPos = currentItem->itemPosition();
+ if (pos < currPos + currentItem->itemSize() - highlightRangeEnd)
+ pos = currPos + currentItem->itemSize() - highlightRangeEnd;
if (pos > currPos - highlightRangeStart)
pos = currPos - highlightRangeStart;
}
@@ -1191,10 +1218,10 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m
} else if (haveHighlightRange && highlightRange == QDeclarativeListView::StrictlyEnforceRange) {
if (currentItem) {
updateHighlight();
- qreal pos = currentItem->position();
+ qreal pos = currentItem->itemPosition();
qreal viewPos = position();
- if (viewPos < pos + currentItem->size() - highlightRangeEnd)
- viewPos = pos + currentItem->size() - highlightRangeEnd;
+ if (viewPos < pos + currentItem->itemSize() - highlightRangeEnd)
+ viewPos = pos + currentItem->itemSize() - highlightRangeEnd;
if (viewPos > pos - highlightRangeStart)
viewPos = pos - highlightRangeStart;
@@ -1405,7 +1432,7 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m
to set \e {clip: true} in order to have the out of view items clipped
nicely.
- \sa {Data Models}, GridView, {declarative/modelviews/listview}{ListView examples}
+ \sa {QML Data Models}, GridView, {declarative/modelviews/listview}{ListView examples}
*/
QDeclarativeListView::QDeclarativeListView(QDeclarativeItem *parent)
@@ -2342,6 +2369,10 @@ qreal QDeclarativeListView::minYExtent() const
d->minExtent += d->header->size();
if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
d->minExtent += d->highlightRangeStart;
+ if (d->sectionCriteria) {
+ if (d->visibleItem(0))
+ d->minExtent -= d->visibleItem(0)->sectionSize();
+ }
d->minExtent = qMax(d->minExtent, -(d->endPositionAt(0) - d->highlightRangeEnd + 1));
}
d->minExtentDirty = false;
@@ -2454,6 +2485,16 @@ void QDeclarativeListView::keyPressEvent(QKeyEvent *event)
QDeclarativeFlickable::keyPressEvent(event);
}
+void QDeclarativeListView::geometryChanged(const QRectF &newGeometry,
+ const QRectF &oldGeometry)
+{
+ Q_D(QDeclarativeListView);
+ d->maxExtentDirty = true;
+ d->minExtentDirty = true;
+ QDeclarativeFlickable::geometryChanged(newGeometry, oldGeometry);
+}
+
+
/*!
\qmlmethod ListView::incrementCurrentIndex()
@@ -2579,6 +2620,11 @@ void QDeclarativeListView::positionViewAtIndex(int index, int mode)
d->moveReason = QDeclarativeListViewPrivate::Other;
cancelFlick();
d->setPosition(pos);
+ if (d->highlight) {
+ d->highlight->setPosition(d->currentItem->itemPosition());
+ d->highlight->setSize(d->currentItem->itemSize());
+ d->updateHighlight();
+ }
}
d->fixupPosition();
}
@@ -2639,7 +2685,12 @@ void QDeclarativeListView::trackedPositionChanged()
if (!d->trackedItem || !d->currentItem)
return;
if (d->moveReason == QDeclarativeListViewPrivate::SetIndex) {
- const qreal trackedPos = qCeil(d->trackedItem->position());
+ qreal trackedPos = qCeil(d->trackedItem->position());
+ qreal trackedSize = d->trackedItem->size();
+ if (d->trackedItem != d->currentItem) {
+ trackedPos -= d->currentItem->sectionSize();
+ trackedSize += d->currentItem->sectionSize();
+ }
const qreal viewPos = d->position();
qreal pos = viewPos;
if (d->haveHighlightRange) {
@@ -2652,28 +2703,28 @@ void QDeclarativeListView::trackedPositionChanged()
if (trackedPos < d->startPosition() + d->highlightRangeStart) {
pos = d->startPosition();
} else if (d->trackedItem->endPosition() > d->endPosition() - d->size() + d->highlightRangeEnd) {
- pos = d->endPosition() - d->size();
+ pos = d->endPosition() - d->size() + 1;
if (pos < d->startPosition())
pos = d->startPosition();
} else {
if (trackedPos < viewPos + d->highlightRangeStart) {
pos = trackedPos - d->highlightRangeStart;
- } else if (trackedPos > viewPos + d->highlightRangeEnd - d->trackedItem->size()) {
- pos = trackedPos - d->highlightRangeEnd + d->trackedItem->size();
+ } else if (trackedPos > viewPos + d->highlightRangeEnd - trackedSize) {
+ pos = trackedPos - d->highlightRangeEnd + trackedSize;
}
}
}
} else {
if (trackedPos < viewPos && d->currentItem->position() < viewPos) {
pos = d->currentItem->position() < trackedPos ? trackedPos : d->currentItem->position();
- } else if (d->trackedItem->endPosition() > viewPos + d->size()
- && d->currentItem->endPosition() > viewPos + d->size()) {
- if (d->trackedItem->endPosition() < d->currentItem->endPosition()) {
- pos = d->trackedItem->endPosition() - d->size();
- if (d->trackedItem->size() > d->size())
+ } else if (d->trackedItem->endPosition() >= viewPos + d->size()
+ && d->currentItem->endPosition() >= viewPos + d->size()) {
+ if (d->trackedItem->endPosition() <= d->currentItem->endPosition()) {
+ pos = d->trackedItem->endPosition() - d->size() + 1;
+ if (trackedSize > d->size())
pos = trackedPos;
} else {
- pos = d->currentItem->endPosition() - d->size();
+ pos = d->currentItem->endPosition() - d->size() + 1;
if (d->currentItem->size() > d->size())
pos = d->currentItem->position();
}
@@ -2906,14 +2957,18 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count)
}
if (removedVisible && d->visibleItems.isEmpty()) {
- d->visibleIndex = 0;
- d->visiblePos = d->header ? d->header->size() : 0;
d->timeline.clear();
- d->setPosition(0);
if (d->itemCount == 0) {
+ d->visibleIndex = 0;
+ d->visiblePos = d->header ? d->header->size() : 0;
+ d->setPosition(0);
d->updateHeader();
d->updateFooter();
update();
+ } else {
+ if (modelIndex < d->visibleIndex)
+ d->visibleIndex = modelIndex+1;
+ d->visibleIndex = qMax(qMin(d->visibleIndex, d->itemCount-1), 0);
}
}
diff --git a/src/declarative/graphicsitems/qdeclarativelistview_p.h b/src/declarative/graphicsitems/qdeclarativelistview_p.h
index b264861..735b248 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview_p.h
+++ b/src/declarative/graphicsitems/qdeclarativelistview_p.h
@@ -43,6 +43,7 @@
#define QDECLARATIVELISTVIEW_H
#include "private/qdeclarativeflickable_p.h"
+#include "private/qdeclarativeguard_p.h"
QT_BEGIN_HEADER
@@ -245,6 +246,7 @@ protected:
virtual qreal minXExtent() const;
virtual qreal maxXExtent() const;
virtual void keyPressEvent(QKeyEvent *);
+ virtual void geometryChanged(const QRectF &newGeometry,const QRectF &oldGeometry);
virtual void componentComplete();
private Q_SLOTS:
@@ -268,8 +270,14 @@ public:
: QObject(parent), m_view(0), m_isCurrent(false), m_delayRemove(false) {}
~QDeclarativeListViewAttached() {}
- Q_PROPERTY(QDeclarativeListView *view READ view CONSTANT)
+ Q_PROPERTY(QDeclarativeListView *view READ view NOTIFY viewChanged)
QDeclarativeListView *view() { return m_view; }
+ void setView(QDeclarativeListView *view) {
+ if (view != m_view) {
+ m_view = view;
+ emit viewChanged();
+ }
+ }
Q_PROPERTY(bool isCurrentItem READ isCurrentItem NOTIFY currentItemChanged)
bool isCurrentItem() const { return m_isCurrent; }
@@ -327,9 +335,10 @@ Q_SIGNALS:
void delayRemoveChanged();
void add();
void remove();
+ void viewChanged();
public:
- QDeclarativeListView *m_view;
+ QDeclarativeGuard<QDeclarativeListView> m_view;
mutable QString m_section;
QString m_prevSection;
QString m_nextSection;
diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp
index 2fde4c8..5d71625 100644
--- a/src/declarative/graphicsitems/qdeclarativeloader.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp
@@ -189,14 +189,6 @@ void QDeclarativeLoaderPrivate::initResize()
\sa {dynamic-object-creation}{Dynamic Object Creation}
*/
-/*!
- \internal
- \class QDeclarativeLoader
- */
-
-/*!
- Create a new QDeclarativeLoader instance.
- */
QDeclarativeLoader::QDeclarativeLoader(QDeclarativeItem *parent)
: QDeclarativeItem(*(new QDeclarativeLoaderPrivate), parent)
{
@@ -204,9 +196,6 @@ QDeclarativeLoader::QDeclarativeLoader(QDeclarativeItem *parent)
d->flags |= QGraphicsItem::ItemIsFocusScope;
}
-/*!
- Destroy the loader instance.
- */
QDeclarativeLoader::~QDeclarativeLoader()
{
Q_D(QDeclarativeLoader);
diff --git a/src/declarative/graphicsitems/qdeclarativemousearea.cpp b/src/declarative/graphicsitems/qdeclarativemousearea.cpp
index 2823888..5516611 100644
--- a/src/declarative/graphicsitems/qdeclarativemousearea.cpp
+++ b/src/declarative/graphicsitems/qdeclarativemousearea.cpp
@@ -250,7 +250,7 @@ QDeclarativeMouseAreaPrivate::~QDeclarativeMouseAreaPrivate()
*/
/*!
- \qmlsignal MouseArea::onClicked(mouse)
+ \qmlsignal MouseArea::onClicked(MouseEvent mouse)
This handler is called when there is a click. A click is defined as a press followed by a release,
both inside the MouseArea (pressing, moving outside the MouseArea, and then moving back inside and
@@ -263,7 +263,7 @@ QDeclarativeMouseAreaPrivate::~QDeclarativeMouseAreaPrivate()
*/
/*!
- \qmlsignal MouseArea::onPressed(mouse)
+ \qmlsignal MouseArea::onPressed(MouseEvent mouse)
This handler is called when there is a press.
The \l {MouseEvent}{mouse} parameter provides information about the press, including the x and y
@@ -277,7 +277,7 @@ QDeclarativeMouseAreaPrivate::~QDeclarativeMouseAreaPrivate()
*/
/*!
- \qmlsignal MouseArea::onReleased(mouse)
+ \qmlsignal MouseArea::onReleased(MouseEvent mouse)
This handler is called when there is a release.
The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y
@@ -287,7 +287,7 @@ QDeclarativeMouseAreaPrivate::~QDeclarativeMouseAreaPrivate()
*/
/*!
- \qmlsignal MouseArea::onPressAndHold(mouse)
+ \qmlsignal MouseArea::onPressAndHold(MouseEvent mouse)
This handler is called when there is a long press (currently 800ms).
The \l {MouseEvent}{mouse} parameter provides information about the press, including the x and y
@@ -297,7 +297,7 @@ QDeclarativeMouseAreaPrivate::~QDeclarativeMouseAreaPrivate()
*/
/*!
- \qmlsignal MouseArea::onDoubleClicked(mouse)
+ \qmlsignal MouseArea::onDoubleClicked(MouseEvent mouse)
This handler is called when there is a double-click (a press followed by a release followed by a press).
The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y
@@ -317,16 +317,6 @@ QDeclarativeMouseAreaPrivate::~QDeclarativeMouseAreaPrivate()
\l Flickable, \c onCanceled should be used in addition to onReleased.
*/
-/*!
- \internal
- \class QDeclarativeMouseArea
- \brief The QDeclarativeMouseArea class provides a simple mouse handling abstraction for use within QML.
-
- All QDeclarativeItem derived classes can do mouse handling but the QDeclarativeMouseArea class exposes mouse
- handling data as properties and tracks flicking and dragging of the mouse.
-
- A QDeclarativeMouseArea object can be instantiated in QML using the tag \l MouseArea.
- */
QDeclarativeMouseArea::QDeclarativeMouseArea(QDeclarativeItem *parent)
: QDeclarativeItem(*(new QDeclarativeMouseAreaPrivate), parent)
{
@@ -690,7 +680,6 @@ void QDeclarativeMouseArea::geometryChanged(const QRectF &newGeometry,
d->lastPos = mapFromScene(d->lastScenePos);
}
-/*! \internal */
QVariant QDeclarativeMouseArea::itemChange(GraphicsItemChange change,
const QVariant &value)
{
diff --git a/src/declarative/graphicsitems/qdeclarativepath.cpp b/src/declarative/graphicsitems/qdeclarativepath.cpp
index 0c069ce..f93357d 100644
--- a/src/declarative/graphicsitems/qdeclarativepath.cpp
+++ b/src/declarative/graphicsitems/qdeclarativepath.cpp
@@ -62,11 +62,6 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \internal
- \class QDeclarativePathElement
-*/
-
-/*!
\qmlclass Path QDeclarativePath
\ingroup qml-view-elements
\since 4.7
@@ -83,13 +78,6 @@ QT_BEGIN_NAMESPACE
\sa PathView, PathAttribute, PathPercent, PathLine, PathQuad, PathCubic
*/
-
-/*!
- \internal
- \class QDeclarativePath
- \brief The QDeclarativePath class defines a path.
- \sa QDeclarativePathView
-*/
QDeclarativePath::QDeclarativePath(QObject *parent)
: QObject(*(new QDeclarativePathPrivate), parent)
{
@@ -527,15 +515,6 @@ void QDeclarativeCurve::setY(qreal y)
*/
/*!
- \internal
- \class QDeclarativePathAttribute
- \brief The QDeclarativePathAttribute class allows to set the value of an attribute at a given position in the path.
-
- \sa QDeclarativePath
-*/
-
-
-/*!
\qmlproperty string PathAttribute::name
the name of the attribute to change.
@@ -608,14 +587,6 @@ void QDeclarativePathAttribute::setValue(qreal value)
*/
/*!
- \internal
- \class QDeclarativePathLine
- \brief The QDeclarativePathLine class defines a straight line.
-
- \sa QDeclarativePath
-*/
-
-/*!
\qmlproperty real PathLine::x
\qmlproperty real PathLine::y
@@ -652,15 +623,6 @@ void QDeclarativePathLine::addToPath(QPainterPath &path)
*/
/*!
- \internal
- \class QDeclarativePathQuad
- \brief The QDeclarativePathQuad class defines a quadratic Bezier curve with a control point.
-
- \sa QDeclarativePath
-*/
-
-
-/*!
\qmlproperty real PathQuad::x
\qmlproperty real PathQuad::y
@@ -743,14 +705,6 @@ void QDeclarativePathQuad::addToPath(QPainterPath &path)
*/
/*!
- \internal
- \class QDeclarativePathCubic
- \brief The QDeclarativePathCubic class defines a cubic Bezier curve with two control points.
-
- \sa QDeclarativePath
-*/
-
-/*!
\qmlproperty real PathCubic::x
\qmlproperty real PathCubic::y
@@ -872,18 +826,6 @@ void QDeclarativePathCubic::addToPath(QPainterPath &path)
\sa Path
*/
-/*!
- \internal
- \class QDeclarativePathPercent
- \brief The QDeclarativePathPercent class manipulates the way a path is interpreted.
-
- QDeclarativePathPercent allows you to bunch up items (or spread out items) along various
- segments of a QDeclarativePathView's path.
-
- \sa QDeclarativePath
-
-*/
-
qreal QDeclarativePathPercent::value() const
{
return _value;
diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp
index 4b97505..de3f9fa 100644
--- a/src/declarative/graphicsitems/qdeclarativepathview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp
@@ -67,7 +67,7 @@ inline qreal qmlMod(qreal x, qreal y)
static QDeclarativeOpenMetaObjectType *qPathViewAttachedType = 0;
QDeclarativePathViewAttached::QDeclarativePathViewAttached(QObject *parent)
-: QObject(parent), m_view(0), m_onPath(false), m_isCurrent(false)
+: QObject(parent), m_percent(-1), m_view(0), m_onPath(false), m_isCurrent(false)
{
if (qPathViewAttachedType) {
m_metaobject = new QDeclarativeOpenMetaObject(this, qPathViewAttachedType);
@@ -164,8 +164,8 @@ void QDeclarativePathViewPrivate::clear()
void QDeclarativePathViewPrivate::updateMappedRange()
{
- if (model && pathItems != -1 && pathItems < model->count())
- mappedRange = qreal(pathItems)/model->count();
+ if (model && pathItems != -1 && pathItems < modelCount)
+ mappedRange = qreal(pathItems)/modelCount;
else
mappedRange = 1.0;
}
@@ -174,13 +174,13 @@ qreal QDeclarativePathViewPrivate::positionOfIndex(qreal index) const
{
qreal pos = -1.0;
- if (model && index >= 0 && index < model->count()) {
+ if (model && index >= 0 && index < modelCount) {
qreal start = 0.0;
if (haveHighlightRange && highlightRangeMode != QDeclarativePathView::NoHighlightRange)
start = highlightRangeStart;
qreal globalPos = index + offset;
- globalPos = qmlMod(globalPos, qreal(model->count())) / model->count();
- if (pathItems != -1 && pathItems < model->count()) {
+ globalPos = qmlMod(globalPos, qreal(modelCount)) / modelCount;
+ if (pathItems != -1 && pathItems < modelCount) {
globalPos += start * mappedRange;
globalPos = qmlMod(globalPos, 1.0);
if (globalPos < mappedRange)
@@ -242,21 +242,22 @@ void QDeclarativePathViewPrivate::updateHighlight()
} else {
qreal target = currentIndex;
+ offsetAdj = 0.0;
tl.reset(moveHighlight);
moveHighlight.setValue(highlightPosition);
const int duration = highlightMoveDuration;
- if (target - highlightPosition > model->count()/2) {
+ if (target - highlightPosition > modelCount/2) {
highlightUp = false;
- qreal distance = model->count() - target + highlightPosition;
+ qreal distance = modelCount - target + highlightPosition;
tl.move(moveHighlight, 0.0, QEasingCurve(QEasingCurve::InQuad), int(duration * highlightPosition / distance));
- tl.set(moveHighlight, model->count()-0.01);
- tl.move(moveHighlight, target, QEasingCurve(QEasingCurve::OutQuad), int(duration * (model->count()-target) / distance));
- } else if (target - highlightPosition <= -model->count()/2) {
+ tl.set(moveHighlight, modelCount-0.01);
+ tl.move(moveHighlight, target, QEasingCurve(QEasingCurve::OutQuad), int(duration * (modelCount-target) / distance));
+ } else if (target - highlightPosition <= -modelCount/2) {
highlightUp = true;
- qreal distance = model->count() - highlightPosition + target;
- tl.move(moveHighlight, model->count()-0.01, QEasingCurve(QEasingCurve::InQuad), int(duration * (model->count()-highlightPosition) / distance));
+ qreal distance = modelCount - highlightPosition + target;
+ tl.move(moveHighlight, modelCount-0.01, QEasingCurve(QEasingCurve::InQuad), int(duration * (modelCount-highlightPosition) / distance));
tl.set(moveHighlight, 0.0);
tl.move(moveHighlight, target, QEasingCurve(QEasingCurve::OutQuad), int(duration * target / distance));
} else {
@@ -277,7 +278,7 @@ void QDeclarativePathViewPrivate::setHighlightPosition(qreal pos)
end = highlightRangeEnd;
}
- qreal range = qreal(model->count());
+ qreal range = qreal(modelCount);
// calc normalized position of highlight relative to offset
qreal relativeHighlight = qmlMod(pos + offset, range) / range;
@@ -300,6 +301,9 @@ void QDeclarativePathViewPrivate::setHighlightPosition(qreal pos)
void QDeclarativePathViewPrivate::updateItem(QDeclarativeItem *item, qreal percent)
{
if (QDeclarativePathViewAttached *att = attached(item)) {
+ if (qFuzzyCompare(att->m_percent, percent))
+ return;
+ att->m_percent = percent;
foreach(const QString &attr, path->attributes())
att->setValue(attr.toUtf8(), path->attributeAt(attr, percent));
}
@@ -473,17 +477,19 @@ void QDeclarativePathView::setModel(const QVariant &model)
if (QDeclarativeVisualDataModel *dataModel = qobject_cast<QDeclarativeVisualDataModel*>(d->model))
dataModel->setModel(model);
}
+ d->modelCount = 0;
if (d->model) {
connect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
connect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int)));
connect(d->model, SIGNAL(itemsMoved(int,int,int)), this, SLOT(itemsMoved(int,int,int)));
connect(d->model, SIGNAL(modelReset()), this, SLOT(modelReset()));
connect(d->model, SIGNAL(createdItem(int, QDeclarativeItem*)), this, SLOT(createdItem(int,QDeclarativeItem*)));
- }
- if (d->model->count())
- d->offset = qmlMod(d->offset, qreal(d->model->count()));
- if (d->offset < 0)
- d->offset = d->model->count() + d->offset;
+ d->modelCount = d->model->count();
+ if (d->model->count())
+ d->offset = qmlMod(d->offset, qreal(d->model->count()));
+ if (d->offset < 0)
+ d->offset = d->model->count() + d->offset;
+}
d->regenerate();
d->fixOffset();
emit countChanged();
@@ -497,7 +503,7 @@ void QDeclarativePathView::setModel(const QVariant &model)
int QDeclarativePathView::count() const
{
Q_D(const QDeclarativePathView);
- return d->model ? d->model->count() : 0;
+ return d->model ? d->modelCount : 0;
}
/*!
@@ -545,11 +551,11 @@ int QDeclarativePathView::currentIndex() const
void QDeclarativePathView::setCurrentIndex(int idx)
{
Q_D(QDeclarativePathView);
- if (d->model && d->model->count())
- idx = qAbs(idx % d->model->count());
+ if (d->model && d->modelCount)
+ idx = qAbs(idx % d->modelCount);
if (d->model && idx != d->currentIndex) {
- if (d->model->count()) {
- int itemIndex = (d->currentIndex - d->firstIndex + d->model->count()) % d->model->count();
+ if (d->modelCount) {
+ int itemIndex = (d->currentIndex - d->firstIndex + d->modelCount) % d->modelCount;
if (itemIndex < d->items.count()) {
if (QDeclarativeItem *item = d->items.at(itemIndex)) {
if (QDeclarativePathViewAttached *att = d->attached(item))
@@ -560,10 +566,10 @@ void QDeclarativePathView::setCurrentIndex(int idx)
d->currentItem = 0;
d->moveReason = QDeclarativePathViewPrivate::SetIndex;
d->currentIndex = idx;
- if (d->model->count()) {
+ if (d->modelCount) {
if (d->haveHighlightRange && d->highlightRangeMode == QDeclarativePathView::StrictlyEnforceRange)
d->snapToCurrent();
- int itemIndex = (idx - d->firstIndex + d->model->count()) % d->model->count();
+ int itemIndex = (idx - d->firstIndex + d->modelCount) % d->modelCount;
if (itemIndex < d->items.count()) {
d->currentItem = d->items.at(itemIndex);
d->currentItem->setFocus(true);
@@ -600,10 +606,10 @@ void QDeclarativePathView::incrementCurrentIndex()
void QDeclarativePathView::decrementCurrentIndex()
{
Q_D(QDeclarativePathView);
- if (d->model && d->model->count()) {
+ if (d->model && d->modelCount) {
int idx = currentIndex()-1;
if (idx < 0)
- idx = d->model->count() - 1;
+ idx = d->modelCount - 1;
setCurrentIndex(idx);
}
}
@@ -632,9 +638,9 @@ void QDeclarativePathViewPrivate::setOffset(qreal o)
Q_Q(QDeclarativePathView);
if (offset != o) {
if (isValid() && q->isComponentComplete()) {
- offset = qmlMod(o, qreal(model->count()));
+ offset = qmlMod(o, qreal(modelCount));
if (offset < 0)
- offset += qreal(model->count());
+ offset += qreal(modelCount);
q->refill();
} else {
offset = o;
@@ -643,6 +649,11 @@ void QDeclarativePathViewPrivate::setOffset(qreal o)
}
}
+void QDeclarativePathViewPrivate::setAdjustedOffset(qreal o)
+{
+ setOffset(o+offsetAdj);
+}
+
/*!
\qmlproperty Component PathView::highlight
This property holds the component to use as the highlight.
@@ -705,6 +716,8 @@ QDeclarativeItem *QDeclarativePathView::highlightItem()
These properties set the preferred range of the highlight (current item)
within the view. The preferred values must be in the range 0.0-1.0.
+ If highlightRangeMode is set to \e PathView.NoHighlightRange
+
If highlightRangeMode is set to \e PathView.ApplyRange the view will
attempt to maintain the highlight within the range, however
the highlight can move outside of the range at the ends of the path
@@ -1071,14 +1084,14 @@ void QDeclarativePathView::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
d->moveReason = QDeclarativePathViewPrivate::Mouse;
qreal newPc;
d->pointNear(event->pos(), &newPc);
- qreal diff = (newPc - d->startPc)*d->model->count()*d->mappedRange;
+ qreal diff = (newPc - d->startPc)*d->modelCount*d->mappedRange;
if (diff) {
setOffset(d->offset + diff);
- if (diff > d->model->count()/2)
- diff -= d->model->count();
- else if (diff < -d->model->count()/2)
- diff += d->model->count();
+ if (diff > d->modelCount/2)
+ diff -= d->modelCount;
+ else if (diff < -d->modelCount/2)
+ diff += d->modelCount;
d->lastElapsed = QDeclarativeItemPrivate::restart(d->lastPosTime);
d->lastDist = diff;
@@ -1102,15 +1115,15 @@ void QDeclarativePathView::mouseReleaseEvent(QGraphicsSceneMouseEvent *)
qreal elapsed = qreal(d->lastElapsed + QDeclarativeItemPrivate::elapsed(d->lastPosTime)) / 1000.;
qreal velocity = elapsed > 0. ? d->lastDist / elapsed : 0;
- if (d->model && d->model->count() && qAbs(velocity) > 1.) {
- qreal count = d->pathItems == -1 ? d->model->count() : d->pathItems;
+ if (d->model && d->modelCount && qAbs(velocity) > 1.) {
+ qreal count = d->pathItems == -1 ? d->modelCount : d->pathItems;
if (qAbs(velocity) > count * 2) // limit velocity
velocity = (velocity > 0 ? count : -count) * 2;
// Calculate the distance to be travelled
qreal v2 = velocity*velocity;
qreal accel = d->deceleration/10;
// + 0.25 to encourage moving at least one item in the flick direction
- qreal dist = qMin(qreal(d->model->count()-1), qreal(v2 / (accel * 2.0) + 0.25));
+ qreal dist = qMin(qreal(d->modelCount-1), qreal(v2 / (accel * 2.0) + 0.25));
if (d->haveHighlightRange && d->highlightRangeMode == QDeclarativePathView::StrictlyEnforceRange) {
// round to nearest item.
if (velocity > 0.)
@@ -1125,6 +1138,7 @@ void QDeclarativePathView::mouseReleaseEvent(QGraphicsSceneMouseEvent *)
accel = v2 / (2.0f * qAbs(dist));
}
}
+ d->offsetAdj = 0.0;
d->moveOffset.setValue(d->offset);
d->tl.accel(d->moveOffset, velocity, accel, dist);
d->tl.callback(QDeclarativeTimeLineCallback(&d->moveOffset, d->fixOffsetCallback, d));
@@ -1260,79 +1274,81 @@ void QDeclarativePathView::refill()
d->updateItem(item, 1.0);
d->releaseItem(item);
if (it == d->items.begin()) {
- if (++d->firstIndex >= d->model->count())
+ if (++d->firstIndex >= d->modelCount)
d->firstIndex = 0;
}
it = d->items.erase(it);
}
++idx;
- if (idx >= d->model->count())
+ if (idx >= d->modelCount)
idx = 0;
}
- // add items to beginning and end
- int count = d->pathItems == -1 ? d->model->count() : qMin(d->pathItems, d->model->count());
- if (d->items.count() < count) {
- int idx = qRound(d->model->count() - d->offset) % d->model->count();
- qreal startPos = 0.0;
- if (d->haveHighlightRange && d->highlightRangeMode != QDeclarativePathView::NoHighlightRange)
- startPos = d->highlightRangeStart;
- if (d->firstIndex >= 0) {
- startPos = d->positionOfIndex(d->firstIndex);
- idx = (d->firstIndex + d->items.count()) % d->model->count();
- }
- qreal pos = d->positionOfIndex(idx);
- while ((pos > startPos || !d->items.count()) && d->items.count() < count) {
-// qDebug() << "append" << idx;
- QDeclarativeItem *item = d->getItem(idx);
- if (d->model->completePending())
- item->setZValue(idx+1);
- if (d->currentIndex == idx) {
- item->setFocus(true);
- if (QDeclarativePathViewAttached *att = d->attached(item))
- att->setIsCurrentItem(true);
- currentVisible = true;
- d->currentItemOffset = pos;
- d->currentItem = item;
+ if (d->modelCount) {
+ // add items to beginning and end
+ int count = d->pathItems == -1 ? d->modelCount : qMin(d->pathItems, d->modelCount);
+ if (d->items.count() < count) {
+ int idx = qRound(d->modelCount - d->offset) % d->modelCount;
+ qreal startPos = 0.0;
+ if (d->haveHighlightRange && d->highlightRangeMode != QDeclarativePathView::NoHighlightRange)
+ startPos = d->highlightRangeStart;
+ if (d->firstIndex >= 0) {
+ startPos = d->positionOfIndex(d->firstIndex);
+ idx = (d->firstIndex + d->items.count()) % d->modelCount;
}
- if (d->items.count() == 0)
- d->firstIndex = idx;
- d->items.append(item);
- d->updateItem(item, pos);
- if (d->model->completePending())
- d->model->completeItem();
- ++idx;
- if (idx >= d->model->count())
- idx = 0;
- pos = d->positionOfIndex(idx);
- }
-
- idx = d->firstIndex - 1;
- if (idx < 0)
- idx = d->model->count() - 1;
- pos = d->positionOfIndex(idx);
- while (pos >= 0.0 && pos < startPos) {
-// qDebug() << "prepend" << idx;
- QDeclarativeItem *item = d->getItem(idx);
- if (d->model->completePending())
- item->setZValue(idx+1);
- if (d->currentIndex == idx) {
- item->setFocus(true);
- if (QDeclarativePathViewAttached *att = d->attached(item))
- att->setIsCurrentItem(true);
- currentVisible = true;
- d->currentItemOffset = pos;
- d->currentItem = item;
+ qreal pos = d->positionOfIndex(idx);
+ while ((pos > startPos || !d->items.count()) && d->items.count() < count) {
+ // qDebug() << "append" << idx;
+ QDeclarativeItem *item = d->getItem(idx);
+ if (d->model->completePending())
+ item->setZValue(idx+1);
+ if (d->currentIndex == idx) {
+ item->setFocus(true);
+ if (QDeclarativePathViewAttached *att = d->attached(item))
+ att->setIsCurrentItem(true);
+ currentVisible = true;
+ d->currentItemOffset = pos;
+ d->currentItem = item;
+ }
+ if (d->items.count() == 0)
+ d->firstIndex = idx;
+ d->items.append(item);
+ d->updateItem(item, pos);
+ if (d->model->completePending())
+ d->model->completeItem();
+ ++idx;
+ if (idx >= d->modelCount)
+ idx = 0;
+ pos = d->positionOfIndex(idx);
}
- d->items.prepend(item);
- d->updateItem(item, pos);
- if (d->model->completePending())
- d->model->completeItem();
- d->firstIndex = idx;
+
idx = d->firstIndex - 1;
if (idx < 0)
- idx = d->model->count() - 1;
+ idx = d->modelCount - 1;
pos = d->positionOfIndex(idx);
+ while (pos >= 0.0 && pos < startPos) {
+ // qDebug() << "prepend" << idx;
+ QDeclarativeItem *item = d->getItem(idx);
+ if (d->model->completePending())
+ item->setZValue(idx+1);
+ if (d->currentIndex == idx) {
+ item->setFocus(true);
+ if (QDeclarativePathViewAttached *att = d->attached(item))
+ att->setIsCurrentItem(true);
+ currentVisible = true;
+ d->currentItemOffset = pos;
+ d->currentItem = item;
+ }
+ d->items.prepend(item);
+ d->updateItem(item, pos);
+ if (d->model->completePending())
+ d->model->completeItem();
+ d->firstIndex = idx;
+ idx = d->firstIndex - 1;
+ if (idx < 0)
+ idx = d->modelCount - 1;
+ pos = d->positionOfIndex(idx);
+ }
}
}
@@ -1348,6 +1364,8 @@ void QDeclarativePathView::refill()
if (QDeclarativePathViewAttached *att = d->attached(d->highlightItem))
att->setOnPath(currentVisible);
}
+ while (d->itemCache.count())
+ d->releaseItem(d->itemCache.takeLast());
}
void QDeclarativePathView::itemsInserted(int modelIndex, int count)
@@ -1357,16 +1375,25 @@ void QDeclarativePathView::itemsInserted(int modelIndex, int count)
if (!d->isValid() || !isComponentComplete())
return;
- QList<QDeclarativeItem *> removedItems = d->items;
+ d->itemCache += d->items;
d->items.clear();
if (modelIndex <= d->currentIndex) {
d->currentIndex += count;
emit currentIndexChanged();
+ } else if (d->offset != 0) {
+ d->offset += count;
+ d->offsetAdj += count;
+ }
+
+ d->modelCount = d->model->count();
+ if (d->flicking || d->moving) {
+ d->regenerate();
+ d->updateCurrent();
+ } else {
+ d->firstIndex = -1;
+ d->updateMappedRange();
+ d->scheduleLayout();
}
- d->regenerate();
- while (removedItems.count())
- d->releaseItem(removedItems.takeLast());
- d->updateCurrent();
emit countChanged();
}
@@ -1374,7 +1401,7 @@ void QDeclarativePathView::itemsRemoved(int modelIndex, int count)
{
//XXX support animated removal
Q_D(QDeclarativePathView);
- if (!d->isValid() || !isComponentComplete())
+ if (!d->model || !d->modelCount || !d->model->isValid() || !d->path || !isComponentComplete())
return;
// fix current
@@ -1384,7 +1411,7 @@ void QDeclarativePathView::itemsRemoved(int modelIndex, int count)
currentChanged = true;
} else if (d->currentIndex >= modelIndex && d->currentIndex < modelIndex + count) {
// current item has been removed.
- d->currentIndex = qMin(modelIndex, d->model->count()-1);
+ d->currentIndex = qMin(modelIndex, d->modelCount-1);
if (d->currentItem) {
if (QDeclarativePathViewAttached *att = d->attached(d->currentItem))
att->setIsCurrentItem(true);
@@ -1392,15 +1419,21 @@ void QDeclarativePathView::itemsRemoved(int modelIndex, int count)
currentChanged = true;
}
- QList<QDeclarativeItem *> removedItems = d->items;
+ d->itemCache += d->items;
d->items.clear();
- if (d->offset >= d->model->count())
- d->offset = d->model->count() - 1;
+ if (modelIndex > d->currentIndex) {
+ if (d->offset >= count) {
+ d->offset -= count;
+ d->offsetAdj -= count;
+ }
+ }
+
+ d->modelCount = d->model->count();
d->regenerate();
- while (removedItems.count())
- d->releaseItem(removedItems.takeLast());
d->updateCurrent();
+ if (!d->modelCount)
+ update();
if (currentChanged)
emit currentIndexChanged();
emit countChanged();
@@ -1431,6 +1464,7 @@ void QDeclarativePathView::itemsMoved(int /*from*/, int /*to*/, int /*count*/)
void QDeclarativePathView::modelReset()
{
Q_D(QDeclarativePathView);
+ d->modelCount = d->model->count();
d->regenerate();
emit countChanged();
}
@@ -1488,11 +1522,11 @@ int QDeclarativePathViewPrivate::calcCurrentIndex()
{
int current = -1;
if (model && items.count()) {
- offset = qmlMod(offset, model->count());
+ offset = qmlMod(offset, modelCount);
if (offset < 0)
- offset += model->count();
- current = qRound(qAbs(qmlMod(model->count() - offset, model->count())));
- current = current % model->count();
+ offset += modelCount;
+ current = qRound(qAbs(qmlMod(modelCount - offset, modelCount)));
+ current = current % modelCount;
}
return current;
@@ -1508,7 +1542,7 @@ void QDeclarativePathViewPrivate::updateCurrent()
int idx = calcCurrentIndex();
if (model && idx != currentIndex) {
- int itemIndex = (currentIndex - firstIndex + model->count()) % model->count();
+ int itemIndex = (currentIndex - firstIndex + modelCount) % modelCount;
if (itemIndex < items.count()) {
if (QDeclarativeItem *item = items.at(itemIndex)) {
if (QDeclarativePathViewAttached *att = attached(item))
@@ -1517,7 +1551,7 @@ void QDeclarativePathViewPrivate::updateCurrent()
}
currentIndex = idx;
currentItem = 0;
- itemIndex = (idx - firstIndex + model->count()) % model->count();
+ itemIndex = (idx - firstIndex + modelCount) % modelCount;
if (itemIndex < items.count()) {
currentItem = items.at(itemIndex);
currentItem->setFocus(true);
@@ -1549,25 +1583,26 @@ void QDeclarativePathViewPrivate::fixOffset()
void QDeclarativePathViewPrivate::snapToCurrent()
{
- if (!model || model->count() <= 0)
+ if (!model || modelCount <= 0)
return;
- qreal targetOffset = model->count() - currentIndex;
+ qreal targetOffset = modelCount - currentIndex;
moveReason = Other;
+ offsetAdj = 0.0;
tl.reset(moveOffset);
moveOffset.setValue(offset);
const int duration = highlightMoveDuration;
- if (targetOffset - offset > model->count()/2) {
- qreal distance = model->count() - targetOffset + offset;
+ if (targetOffset - offset > modelCount/2) {
+ qreal distance = modelCount - targetOffset + offset;
tl.move(moveOffset, 0.0, QEasingCurve(QEasingCurve::InQuad), int(duration * offset / distance));
- tl.set(moveOffset, model->count());
- tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::OutQuad), int(duration * (model->count()-targetOffset) / distance));
- } else if (targetOffset - offset <= -model->count()/2) {
- qreal distance = model->count() - offset + targetOffset;
- tl.move(moveOffset, model->count(), QEasingCurve(QEasingCurve::InQuad), int(duration * (model->count()-offset) / distance));
+ tl.set(moveOffset, modelCount);
+ tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::OutQuad), int(duration * (modelCount-targetOffset) / distance));
+ } else if (targetOffset - offset <= -modelCount/2) {
+ qreal distance = modelCount - offset + targetOffset;
+ tl.move(moveOffset, modelCount, QEasingCurve(QEasingCurve::InQuad), int(duration * (modelCount-offset) / distance));
tl.set(moveOffset, 0.0);
tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::OutQuad), int(duration * targetOffset / distance));
} else {
diff --git a/src/declarative/graphicsitems/qdeclarativepathview_p.h b/src/declarative/graphicsitems/qdeclarativepathview_p.h
index 035a64b..62a8c44 100644
--- a/src/declarative/graphicsitems/qdeclarativepathview_p.h
+++ b/src/declarative/graphicsitems/qdeclarativepathview_p.h
@@ -226,6 +226,7 @@ public:
emit pathChanged();
}
}
+ qreal m_percent;
Q_SIGNALS:
void currentItemChanged();
diff --git a/src/declarative/graphicsitems/qdeclarativepathview_p_p.h b/src/declarative/graphicsitems/qdeclarativepathview_p_p.h
index 9abec2e..dfebe35 100644
--- a/src/declarative/graphicsitems/qdeclarativepathview_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativepathview_p_p.h
@@ -75,19 +75,19 @@ class QDeclarativePathViewPrivate : public QDeclarativeItemPrivate, public QDecl
public:
QDeclarativePathViewPrivate()
: path(0), currentIndex(0), currentItemOffset(0.0), startPc(0), lastDist(0)
- , lastElapsed(0), mappedRange(1.0)
+ , lastElapsed(0), offset(0.0), offsetAdj(0.0), mappedRange(1.0)
, stealMouse(false), ownModel(false), interactive(true), haveHighlightRange(true)
, autoHighlight(true), highlightUp(false), layoutScheduled(false)
, moving(false), flicking(false)
, dragMargin(0), deceleration(100)
- , moveOffset(this, &QDeclarativePathViewPrivate::setOffset)
+ , moveOffset(this, &QDeclarativePathViewPrivate::setAdjustedOffset)
, firstIndex(-1), pathItems(-1), requestedIndex(-1)
, moveReason(Other), attType(0), highlightComponent(0), highlightItem(0)
, moveHighlight(this, &QDeclarativePathViewPrivate::setHighlightPosition)
, highlightPosition(0)
, highlightRangeStart(0), highlightRangeEnd(0)
, highlightRangeMode(QDeclarativePathView::StrictlyEnforceRange)
- , highlightMoveDuration(300)
+ , highlightMoveDuration(300), modelCount(0)
{
}
@@ -96,6 +96,8 @@ public:
void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) {
if ((newGeometry.size() != oldGeometry.size())
&& (!highlightItem || item != highlightItem)) {
+ if (QDeclarativePathViewAttached *att = attached(item))
+ att->m_percent = -1;
scheduleLayout();
}
}
@@ -126,6 +128,7 @@ public:
static void fixOffsetCallback(void*);
void fixOffset();
void setOffset(qreal offset);
+ void setAdjustedOffset(qreal offset);
void regenerate();
void updateItem(QDeclarativeItem *, qreal);
void snapToCurrent();
@@ -140,6 +143,7 @@ public:
qreal lastDist;
int lastElapsed;
qreal offset;
+ qreal offsetAdj;
qreal mappedRange;
bool stealMouse : 1;
bool ownModel : 1;
@@ -160,6 +164,7 @@ public:
int pathItems;
int requestedIndex;
QList<QDeclarativeItem *> items;
+ QList<QDeclarativeItem *> itemCache;
QDeclarativeGuard<QDeclarativeVisualModel> model;
QVariant modelVariant;
enum MovementReason { Other, SetIndex, Mouse };
@@ -173,6 +178,7 @@ public:
qreal highlightRangeEnd;
QDeclarativePathView::HighlightRangeMode highlightRangeMode;
int highlightMoveDuration;
+ int modelCount;
};
QT_END_NAMESPACE
diff --git a/src/declarative/graphicsitems/qdeclarativepositioners.cpp b/src/declarative/graphicsitems/qdeclarativepositioners.cpp
index 4ceb5d9..e2a373f 100644
--- a/src/declarative/graphicsitems/qdeclarativepositioners.cpp
+++ b/src/declarative/graphicsitems/qdeclarativepositioners.cpp
@@ -108,8 +108,7 @@ void QDeclarativeBasePositioner::graphicsWidgetGeometryChanged()
You also need to set a PositionerType, to declare whether you are positioning the x, y or both
for the child items. Depending on the chosen type, only x or y changes will be applied.
- Note that the subclass is responsible for adding the
- spacing in between items.
+ Note that the subclass is responsible for adding the spacing in between items.
*/
QDeclarativeBasePositioner::QDeclarativeBasePositioner(PositionerType at, QDeclarativeItem *parent)
: QDeclarativeItem(*(new QDeclarativeBasePositionerPrivate), parent)
@@ -248,13 +247,13 @@ void QDeclarativeBasePositioner::prePositioning()
positionedItems.append(posItem);
item = &positionedItems[positionedItems.count()-1];
item->isNew = true;
- if (child->opacity() <= 0.0 || childPrivate->explicitlyHidden)
+ if (child->opacity() <= 0.0 || childPrivate->explicitlyHidden || !childPrivate->width() || !childPrivate->height())
item->isVisible = false;
} else {
item = &oldItems[wIdx];
// Items are only omitted from positioning if they are explicitly hidden
// i.e. their positioning is not affected if an ancestor is hidden.
- if (child->opacity() <= 0.0 || childPrivate->explicitlyHidden) {
+ if (child->opacity() <= 0.0 || childPrivate->explicitlyHidden || !childPrivate->width() || !childPrivate->height()) {
item->isVisible = false;
} else if (!item->isVisible) {
item->isVisible = true;
@@ -322,66 +321,67 @@ void QDeclarativeBasePositioner::finishApplyTransitions()
d->moveActions.clear();
}
-static inline bool isInvisible(QGraphicsObject *child)
-{
- QGraphicsItemPrivate *childPrivate = static_cast<QGraphicsItemPrivate*>(QGraphicsItemPrivate::get(child));
- return child->opacity() == 0.0 || childPrivate->explicitlyHidden || !childPrivate->width() || !childPrivate->height();
-}
-
/*!
\qmlclass Column QDeclarativeColumn
- \ingroup qml-positioning-elements
- \since 4.7
+ \ingroup qml-positioning-elements
+ \since 4.7
\brief The Column item arranges its children vertically.
\inherits Item
The Column item positions its child items so that they are vertically
- aligned and not overlapping. Spacing between items can be added.
+ aligned and not overlapping.
- The below example positions differently shaped rectangles using a Column.
- \table
- \row
- \o \image verticalpositioner_example.png
- \o
- \qml
-Column {
- spacing: 2
- Rectangle { color: "red"; width: 50; height: 50 }
- Rectangle { color: "green"; width: 20; height: 50 }
- Rectangle { color: "blue"; width: 50; height: 20 }
-}
- \endqml
- \endtable
+ Spacing between items can be added using the \l spacing property.
+ Transitions can be used for cases where items managed by a Column are
+ added or moved. These are stored in the \l add and \l move properties
+ respectively.
+
+ See \l{Using QML Positioner and Repeater Items} for more details about this item and other
+ related items.
+
+ \section1 Example Usage
+
+ The following example positions differently shaped rectangles using a Column
+ item.
+
+ \image verticalpositioner_example.png
+
+ \snippet doc/src/snippets/declarative/column/vertical-positioner.qml document
+
+ \section1 Using Transitions
+
+ Transitions can be used to animate items that are added to, moved within,
+ or removed from a Column item. The \l add and \l move properties can be set to
+ the transitions that will be applied when items are added to, removed from,
+ or re-positioned within a Column item.
+
+ The use of transitions with positioners is described in more detail in the
+ \l{Using QML Positioner and Repeater Items#Using Transitions}{Using QML
+ Positioner and Repeater Items} document.
- Column also provides for transitions to be set when items are added, moved,
- or removed in the positioner. Adding and removing apply both to items which are deleted
- or have their position in the document changed so as to no longer be children of the positioner,
- as well as to items which have their opacity set to or from zero so as to appear or disappear.
+ \image verticalpositioner_transition.gif
- \table
- \row
- \o \image verticalpositioner_transition.gif
- \o
\qml
-Column {
- spacing: 2
- add: ...
- move: ...
- ...
-}
+ Column {
+ spacing: 2
+ add: ...
+ move: ...
+ ...
+ }
\endqml
- \endtable
+
+ \section1 Limitations
Note that the positioner assumes that the x and y positions of its children
will not change. If you manually change the x or y properties in script, bind
the x or y properties, use anchors on a child of a positioner, or have the
height of a child depend on the position of a child, then the
- positioner may exhibit strange behaviour. If you need to perform any of these
+ positioner may exhibit strange behavior. If you need to perform any of these
actions, consider positioning the items without the use of a Column.
Items with a width or height of 0 will not be positioned.
- \sa Row, {declarative/positioners}{Positioners example}
+ \sa Row, Grid, Flow, {declarative/positioners}{Positioners example}
*/
/*!
\qmlproperty Transition Column::add
@@ -389,60 +389,47 @@ Column {
This property holds the transition to be applied when adding an
item to the positioner. The transition will only be applied to the
added item(s). Positioner transitions will only affect the
- position (x,y) of items.
-
- Added can mean that either the object has been created or
- reparented, and thus is now a child or the positioner, or that the
- object has had its opacity increased from zero, and thus is now
- visible.
+ position (x, y) of items.
+ For a positioner, adding an item can mean that either the object
+ has been created or reparented, and thus is now a child or the
+ positioner, or that the object has had its opacity increased from
+ zero, and thus is now visible.
+ \sa move
*/
/*!
\qmlproperty Transition Column::move
This property holds the transition to apply when moving an item
within the positioner. Positioner transitions will only affect
- the position (x,y) of items.
+ the position (x, y) of items.
- This can happen when other items are added or removed from the
- positioner, or when items resize themselves.
+ This transition can be performed when other items are added or removed
+ from the positioner, or when items resize themselves.
+
+ \image positioner-move.gif
- \table
- \row
- \o \image positioner-move.gif
- \o
\qml
-Column {
- move: Transition {
- NumberAnimation {
- properties: "y"
- easing.type: Easing.OutBounce
+ Column {
+ move: Transition {
+ NumberAnimation {
+ properties: "y"
+ easing.type: Easing.OutBounce
+ }
}
}
-}
\endqml
- \endtable
+
+ \sa add, {declarative/positioners}{Positioners example}
*/
/*!
\qmlproperty int Column::spacing
- spacing is the amount in pixels left empty between each adjacent
- item, and defaults to 0.
+ The spacing is the amount in pixels left empty between adjacent
+ items. The default spacing is 0.
- The below example places a \l Grid containing a red, a blue and a
- green rectangle on a gray background. The area the grid positioner
- occupies is colored white. The top positioner has the default of no spacing,
- and the bottom positioner has its spacing set to 2.
-
- \image spacing_a.png
- \image spacing_b.png
-
-*/
-/*!
- \internal
- \class QDeclarativeColumn
- \brief The QDeclarativeColumn class lines up items vertically.
+ \sa Grid::spacing
*/
QDeclarativeColumn::QDeclarativeColumn(QDeclarativeItem *parent)
: QDeclarativeBasePositioner(Vertical, parent)
@@ -455,7 +442,7 @@ void QDeclarativeColumn::doPositioning(QSizeF *contentSize)
for (int ii = 0; ii < positionedItems.count(); ++ii) {
const PositionedItem &child = positionedItems.at(ii);
- if (!child.item || isInvisible(child.item))
+ if (!child.item || !child.isVisible)
continue;
if(child.item->y() != voffset)
@@ -496,29 +483,38 @@ void QDeclarativeColumn::reportConflictingAnchors()
/*!
\qmlclass Row QDeclarativeRow
- \ingroup qml-positioning-elements
+ \ingroup qml-positioning-elements
\since 4.7
\brief The Row item arranges its children horizontally.
\inherits Item
- The Row item positions its child items so that they are
- horizontally aligned and not overlapping.
+ The Row item positions its child items so that they are horizontally
+ aligned and not overlapping.
Use \l spacing to set the spacing between items in a Row, and use the
\l add and \l move properties to set the transitions that should be applied
when items are added to, removed from, or re-positioned within the Row.
- The below example lays out differently shaped rectangles using a Row.
- \qml
-Row {
- spacing: 2
- Rectangle { color: "red"; width: 50; height: 50 }
- Rectangle { color: "green"; width: 20; height: 50 }
- Rectangle { color: "blue"; width: 50; height: 20 }
-}
- \endqml
+ See \l{Using QML Positioner and Repeater Items} for more details about this item and other
+ related items.
+
+ \section1 Example Usage
+
+ The following example lays out differently shaped rectangles using a Row.
+
\image horizontalpositioner_example.png
+ \snippet doc/src/snippets/declarative/row/row.qml document
+
+ \section1 Using Transitions
+
+ Transitions can be used to animate items that are added to, moved within,
+ or removed from a Grid item. The \l add and \l move properties can be set to
+ the transitions that will be applied when items are added to, removed from,
+ or re-positioned within a Row item.
+
+ \section1 Limitations
+
Note that the positioner assumes that the x and y positions of its children
will not change. If you manually change the x or y properties in script, bind
the x or y properties, use anchors on a child of a positioner, or have the
@@ -528,61 +524,54 @@ Row {
Items with a width or height of 0 will not be positioned.
- \sa Column, {declarative/positioners}{Positioners example}
+ \sa Column, Grid, Flow, {declarative/positioners}{Positioners example}
*/
/*!
\qmlproperty Transition Row::add
- This property holds the transition to apply when adding an item to the positioner.
- The transition will only be applied to the added item(s).
- Positioner transitions will only affect the position (x,y) of items.
-
- An object is considered to be added to the positioner if it has been
- created or reparented and thus is now a child or the positioner, or if the
- object has had its opacity increased from zero, and thus is now
- visible.
+
+ This property holds the transition to be applied when adding an
+ item to the positioner. The transition will only be applied to the
+ added item(s). Positioner transitions will only affect the
+ position (x, y) of items.
+
+ For a positioner, adding an item can mean that either the object
+ has been created or reparented, and thus is now a child or the
+ positioner, or that the object has had its opacity increased from
+ zero, and thus is now visible.
+
+ \sa move
*/
/*!
\qmlproperty Transition Row::move
- This property holds the transition to apply when moving an item
- within the positioner. Positioner transitions will only affect
- the position (x,y) of items.
+ This property holds the transition to be applied when moving an
+ item within the positioner. Positioner transitions will only affect
+ the position (x, y) of items.
- This can happen when other items are added or removed from the
- positioner, or when items resize themselves.
+ This transition can be performed when other items are added or removed
+ from the positioner, or when items resize themselves.
\qml
-Row {
- id: positioner
- move: Transition {
- NumberAnimation {
- properties: "x"
- ease: "easeOutBounce"
+ Row {
+ id: positioner
+ move: Transition {
+ NumberAnimation {
+ properties: "x"
+ ease: "easeOutBounce"
+ }
}
}
-}
\endqml
+ \sa add, {declarative/positioners}{Positioners example}
*/
/*!
\qmlproperty int Row::spacing
- spacing is the amount in pixels left empty between each adjacent
- item, and defaults to 0.
-
- The below example places a \l Grid containing a red, a blue and a
- green rectangle on a gray background. The area the grid positioner
- occupies is colored white. The top positioner has the default of no spacing,
- and the bottom positioner has its spacing set to 2.
+ The spacing is the amount in pixels left empty between adjacent
+ items. The default spacing is 0.
- \image spacing_a.png
- \image spacing_b.png
-
-*/
-/*!
- \internal
- \class QDeclarativeRow
- \brief The QDeclarativeRow class lines up items horizontally.
+ \sa Grid::spacing
*/
QDeclarativeRow::QDeclarativeRow(QDeclarativeItem *parent)
: QDeclarativeBasePositioner(Horizontal, parent)
@@ -595,7 +584,7 @@ void QDeclarativeRow::doPositioning(QSizeF *contentSize)
for (int ii = 0; ii < positionedItems.count(); ++ii) {
const PositionedItem &child = positionedItems.at(ii);
- if (!child.item || isInvisible(child.item))
+ if (!child.item || !child.isVisible)
continue;
if(child.item->x() != hoffset)
@@ -635,47 +624,46 @@ void QDeclarativeRow::reportConflictingAnchors()
/*!
\qmlclass Grid QDeclarativeGrid
- \ingroup qml-positioning-elements
+ \ingroup qml-positioning-elements
\since 4.7
\brief The Grid item positions its children in a grid.
\inherits Item
The Grid item positions its child items so that they are
aligned in a grid and are not overlapping.
-
- Spacing can be added
- between child items. It also provides for transitions to be set when items are
- added, moved, or removed in the positioner. Adding and removing apply
- both to items which are deleted or have their position in the
- document changed so as to no longer be children of the positioner, as
- well as to items which have their opacity set to or from zero so
- as to appear or disappear.
-
- A Grid defaults to four columns, and as many rows as
- are necessary to fit all child items. The number of rows
- and/or the number of columns can be constrained by setting the \l rows
- or \l columns properties. The grid positioner calculates a grid with
- rectangular cells of sufficient size to hold all items, and then
- places the items in the cells, going across then down, and
- positioning each item at the (0,0) corner of the cell. The below
- example demonstrates this.
-
- \table
- \row
- \o \image gridLayout_example.png
- \o
- \qml
-Grid {
- columns: 3
- spacing: 2
- Rectangle { color: "red"; width: 50; height: 50 }
- Rectangle { color: "green"; width: 20; height: 50 }
- Rectangle { color: "blue"; width: 50; height: 20 }
- Rectangle { color: "cyan"; width: 50; height: 50 }
- Rectangle { color: "magenta"; width: 10; height: 10 }
-}
- \endqml
- \endtable
+
+ The grid positioner calculates a grid of rectangular cells of sufficient
+ size to hold all items, placing the items in the cells, from left to right
+ and top to bottom. Each item is positioned in the top-left corner of its
+ cell with position (0, 0).
+
+ A Grid defaults to four columns, and as many rows as are necessary to
+ fit all child items. The number of rows and columns can be constrained
+ by setting the \l rows and \l columns properties.
+
+ Spacing can be added between child items by setting the \l spacing
+ property. The amount of spacing applied will be the same in the
+ horizontal and vertical directions.
+
+ See \l{Using QML Positioner and Repeater Items} for more details about this item and other
+ related items.
+
+ \section1 Example Usage
+
+ The following example demonstrates this.
+
+ \image gridLayout_example.png
+
+ \snippet doc/src/snippets/declarative/grid/grid.qml document
+
+ \section1 Using Transitions
+
+ Transitions can be used to animate items that are added to, moved within,
+ or removed from a Grid item. The \l add and \l move properties can be set to
+ the transitions that will be applied when items are added to, removed from,
+ or re-positioned within a Grid item.
+
+ \section1 Limitations
Note that the positioner assumes that the x and y positions of its children
will not change. If you manually change the x or y properties in script, bind
@@ -686,60 +674,62 @@ Grid {
Items with a width or height of 0 will not be positioned.
- \sa Flow, {declarative/positioners}{Positioners example}
+ \sa Flow, Row, Column, {declarative/positioners}{Positioners example}
*/
/*!
\qmlproperty Transition Grid::add
- This property holds the transition to apply when adding an item to the positioner.
- The transition is only applied to the added item(s).
- Positioner transitions will only affect the position (x,y) of items,
- as that is all the positioners affect. To animate other property change
- you will have to do so based on how you have changed those properties.
-
- An object is considered to be added to the positioner if it has been
- created or reparented and thus is now a child or the positioner, or if the
- object has had its opacity increased from zero, and thus is now
- visible.
+
+ This property holds the transition to be applied when adding an
+ item to the positioner. The transition will only be applied to the
+ added item(s). Positioner transitions will only affect the
+ position (x, y) of items.
+
+ For a positioner, adding an item can mean that either the object
+ has been created or reparented, and thus is now a child or the
+ positioner, or that the object has had its opacity increased from
+ zero, and thus is now visible.
+
+ \sa move
*/
/*!
\qmlproperty Transition Grid::move
- This property holds the transition to apply when moving an item within the positioner.
- Positioner transitions will only affect the position (x,y) of items.
- This can happen when other items are added or removed from the positioner, or
- when items resize themselves.
+ This property holds the transition to be applied when moving an
+ item within the positioner. Positioner transitions will only affect
+ the position (x, y) of items.
+
+ This transition can be performed when other items are added or removed
+ from the positioner, or when items resize themselves.
\qml
-Grid {
- move: Transition {
- NumberAnimation {
- properties: "x,y"
- ease: "easeOutBounce"
+ Grid {
+ move: Transition {
+ NumberAnimation {
+ properties: "x,y"
+ ease: "easeOutBounce"
+ }
}
}
-}
\endqml
+ \sa add, {declarative/positioners}{Positioners example}
*/
/*!
\qmlproperty int Grid::spacing
- spacing is the amount in pixels left empty between each adjacent
- item, and defaults to 0.
+ The spacing is the amount in pixels left empty between adjacent
+ items. The default spacing is 0.
The below example places a Grid containing a red, a blue and a
green rectangle on a gray background. The area the grid positioner
- occupies is colored white. The top positioner has the default of no spacing,
- and the bottom positioner has its spacing set to 2.
+ occupies is colored white. The positioner on the left has the
+ no spacing (the default), and the positioner on the right has
+ a spacing of 6.
- \image spacing_a.png
- \image spacing_b.png
+ \inlineimage qml-grid-no-spacing.png
+ \inlineimage qml-grid-spacing.png
-*/
-/*!
- \internal
- \class QDeclarativeGrid
- \brief The QDeclarativeGrid class lays out items in a grid.
+ \sa rows, columns
*/
QDeclarativeGrid::QDeclarativeGrid(QDeclarativeItem *parent) :
QDeclarativeBasePositioner(Both, parent), m_rows(-1), m_columns(-1), m_flow(LeftToRight)
@@ -748,7 +738,9 @@ QDeclarativeGrid::QDeclarativeGrid(QDeclarativeItem *parent) :
/*!
\qmlproperty int Grid::columns
- This property holds the number of columns in the grid.
+
+ This property holds the number of columns in the grid. The default
+ number of columns is 4.
If the grid does not have enough items to fill the specified
number of columns, some columns will be of zero width.
@@ -809,9 +801,17 @@ void QDeclarativeGrid::setFlow(Flow flow)
void QDeclarativeGrid::doPositioning(QSizeF *contentSize)
{
+
int c = m_columns;
int r = m_rows;
- int numVisible = positionedItems.count();
+ //Is allocating the extra QPODVector too much overhead?
+ QPODVector<PositionedItem, 8> visibleItems;//we aren't concerned with invisible items
+ visibleItems.reserve(positionedItems.count());
+ for(int i=0; i<positionedItems.count(); i++)
+ if(positionedItems[i].item && positionedItems[i].isVisible)
+ visibleItems.append(positionedItems[i]);
+
+ int numVisible = visibleItems.count();
if (m_columns <= 0 && m_rows <= 0){
c = 4;
r = (numVisible+3)/4;
@@ -832,11 +832,10 @@ void QDeclarativeGrid::doPositioning(QSizeF *contentSize)
if (i==0)
maxColWidth << 0;
- if (childIndex == positionedItems.count())
- continue;
- const PositionedItem &child = positionedItems.at(childIndex++);
- if (!child.item || isInvisible(child.item))
- continue;
+ if (childIndex == visibleItems.count())
+ break;
+
+ const PositionedItem &child = visibleItems.at(childIndex++);
QGraphicsItemPrivate *childPrivate = QGraphicsItemPrivate::get(child.item);
if (childPrivate->width() > maxColWidth[j])
maxColWidth[j] = childPrivate->width();
@@ -853,10 +852,9 @@ void QDeclarativeGrid::doPositioning(QSizeF *contentSize)
maxColWidth << 0;
if (childIndex == positionedItems.count())
- continue;
- const PositionedItem &child = positionedItems.at(childIndex++);
- if (!child.item || isInvisible(child.item))
- continue;
+ break;
+
+ const PositionedItem &child = visibleItems.at(childIndex++);
QGraphicsItemPrivate *childPrivate = QGraphicsItemPrivate::get(child.item);
if (childPrivate->width() > maxColWidth[j])
maxColWidth[j] = childPrivate->width();
@@ -870,10 +868,8 @@ void QDeclarativeGrid::doPositioning(QSizeF *contentSize)
int yoffset=0;
int curRow =0;
int curCol =0;
- for (int i = 0; i < positionedItems.count(); ++i) {
- const PositionedItem &child = positionedItems.at(i);
- if (!child.item || isInvisible(child.item))
- continue;
+ for (int i = 0; i < visibleItems.count(); ++i) {
+ const PositionedItem &child = visibleItems.at(i);
if((child.item->x()!=xoffset)||(child.item->y()!=yoffset)){
positionX(xoffset, child);
positionY(yoffset, child);
@@ -930,13 +926,43 @@ void QDeclarativeGrid::reportConflictingAnchors()
/*!
\qmlclass Flow QDeclarativeFlow
- \ingroup qml-positioning-elements
+ \ingroup qml-positioning-elements
\since 4.7
\brief The Flow item arranges its children side by side, wrapping as necessary.
\inherits Item
- The Flow item positions its child items so that they are side by side and are
- not overlapping.
+ The Flow item positions its child items like words on a page, wrapping them
+ to create rows or columns of items that do not overlap.
+
+ Spacing between items can be added using the \l spacing property.
+ Transitions can be used for cases where items managed by a Column are
+ added or moved. These are stored in the \l add and \l move properties
+ respectively.
+
+ See \l{Using QML Positioner and Repeater Items} for more details about this item and other
+ related items.
+
+ \section1 Example Usage
+
+ The following example positions \l Text items within a parent item using
+ a Flow item.
+
+ \image qml-flow-snippet.png
+
+ \snippet doc/src/snippets/declarative/flow.qml flow item
+
+ \section1 Using Transitions
+
+ Transitions can be used to animate items that are added to, moved within,
+ or removed from a Flow item. The \l add and \l move properties can be set to
+ the transitions that will be applied when items are added to, removed from,
+ or re-positioned within a Flow item.
+
+ The use of transitions with positioners is described in more detail in the
+ \l{Using QML Positioner and Repeater Items#Using Transitions}{Using QML
+ Positioner and Repeater Items} document.
+
+ \section1 Limitations
Note that the positioner assumes that the x and y positions of its children
will not change. If you manually change the x or y properties in script, bind
@@ -947,38 +973,46 @@ void QDeclarativeGrid::reportConflictingAnchors()
Items with a width or height of 0 will not be positioned.
- \sa Grid, {declarative/positioners}{Positioners example}
+ \sa Column, Row, Grid, {declarative/positioners}{Positioners example}
*/
/*!
\qmlproperty Transition Flow::add
- This property holds the transition to apply when adding an item to the positioner.
- The transition will only be applied to the added item(s).
- Positioner transitions will only affect the position (x,y) of items.
-
- An object is considered to be added to the positioner if it has been
- created or reparented and thus is now a child or the positioner, or if the
- object has had its opacity increased from zero, and thus is now
- visible.
+
+ This property holds the transition to be applied when adding an
+ item to the positioner. The transition will only be applied to the
+ added item(s). Positioner transitions will only affect the
+ position (x, y) of items.
+
+ For a positioner, adding an item can mean that either the object
+ has been created or reparented, and thus is now a child or the
+ positioner, or that the object has had its opacity increased from
+ zero, and thus is now visible.
+
+ \sa move
*/
/*!
\qmlproperty Transition Flow::move
- This property holds the transition to apply when moving an item within the positioner.
- Positioner transitions will only affect the position (x,y) of items.
- This can happen when other items are added or removed from the positioner, or when items resize themselves.
+ This property holds the transition to be applied when moving an
+ item within the positioner. Positioner transitions will only affect
+ the position (x, y) of items.
+
+ This transition can be performed when other items are added or removed
+ from the positioner, or when items resize themselves.
\qml
-Flow {
- id: positioner
- move: Transition {
- NumberAnimation {
- properties: "x,y"
- ease: "easeOutBounce"
+ Flow {
+ id: positioner
+ move: Transition {
+ NumberAnimation {
+ properties: "x,y"
+ ease: "easeOutBounce"
+ }
}
}
-}
\endqml
+ \sa add, {declarative/positioners}{Positioners example}
*/
/*!
\qmlproperty int Flow::spacing
@@ -986,6 +1020,7 @@ Flow {
spacing is the amount in pixels left empty between each adjacent
item, and defaults to 0.
+ \sa Grid::spacing
*/
class QDeclarativeFlowPrivate : public QDeclarativeBasePositionerPrivate
@@ -1049,7 +1084,7 @@ void QDeclarativeFlow::doPositioning(QSizeF *contentSize)
for (int i = 0; i < positionedItems.count(); ++i) {
const PositionedItem &child = positionedItems.at(i);
- if (!child.item || isInvisible(child.item))
+ if (!child.item || !child.isVisible)
continue;
QGraphicsItemPrivate *childPrivate = QGraphicsItemPrivate::get(child.item);
diff --git a/src/declarative/graphicsitems/qdeclarativerectangle.cpp b/src/declarative/graphicsitems/qdeclarativerectangle.cpp
index 5990c2d..d027924 100644
--- a/src/declarative/graphicsitems/qdeclarativerectangle.cpp
+++ b/src/declarative/graphicsitems/qdeclarativerectangle.cpp
@@ -180,11 +180,6 @@ void QDeclarativeGradient::doUpdate()
int QDeclarativeRectanglePrivate::doUpdateSlotIdx = -1;
-/*!
- \internal
- \class QDeclarativeRectangle
- \brief The QDeclarativeRectangle class provides a rectangle item that you can add to a QDeclarativeView.
-*/
QDeclarativeRectangle::QDeclarativeRectangle(QDeclarativeItem *parent)
: QDeclarativeItem(*(new QDeclarativeRectanglePrivate), parent)
{
diff --git a/src/declarative/graphicsitems/qdeclarativerepeater.cpp b/src/declarative/graphicsitems/qdeclarativerepeater.cpp
index 4a951a2..00f2848 100644
--- a/src/declarative/graphicsitems/qdeclarativerepeater.cpp
+++ b/src/declarative/graphicsitems/qdeclarativerepeater.cpp
@@ -78,9 +78,9 @@ QDeclarativeRepeaterPrivate::~QDeclarativeRepeaterPrivate()
The following Repeater creates three instances of a \l Rectangle item within
a \l Row:
- \snippet doc/src/snippets/declarative/repeater.qml import
+ \snippet doc/src/snippets/declarative/repeaters/repeater.qml import
\codeline
- \snippet doc/src/snippets/declarative/repeater.qml simple
+ \snippet doc/src/snippets/declarative/repeaters/repeater.qml simple
\image repeater-simple.png
@@ -92,7 +92,7 @@ QDeclarativeRepeaterPrivate::~QDeclarativeRepeaterPrivate()
a Repeater to be used inside a layout. For example, the following Repeater's
items are stacked between a red rectangle and a blue rectangle:
- \snippet doc/src/snippets/declarative/repeater.qml layout
+ \snippet doc/src/snippets/declarative/repeaters/repeater.qml layout
\image repeater.png
@@ -106,7 +106,7 @@ QDeclarativeRepeaterPrivate::~QDeclarativeRepeaterPrivate()
\table
\row
- \o \snippet doc/src/snippets/declarative/repeater.qml index
+ \o \snippet doc/src/snippets/declarative/repeaters/repeater.qml index
\o \image repeater-index.png
\endtable
@@ -115,7 +115,7 @@ QDeclarativeRepeaterPrivate::~QDeclarativeRepeaterPrivate()
\table
\row
- \o \snippet doc/src/snippets/declarative/repeater.qml modeldata
+ \o \snippet doc/src/snippets/declarative/repeaters/repeater.qml modeldata
\o \image repeater-modeldata.png
\endtable
@@ -146,23 +146,11 @@ QDeclarativeRepeaterPrivate::~QDeclarativeRepeaterPrivate()
\endcode
*/
-/*!
- \internal
- \class QDeclarativeRepeater
- */
-
-/*!
- Create a new QDeclarativeRepeater instance.
- */
QDeclarativeRepeater::QDeclarativeRepeater(QDeclarativeItem *parent)
: QDeclarativeItem(*(new QDeclarativeRepeaterPrivate), parent)
{
}
-/*!
- Destroy the repeater instance. All items it instantiated are also
- destroyed.
- */
QDeclarativeRepeater::~QDeclarativeRepeater()
{
}
@@ -301,18 +289,12 @@ int QDeclarativeRepeater::count() const
}
-/*!
- \internal
- */
void QDeclarativeRepeater::componentComplete()
{
QDeclarativeItem::componentComplete();
regenerate();
}
-/*!
- \internal
- */
QVariant QDeclarativeRepeater::itemChange(GraphicsItemChange change,
const QVariant &value)
{
@@ -335,9 +317,6 @@ void QDeclarativeRepeater::clear()
d->deletables.clear();
}
-/*!
- \internal
- */
void QDeclarativeRepeater::regenerate()
{
Q_D(QDeclarativeRepeater);
diff --git a/src/declarative/graphicsitems/qdeclarativetext.cpp b/src/declarative/graphicsitems/qdeclarativetext.cpp
index e5ad743..14194a0 100644
--- a/src/declarative/graphicsitems/qdeclarativetext.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetext.cpp
@@ -190,32 +190,6 @@ QSet<QUrl> QTextDocumentWithImageResources::errors;
\sa {declarative/text/fonts}{Fonts example}
*/
-
-/*!
- \internal
- \class QDeclarativeText
- \qmlclass Text
-
- \brief The QDeclarativeText class provides a formatted text item that you can add to a QDeclarativeView.
-
- Text was designed for read-only text; it does not allow for any text editing.
- It can display both plain and rich text. For example:
-
- \qml
- Text { text: "Hello World!"; font.family: "Helvetica"; font.pointSize: 24; color: "red" }
- Text { text: "<b>Hello</b> <i>World!</i>" }
- \endqml
-
- \image text.png
-
- If height and width are not explicitly set, Text will attempt to determine how
- much room is needed and set it accordingly. Unless \c wrapMode is set, it will always
- prefer width to height (all text will be placed on a single line).
-
- The \c elide property can alternatively be used to fit a line of plain text to a set width.
-
- A QDeclarativeText object can be instantiated in QML using the tag \c Text.
-*/
QDeclarativeText::QDeclarativeText(QDeclarativeItem *parent)
: QDeclarativeItem(*(new QDeclarativeTextPrivate), parent)
{
@@ -455,6 +429,9 @@ void QDeclarativeText::setStyle(QDeclarativeText::TextStyle style)
if (d->style == style)
return;
+ // changing to/from Normal requires the boundingRect() to change
+ if (isComponentComplete() && (d->style == Normal || style == Normal))
+ prepareGeometryChange();
d->style = style;
d->markImgDirty();
emit styleChanged(d->style);
@@ -520,8 +497,9 @@ void QDeclarativeText::setHAlign(HAlignment align)
if (d->hAlign == align)
return;
+ if (isComponentComplete())
+ prepareGeometryChange();
d->hAlign = align;
- update();
emit horizontalAlignmentChanged(align);
}
@@ -537,8 +515,9 @@ void QDeclarativeText::setVAlign(VAlignment align)
if (d->vAlign == align)
return;
+ if (isComponentComplete())
+ prepareGeometryChange();
d->vAlign = align;
- update();
emit verticalAlignmentChanged(align);
}
@@ -831,7 +810,6 @@ void QDeclarativeTextPrivate::updateSize()
else
doc->setTextWidth(doc->idealWidth()); // ### Text does not align if width is not set (QTextDoc bug)
dy -= (int)doc->size().height();
- q->prepareGeometryChange();
QSize dsize = doc->size().toSize();
if (dsize != cachedLayoutSize) {
q->prepareGeometryChange();
@@ -908,8 +886,6 @@ void QDeclarativeTextPrivate::drawOutline()
ppm.drawPixmap(pos, imgCache);
ppm.end();
- if (imgCache.size() != img.size())
- q_func()->prepareGeometryChange();
imgCache = img;
}
@@ -928,8 +904,6 @@ void QDeclarativeTextPrivate::drawOutline(int yOffset)
ppm.drawPixmap(pos, imgCache);
ppm.end();
- if (imgCache.size() != img.size())
- q_func()->prepareGeometryChange();
imgCache = img;
}
@@ -1080,8 +1054,6 @@ void QDeclarativeTextPrivate::checkImgCache()
if (style != QDeclarativeText::Normal)
imgStyleCache = wrappedTextImage(true); //### should use styleColor
}
- if (imgCache.size() != newImgCache.size())
- q_func()->prepareGeometryChange();
imgCache = newImgCache;
if (!empty)
switch (style) {
@@ -1231,7 +1203,7 @@ void QDeclarativeText::mousePressEvent(QGraphicsSceneMouseEvent *event)
}
/*!
- \qmlsignal Text::onLinkActivated(link)
+ \qmlsignal Text::onLinkActivated(string link)
This handler is called when the user clicks on a link embedded in the text.
*/
diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
index b8e8726..3ac095c 100644
--- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
@@ -103,23 +103,6 @@ TextEdit {
\sa Text, TextInput, {declarative/text/textselection}{Text Selection example}
*/
-/*!
- \internal
- \class QDeclarativeTextEdit
- \qmlclass TextEdit
-
- \brief The QDeclarativeTextEdit class provides an editable formatted text item that you can add to a QDeclarativeView.
-
- It can display both plain and rich text.
-
- \image declarative-textedit.png
-
- A QDeclarativeTextEdit object can be instantiated in QML using the tag \c &lt;TextEdit&gt;.
-*/
-
-/*!
- Constructs a new QDeclarativeTextEdit.
-*/
QDeclarativeTextEdit::QDeclarativeTextEdit(QDeclarativeItem *parent)
: QDeclarativePaintedItem(*(new QDeclarativeTextEditPrivate), parent)
{
@@ -572,7 +555,7 @@ QRectF QDeclarativeTextEdit::positionToRectangle(int pos) const
}
/*!
- \qmlmethod int TextEdit::positionAt(x,y)
+ \qmlmethod int TextEdit::positionAt(int x, int y)
Returns the text position closest to pixel position (\a x, \a y).
@@ -1035,7 +1018,7 @@ void QDeclarativeTextEdit::selectWord()
}
/*!
- \qmlmethod void TextEdit::select(start,end)
+ \qmlmethod void TextEdit::select(int start, int end)
Causes the text from \a start to \a end to be selected.
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
index b4f36f4..5604b82 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
@@ -437,8 +437,6 @@ void QDeclarativeTextInput::setCursorPosition(int cp)
}
/*!
- \internal
-
Returns a Rect which encompasses the cursor, but which may be larger than is
required. Ignores custom cursor delegates.
*/
diff --git a/src/declarative/graphicsitems/qdeclarativetranslate.cpp b/src/declarative/graphicsitems/qdeclarativetranslate.cpp
index 0bae0cd..2e0af2a 100644
--- a/src/declarative/graphicsitems/qdeclarativetranslate.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetranslate.cpp
@@ -116,9 +116,6 @@ void QDeclarativeTranslate::setY(qreal y)
emit yChanged();
}
-/*!
- \internal
-*/
void QDeclarativeTranslate::applyTo(QMatrix4x4 *matrix) const
{
Q_D(const QDeclarativeTranslate);
diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
index 65b14cf..a46ee73 100644
--- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
+++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
@@ -714,6 +714,7 @@ void QDeclarativeVisualDataModel::setModel(const QVariant &model)
QObject::disconnect(d->m_abstractItemModel, SIGNAL(rowsMoved(const QModelIndex&,int,int,const QModelIndex&,int)),
this, SLOT(_q_rowsMoved(const QModelIndex&,int,int,const QModelIndex&,int)));
QObject::disconnect(d->m_abstractItemModel, SIGNAL(modelReset()), this, SLOT(_q_modelReset()));
+ QObject::disconnect(d->m_abstractItemModel, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged()));
d->m_abstractItemModel = 0;
} else if (d->m_visualItemModel) {
QObject::disconnect(d->m_visualItemModel, SIGNAL(itemsInserted(int,int)),
@@ -761,6 +762,7 @@ void QDeclarativeVisualDataModel::setModel(const QVariant &model)
QObject::connect(d->m_abstractItemModel, SIGNAL(rowsMoved(const QModelIndex&,int,int,const QModelIndex&,int)),
this, SLOT(_q_rowsMoved(const QModelIndex&,int,int,const QModelIndex&,int)));
QObject::connect(d->m_abstractItemModel, SIGNAL(modelReset()), this, SLOT(_q_modelReset()));
+ QObject::connect(d->m_abstractItemModel, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged()));
d->m_metaDataCacheable = true;
return;
}
@@ -1303,24 +1305,27 @@ void QDeclarativeVisualDataModel::_q_itemsMoved(int from, int to, int count)
void QDeclarativeVisualDataModel::_q_rowsInserted(const QModelIndex &parent, int begin, int end)
{
- if (!parent.isValid())
+ Q_D(QDeclarativeVisualDataModel);
+ if (parent == d->m_root)
_q_itemsInserted(begin, end - begin + 1);
}
void QDeclarativeVisualDataModel::_q_rowsRemoved(const QModelIndex &parent, int begin, int end)
{
- if (!parent.isValid())
+ Q_D(QDeclarativeVisualDataModel);
+ if (parent == d->m_root)
_q_itemsRemoved(begin, end - begin + 1);
}
void QDeclarativeVisualDataModel::_q_rowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow)
{
+ Q_D(QDeclarativeVisualDataModel);
const int count = sourceEnd - sourceStart + 1;
- if (!destinationParent.isValid() && !sourceParent.isValid()) {
+ if (destinationParent == d->m_root && sourceParent == d->m_root) {
_q_itemsMoved(sourceStart, destinationRow, count);
- } else if (!sourceParent.isValid()) {
+ } else if (sourceParent == d->m_root) {
_q_itemsRemoved(sourceStart, count);
- } else if (!destinationParent.isValid()) {
+ } else if (destinationParent == d->m_root) {
_q_itemsInserted(destinationRow, count);
}
}
@@ -1328,10 +1333,16 @@ void QDeclarativeVisualDataModel::_q_rowsMoved(const QModelIndex &sourceParent,
void QDeclarativeVisualDataModel::_q_dataChanged(const QModelIndex &begin, const QModelIndex &end)
{
Q_D(QDeclarativeVisualDataModel);
- if (!begin.parent().isValid())
+ if (begin.parent() == d->m_root)
_q_itemsChanged(begin.row(), end.row() - begin.row() + 1, d->m_roles);
}
+void QDeclarativeVisualDataModel::_q_layoutChanged()
+{
+ Q_D(QDeclarativeVisualDataModel);
+ _q_itemsChanged(0, count(), d->m_roles);
+}
+
void QDeclarativeVisualDataModel::_q_modelReset()
{
emit modelReset();
diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel_p.h b/src/declarative/graphicsitems/qdeclarativevisualitemmodel_p.h
index 50d2c53..e159786 100644
--- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel_p.h
+++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel_p.h
@@ -194,6 +194,7 @@ private Q_SLOTS:
void _q_rowsRemoved(const QModelIndex &,int,int);
void _q_rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
void _q_dataChanged(const QModelIndex&,const QModelIndex&);
+ void _q_layoutChanged();
void _q_modelReset();
void _q_createdPackage(int index, QDeclarativePackage *package);
void _q_destroyingPackage(QDeclarativePackage *package);
diff --git a/src/declarative/qml/parser/qdeclarativejslexer.cpp b/src/declarative/qml/parser/qdeclarativejslexer.cpp
index cd08658..1eb42e4 100644
--- a/src/declarative/qml/parser/qdeclarativejslexer.cpp
+++ b/src/declarative/qml/parser/qdeclarativejslexer.cpp
@@ -677,9 +677,9 @@ int Lexer::lex()
setDone(Other);
} else
state = Start;
- if (driver) driver->addComment(startpos, tokenLength(), startlineno, startcolumn);
+ if (driver) driver->addComment(startpos+2, tokenLength()-2, startlineno, startcolumn+2);
} else if (current == 0) {
- if (driver) driver->addComment(startpos, tokenLength(), startlineno, startcolumn);
+ if (driver) driver->addComment(startpos+2, tokenLength()-2, startlineno, startcolumn+2);
setDone(Eof);
}
@@ -689,14 +689,14 @@ int Lexer::lex()
setDone(Bad);
err = UnclosedComment;
errmsg = QCoreApplication::translate("QDeclarativeParser", "Unclosed comment at end of file");
- if (driver) driver->addComment(startpos, tokenLength(), startlineno, startcolumn);
+ if (driver) driver->addComment(startpos+2, tokenLength()-2, startlineno, startcolumn+2);
} else if (isLineTerminator()) {
shiftWindowsLineBreak();
yylineno++;
} else if (current == '*' && next1 == '/') {
state = Start;
shift(1);
- if (driver) driver->addComment(startpos, tokenLength(), startlineno, startcolumn);
+ if (driver) driver->addComment(startpos+2, tokenLength()-3, startlineno, startcolumn+2);
}
break;
diff --git a/src/declarative/qml/qdeclarativecompiledbindings.cpp b/src/declarative/qml/qdeclarativecompiledbindings.cpp
index 723da94..9402596 100644
--- a/src/declarative/qml/qdeclarativecompiledbindings.cpp
+++ b/src/declarative/qml/qdeclarativecompiledbindings.cpp
@@ -1874,7 +1874,7 @@ bool QDeclarativeBindingCompilerPrivate::parseName(AST::Node *node, Result &type
return false;
QDeclarativeImportedNamespace *ns = 0;
- if (!engine->importDatabase.resolveType(imports, name.toUtf8(), &attachType, 0, 0, 0, &ns))
+ if (!imports.resolveType(name.toUtf8(), &attachType, 0, 0, 0, &ns))
return false;
if (ns || !attachType || !attachType->attachedPropertiesType())
return false;
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp
index 2b4a4a5..e55dc92 100644
--- a/src/declarative/qml/qdeclarativecompiler.cpp
+++ b/src/declarative/qml/qdeclarativecompiler.cpp
@@ -41,7 +41,6 @@
#include "private/qdeclarativecompiler_p.h"
-#include "private/qdeclarativecompositetypedata_p.h"
#include "private/qdeclarativeparser_p.h"
#include "private/qdeclarativescriptparser_p.h"
#include "qdeclarativepropertyvaluesource.h"
@@ -562,7 +561,7 @@ void QDeclarativeCompiler::reset(QDeclarativeCompiledData *data)
on a successful compiler.
*/
bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine,
- QDeclarativeCompositeTypeData *unit,
+ QDeclarativeTypeData *unit,
QDeclarativeCompiledData *out)
{
exceptions.clear();
@@ -573,10 +572,15 @@ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine,
output = out;
// Compile types
- for (int ii = 0; ii < unit->types.count(); ++ii) {
- QDeclarativeCompositeTypeData::TypeReference &tref = unit->types[ii];
+ const QList<QDeclarativeTypeData::TypeReference> &resolvedTypes = unit->resolvedTypes();
+ QList<QDeclarativeScriptParser::TypeReference *> referencedTypes = unit->parser().referencedTypes();
+
+ for (int ii = 0; ii < resolvedTypes.count(); ++ii) {
QDeclarativeCompiledData::TypeReference ref;
- QDeclarativeScriptParser::TypeReference *parserRef = unit->data.referencedTypes().at(ii);
+
+ const QDeclarativeTypeData::TypeReference &tref = resolvedTypes.at(ii);
+ QDeclarativeScriptParser::TypeReference *parserRef = referencedTypes.at(ii);
+
if (tref.type) {
ref.type = tref.type;
if (!ref.type->isCreatable()) {
@@ -585,33 +589,16 @@ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine,
err = tr( "Element is not creatable.");
COMPILE_EXCEPTION(parserRef->refObjects.first(), err);
}
- } else if (tref.unit) {
- ref.component = tref.unit->toComponent(engine);
-
- if (ref.component->isError()) {
- QDeclarativeError error;
- error.setUrl(output->url);
- error.setDescription(QLatin1String("Unable to create type ") +
- parserRef->name);
- if (!parserRef->refObjects.isEmpty()) {
- QDeclarativeParser::Object *parserObject = parserRef->refObjects.first();
- error.setLine(parserObject->location.start.line);
- error.setColumn(parserObject->location.start.column);
- }
-
- exceptions << error;
- exceptions << ref.component->errors();
- reset(out);
- return false;
- }
- ref.ref = tref.unit;
+ } else if (tref.typeData) {
+ ref.component = tref.typeData->component();
+ ref.ref = tref.typeData;
ref.ref->addref();
}
ref.className = parserRef->name.toUtf8();
out->types << ref;
}
- Object *root = unit->data.tree();
+ Object *root = unit->parser().tree();
Q_ASSERT(root);
this->engine = engine;
@@ -664,17 +651,18 @@ void QDeclarativeCompiler::compileTree(Object *tree)
QHash<QString, Object::ScriptBlock> importedScripts;
QStringList importedScriptIndexes;
- for (int ii = 0; ii < unit->scripts.count(); ++ii) {
- QString scriptCode = QString::fromUtf8(unit->scripts.at(ii).resource->data);
- Object::ScriptBlock::Pragmas pragmas = QDeclarativeScriptParser::extractPragmas(scriptCode);
+ foreach (const QDeclarativeTypeData::ScriptReference &script, unit->resolvedScripts()) {
+ QString scriptCode = script.script->scriptSource();
+ Object::ScriptBlock::Pragmas pragmas = script.script->pragmas();
+
+ Q_ASSERT(!importedScripts.contains(script.qualifier));
if (!scriptCode.isEmpty()) {
- Object::ScriptBlock &scriptBlock = importedScripts[unit->scripts.at(ii).qualifier];
+ Object::ScriptBlock &scriptBlock = importedScripts[script.qualifier];
- scriptBlock.codes.append(scriptCode);
- scriptBlock.lineNumbers.append(1);
- scriptBlock.files.append(unit->scripts.at(ii).resource->url);
- scriptBlock.pragmas.append(pragmas);
+ scriptBlock.code = scriptCode;
+ scriptBlock.file = script.script->finalUrl().toString();
+ scriptBlock.pragmas = pragmas;
}
}
@@ -703,7 +691,7 @@ void QDeclarativeCompiler::compileTree(Object *tree)
for (int ii = 0; ii < importedScriptIndexes.count(); ++ii)
output->importCache->add(importedScriptIndexes.at(ii), ii);
- unit->imports.cache(output->importCache, engine);
+ unit->imports().populateCache(output->importCache, engine);
Q_ASSERT(tree->metatype);
@@ -986,7 +974,7 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj)
}
// Begin the class
- if (obj->parserStatusCast != -1) {
+ if (tr.type && obj->parserStatusCast != -1) {
QDeclarativeInstruction begin;
begin.type = QDeclarativeInstruction::BeginObject;
begin.begin.castValue = obj->parserStatusCast;
@@ -1374,7 +1362,7 @@ bool QDeclarativeCompiler::doesPropertyExist(QDeclarativeParser::Property *prop,
return p.name() != 0;
} else {
int idx = mo->indexOfProperty(prop->name.constData());
- return idx != -1;
+ return idx != -1 && mo->property(idx).isScriptable();
}
}
@@ -1403,8 +1391,7 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
QDeclarativeType *type = 0;
QDeclarativeImportedNamespace *typeNamespace = 0;
- enginePrivate->importDatabase.resolveType(unit->imports, prop->name,
- &type, 0, 0, 0, &typeNamespace);
+ unit->imports().resolveType(prop->name, &type, 0, 0, 0, &typeNamespace);
if (typeNamespace) {
// ### We might need to indicate that this property is a namespace
@@ -1440,6 +1427,11 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
if (prop->index != -1) {
p = metaObject->property(prop->index);
Q_ASSERT(p.name());
+
+ if (!p.isScriptable()) {
+ prop->index = -1;
+ p = QMetaProperty();
+ }
}
}
@@ -1512,7 +1504,7 @@ bool QDeclarativeCompiler::buildPropertyInNamespace(QDeclarativeImportedNamespac
// Setup attached property data
QDeclarativeType *type = 0;
- enginePrivate->importDatabase.resolveTypeInNamespace(ns, prop->name, &type, 0, 0, 0);
+ unit->imports().resolveType(ns, prop->name, &type, 0, 0, 0);
if (!type || !type->attachedPropertiesType())
COMPILE_EXCEPTION(prop, tr("Non-existent attached object"));
@@ -1772,9 +1764,7 @@ bool QDeclarativeCompiler::buildGroupedProperty(QDeclarativeParser::Property *pr
Q_ASSERT(prop->index != -1);
if (QDeclarativeValueTypeFactory::isValueType(prop->type)) {
- QDeclarativeEnginePrivate *ep =
- static_cast<QDeclarativeEnginePrivate *>(QObjectPrivate::get(engine));
- if (prop->type >= 0 /* QVariant == -1 */ && ep->valueTypes[prop->type]) {
+ if (prop->type >= 0 /* QVariant == -1 */ && enginePrivate->valueTypes[prop->type]) {
if (prop->values.count()) {
if (prop->values.at(0)->location < prop->value->location) {
@@ -1788,7 +1778,7 @@ bool QDeclarativeCompiler::buildGroupedProperty(QDeclarativeParser::Property *pr
COMPILE_EXCEPTION(prop, tr( "Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop->name)));
}
- COMPILE_CHECK(buildValueTypeProperty(ep->valueTypes[prop->type],
+ COMPILE_CHECK(buildValueTypeProperty(enginePrivate->valueTypes[prop->type],
prop->value, obj, ctxt.incr()));
obj->addValueTypeProperty(prop);
} else {
@@ -1826,6 +1816,8 @@ bool QDeclarativeCompiler::buildValueTypeProperty(QObject *type,
if (idx == -1)
COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(QString::fromUtf8(prop->name)));
QMetaProperty p = type->metaObject()->property(idx);
+ if (!p.isScriptable())
+ COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(QString::fromUtf8(prop->name)));
prop->index = idx;
prop->type = p.userType();
prop->isValueTypeSubProperty = true;
@@ -2139,8 +2131,7 @@ bool QDeclarativeCompiler::testQualifiedEnumAssignment(const QMetaProperty &prop
QString typeName = parts.at(0);
QDeclarativeType *type = 0;
- enginePrivate->importDatabase.resolveType(unit->imports, typeName.toUtf8(),
- &type, 0, 0, 0, 0);
+ unit->imports().resolveType(typeName.toUtf8(), &type, 0, 0, 0, 0);
if (!type || obj->typeName != type->qmlTypeName())
return true;
@@ -2167,7 +2158,7 @@ int QDeclarativeCompiler::evaluateEnum(const QByteArray& script) const
int dot = script.indexOf('.');
if (dot > 0) {
QDeclarativeType *type = 0;
- enginePrivate->importDatabase.resolveType(unit->imports, script.left(dot), &type, 0, 0, 0, 0);
+ unit->imports().resolveType(script.left(dot), &type, 0, 0, 0, 0);
if (!type)
return -1;
const QMetaObject *mo = type->metaObject();
@@ -2185,8 +2176,7 @@ int QDeclarativeCompiler::evaluateEnum(const QByteArray& script) const
const QMetaObject *QDeclarativeCompiler::resolveType(const QByteArray& name) const
{
QDeclarativeType *qmltype = 0;
- if (!enginePrivate->importDatabase.resolveType(unit->imports, name, &qmltype,
- 0, 0, 0, 0))
+ if (!unit->imports().resolveType(name, &qmltype, 0, 0, 0, 0))
return 0;
if (!qmltype)
return 0;
@@ -2219,7 +2209,7 @@ bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj)
if (propName.at(0).isUpper())
COMPILE_EXCEPTION(&prop, tr("Property names cannot begin with an upper case letter"));
- if (QDeclarativeEnginePrivate::get(engine)->globalClass->illegalNames().contains(propName))
+ if (enginePrivate->globalClass->illegalNames().contains(propName))
COMPILE_EXCEPTION(&prop, tr("Illegal property name"));
propNames.insert(prop.name);
@@ -2232,7 +2222,7 @@ bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj)
QString nameStr = QString::fromUtf8(name);
if (nameStr.at(0).isUpper())
COMPILE_EXCEPTION(obj, tr("Signal names cannot begin with an upper case letter"));
- if (QDeclarativeEnginePrivate::get(engine)->globalClass->illegalNames().contains(nameStr))
+ if (enginePrivate->globalClass->illegalNames().contains(nameStr))
COMPILE_EXCEPTION(obj, tr("Illegal signal name"));
methodNames.insert(name);
}
@@ -2243,7 +2233,7 @@ bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj)
QString nameStr = QString::fromUtf8(name);
if (nameStr.at(0).isUpper())
COMPILE_EXCEPTION(obj, tr("Method names cannot begin with an upper case letter"));
- if (QDeclarativeEnginePrivate::get(engine)->globalClass->illegalNames().contains(nameStr))
+ if (enginePrivate->globalClass->illegalNames().contains(nameStr))
COMPILE_EXCEPTION(obj, tr("Illegal method name"));
methodNames.insert(name);
}
@@ -2344,17 +2334,18 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
QByteArray customTypeName;
QDeclarativeType *qmltype = 0;
QUrl url;
- if (!enginePrivate->importDatabase.resolveType(unit->imports, p.customType, &qmltype,
- &url, 0, 0, 0))
+ if (!unit->imports().resolveType(p.customType, &qmltype, &url, 0, 0, 0))
COMPILE_EXCEPTION(&p, tr("Invalid property type"));
if (!qmltype) {
- QDeclarativeCompositeTypeData *tdata = enginePrivate->typeManager.get(url);
+ QDeclarativeTypeData *tdata = enginePrivate->typeLoader.get(url);
Q_ASSERT(tdata);
- Q_ASSERT(tdata->status == QDeclarativeCompositeTypeData::Complete);
+ Q_ASSERT(tdata->isComplete());
- QDeclarativeCompiledData *data = tdata->toCompiledComponent(engine);
+ QDeclarativeCompiledData *data = tdata->compiledData();
customTypeName = data->root->className();
+ data->release();
+ tdata->release();
} else {
customTypeName = qmltype->typeName();
}
@@ -2420,17 +2411,20 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
builder.addSignal(p.name + "Changed()");
QMetaPropertyBuilder propBuilder =
builder.addProperty(p.name, type, builder.methodCount() - 1);
- propBuilder.setScriptable(true);
propBuilder.setWritable(!readonly);
}
- if (mode == ResolveAliases) {
- for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
- const Object::DynamicProperty &p = obj->dynamicProperties.at(ii);
+ for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
+ const Object::DynamicProperty &p = obj->dynamicProperties.at(ii);
- if (p.type == Object::DynamicProperty::Alias) {
+ if (p.type == Object::DynamicProperty::Alias) {
+ if (mode == ResolveAliases) {
((QDeclarativeVMEMetaData *)dynamicData.data())->aliasCount++;
compileAlias(builder, dynamicData, obj, p);
+ } else {
+ // Need a fake signal so that the metaobject remains consistent across
+ // the resolve and non-resolve alias runs
+ builder.addSignal(p.name + "Changed()");
}
}
}
@@ -2586,6 +2580,9 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
QMetaProperty aliasProperty = idObject->metaObject()->property(propIdx);
+ if (!aliasProperty.isScriptable())
+ COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
+
writable = aliasProperty.isWritable();
if (aliasProperty.isEnumType())
@@ -2622,7 +2619,6 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
builder.addSignal(prop.name + "Changed()");
QMetaPropertyBuilder propBuilder =
builder.addProperty(prop.name, typeName.constData(), builder.methodCount() - 1);
- propBuilder.setScriptable(true);
propBuilder.setWritable(writable);
return true;
}
@@ -2749,7 +2745,7 @@ bool QDeclarativeCompiler::completeComponentBuild()
expr.context = binding.bindingContext.object;
expr.property = binding.property;
expr.expression = binding.expression;
- expr.imports = unit->imports;
+ expr.imports = unit->imports();
int index = bindingCompiler.compile(expr, enginePrivate);
if (index != -1) {
diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h
index 49dc53f..89eef09 100644
--- a/src/declarative/qml/qdeclarativecompiler_p.h
+++ b/src/declarative/qml/qdeclarativecompiler_p.h
@@ -56,13 +56,13 @@
#include "qdeclarative.h"
#include "qdeclarativeerror.h"
#include "private/qdeclarativeinstruction_p.h"
-#include "private/qdeclarativecompositetypemanager_p.h"
#include "private/qdeclarativeparser_p.h"
#include "private/qdeclarativeengine_p.h"
#include "private/qbitfield_p.h"
#include "private/qdeclarativepropertycache_p.h"
#include "private/qdeclarativeintegercache_p.h"
#include "private/qdeclarativetypenamecache_p.h"
+#include "private/qdeclarativetypeloader_p.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qset.h>
@@ -152,7 +152,7 @@ class Q_AUTOTEST_EXPORT QDeclarativeCompiler
public:
QDeclarativeCompiler();
- bool compile(QDeclarativeEngine *, QDeclarativeCompositeTypeData *, QDeclarativeCompiledData *);
+ bool compile(QDeclarativeEngine *, QDeclarativeTypeData *, QDeclarativeCompiledData *);
bool isError() const;
QList<QDeclarativeError> errors() const;
@@ -338,7 +338,7 @@ private:
QDeclarativeEngine *engine;
QDeclarativeEnginePrivate *enginePrivate;
QDeclarativeParser::Object *unitRoot;
- QDeclarativeCompositeTypeData *unit;
+ QDeclarativeTypeData *unit;
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp
index d2d1f19..7f58166 100644
--- a/src/declarative/qml/qdeclarativecomponent.cpp
+++ b/src/declarative/qml/qdeclarativecomponent.cpp
@@ -44,7 +44,6 @@
#include "private/qdeclarativecompiler_p.h"
#include "private/qdeclarativecontext_p.h"
-#include "private/qdeclarativecompositetypedata_p.h"
#include "private/qdeclarativeengine_p.h"
#include "private/qdeclarativevme_p.h"
#include "qdeclarative.h"
@@ -197,7 +196,7 @@ class QByteArray;
\value Error An error has occurred. Call errors() to retrieve a list of \{QDeclarativeError}{errors}.
*/
-void QDeclarativeComponentPrivate::typeDataReady()
+void QDeclarativeComponentPrivate::typeDataReady(QDeclarativeTypeData *)
{
Q_Q(QDeclarativeComponent);
@@ -209,28 +208,25 @@ void QDeclarativeComponentPrivate::typeDataReady()
emit q->statusChanged(q->status());
}
-void QDeclarativeComponentPrivate::updateProgress(qreal p)
+void QDeclarativeComponentPrivate::typeDataProgress(QDeclarativeTypeData *, qreal p)
{
Q_Q(QDeclarativeComponent);
progress = p;
+
emit q->progressChanged(p);
}
-void QDeclarativeComponentPrivate::fromTypeData(QDeclarativeCompositeTypeData *data)
+void QDeclarativeComponentPrivate::fromTypeData(QDeclarativeTypeData *data)
{
- url = data->imports.baseUrl();
- QDeclarativeCompiledData *c = data->toCompiledComponent(engine);
+ url = data->finalUrl();
+ QDeclarativeCompiledData *c = data->compiledData();
if (!c) {
- Q_ASSERT(data->status == QDeclarativeCompositeTypeData::Error);
-
- state.errors = data->errors;
-
+ Q_ASSERT(data->isError());
+ state.errors = data->errors();
} else {
-
cc = c;
-
}
data->release();
@@ -239,7 +235,7 @@ void QDeclarativeComponentPrivate::fromTypeData(QDeclarativeCompositeTypeData *d
void QDeclarativeComponentPrivate::clear()
{
if (typeData) {
- typeData->remWaiter(this);
+ typeData->unregisterCallback(this);
typeData->release();
typeData = 0;
}
@@ -271,7 +267,7 @@ QDeclarativeComponent::~QDeclarativeComponent()
}
if (d->typeData) {
- d->typeData->remWaiter(d);
+ d->typeData->unregisterCallback(d);
d->typeData->release();
}
if (d->cc)
@@ -443,19 +439,13 @@ void QDeclarativeComponent::setData(const QByteArray &data, const QUrl &url)
d->url = url;
- QDeclarativeCompositeTypeData *typeData =
- QDeclarativeEnginePrivate::get(d->engine)->typeManager.getImmediate(data, url);
+ QDeclarativeTypeData *typeData = QDeclarativeEnginePrivate::get(d->engine)->typeLoader.get(data, url);
- if (typeData->status == QDeclarativeCompositeTypeData::Waiting
- || typeData->status == QDeclarativeCompositeTypeData::WaitingResources)
- {
- d->typeData = typeData;
- d->typeData->addWaiter(d);
-
- } else {
-
+ if (typeData->isCompleteOrError()) {
d->fromTypeData(typeData);
-
+ } else {
+ d->typeData = typeData;
+ d->typeData->registerCallback(d);
}
d->progress = 1.0;
@@ -501,18 +491,15 @@ void QDeclarativeComponent::loadUrl(const QUrl &url)
return;
}
- QDeclarativeCompositeTypeData *data =
- QDeclarativeEnginePrivate::get(d->engine)->typeManager.get(d->url);
+ QDeclarativeTypeData *data = QDeclarativeEnginePrivate::get(d->engine)->typeLoader.get(d->url);
- if (data->status == QDeclarativeCompositeTypeData::Waiting
- || data->status == QDeclarativeCompositeTypeData::WaitingResources)
- {
- d->typeData = data;
- d->typeData->addWaiter(d);
- d->progress = data->progress;
- } else {
+ if (data->isCompleteOrError()) {
d->fromTypeData(data);
d->progress = 1.0;
+ } else {
+ d->typeData = data;
+ d->typeData->registerCallback(d);
+ d->progress = data->progress();
}
emit statusChanged(status());
@@ -586,7 +573,7 @@ QDeclarativeComponent::QDeclarativeComponent(QDeclarativeComponentPrivate &dd, Q
}
/*!
- \qmlmethod object Component::createObject(parent)
+ \qmlmethod object Component::createObject(Item parent)
Creates and returns an object instance of this component that will have the given
\a parent. Returns null if object creation fails.
@@ -620,10 +607,11 @@ QScriptValue QDeclarativeComponent::createObject(QObject* parent)
ctxt = d->engine->rootContext();
if (!ctxt)
return QScriptValue(QScriptValue::NullValue);
- QObject* ret = create(ctxt);
- if (!ret)
+ QObject* ret = beginCreate(ctxt);
+ if (!ret) {
+ completeCreate();
return QScriptValue(QScriptValue::NullValue);
-
+ }
if (parent) {
ret->setParent(parent);
@@ -644,6 +632,7 @@ QScriptValue QDeclarativeComponent::createObject(QObject* parent)
if (needParent)
qWarning("QDeclarativeComponent: Created graphical object was not placed in the graphics scene.");
}
+ completeCreate();
QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(d->engine);
QDeclarativeData::get(ret, true)->setImplicitDestructible();
diff --git a/src/declarative/qml/qdeclarativecomponent.h b/src/declarative/qml/qdeclarativecomponent.h
index 1d1fca7..fd9cb2b 100644
--- a/src/declarative/qml/qdeclarativecomponent.h
+++ b/src/declarative/qml/qdeclarativecomponent.h
@@ -117,6 +117,7 @@ private:
Q_DISABLE_COPY(QDeclarativeComponent)
friend class QDeclarativeVME;
friend class QDeclarativeCompositeTypeData;
+ friend class QDeclarativeTypeData;
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecomponent_p.h b/src/declarative/qml/qdeclarativecomponent_p.h
index 2a7d633..1b1454b 100644
--- a/src/declarative/qml/qdeclarativecomponent_p.h
+++ b/src/declarative/qml/qdeclarativecomponent_p.h
@@ -56,7 +56,7 @@
#include "qdeclarativecomponent.h"
#include "private/qdeclarativeengine_p.h"
-#include "private/qdeclarativecompositetypemanager_p.h"
+#include "private/qdeclarativetypeloader_p.h"
#include "private/qbitfield_p.h"
#include "qdeclarativeerror.h"
#include "qdeclarative.h"
@@ -74,7 +74,7 @@ class QDeclarativeEngine;
class QDeclarativeCompiledData;
class QDeclarativeComponentAttached;
-class QDeclarativeComponentPrivate : public QObjectPrivate
+class QDeclarativeComponentPrivate : public QObjectPrivate, public QDeclarativeTypeData::TypeDataCallback
{
Q_DECLARE_PUBLIC(QDeclarativeComponent)
@@ -85,11 +85,11 @@ public:
QObject *beginCreate(QDeclarativeContextData *, const QBitField &);
void completeCreate();
- QDeclarativeCompositeTypeData *typeData;
- void typeDataReady();
- void updateProgress(qreal);
+ QDeclarativeTypeData *typeData;
+ virtual void typeDataReady(QDeclarativeTypeData *);
+ virtual void typeDataProgress(QDeclarativeTypeData *, qreal);
- void fromTypeData(QDeclarativeCompositeTypeData *data);
+ void fromTypeData(QDeclarativeTypeData *data);
QUrl url;
qreal progress;
diff --git a/src/declarative/qml/qdeclarativecompositetypedata_p.h b/src/declarative/qml/qdeclarativecompositetypedata_p.h
deleted file mode 100644
index a0e4cc2..0000000
--- a/src/declarative/qml/qdeclarativecompositetypedata_p.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDECLARATIVECOMPOSITETYPEDATA_P_H
-#define QDECLARATIVECOMPOSITETYPEDATA_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qdeclarativeengine_p.h"
-
-#include <QtCore/qglobal.h>
-
-QT_BEGIN_NAMESPACE
-
-class QDeclarativeCompositeTypeResource;
-class QDeclarativeCompositeTypeData : public QDeclarativeRefCount
-{
-public:
- QDeclarativeCompositeTypeData();
- virtual ~QDeclarativeCompositeTypeData();
-
- enum Status {
- Invalid,
- Complete,
- Error,
- Waiting,
- WaitingResources
- };
- Status status;
- enum ErrorType {
- NoError,
- AccessError,
- GeneralError
- };
- ErrorType errorType;
-
- QList<QDeclarativeError> errors;
-
- QDeclarativeImports imports;
-
- QList<QDeclarativeCompositeTypeData *> dependants;
-
- // Return a QDeclarativeComponent if the QDeclarativeCompositeTypeData is not in the Waiting
- // state. The QDeclarativeComponent is owned by the QDeclarativeCompositeTypeData, so a
- // reference should be kept to keep the QDeclarativeComponent alive.
- QDeclarativeComponent *toComponent(QDeclarativeEngine *);
- // Return a QDeclarativeCompiledData if possible, or 0 if an error
- // occurs
- QDeclarativeCompiledData *toCompiledComponent(QDeclarativeEngine *);
-
- struct TypeReference
- {
- TypeReference();
-
- QDeclarativeType *type;
- QDeclarativeCompositeTypeData *unit;
- };
-
- struct ScriptReference
- {
- ScriptReference();
-
- QString qualifier;
- QDeclarativeCompositeTypeResource *resource;
- };
-
- QList<TypeReference> types;
- QList<ScriptReference> scripts;
- QList<QDeclarativeCompositeTypeResource *> resources;
-
- // Add or remove p as a waiter. When the QDeclarativeCompositeTypeData becomes
- // ready, the QDeclarativeComponentPrivate::typeDataReady() method will be invoked on
- // p. The waiter is automatically removed when the typeDataReady() method
- // is invoked, so there is no need to call remWaiter() in this case.
- void addWaiter(QDeclarativeComponentPrivate *p);
- void remWaiter(QDeclarativeComponentPrivate *p);
-
- qreal progress;
-
-private:
- friend class QDeclarativeCompositeTypeManager;
- friend class QDeclarativeCompiler;
- friend class QDeclarativeDomDocument;
-
- QDeclarativeScriptParser data;
- QList<QDeclarativeComponentPrivate *> waiters;
- QDeclarativeComponent *component;
- QDeclarativeCompiledData *compiledComponent;
-};
-
-class QDeclarativeCompositeTypeResource : public QDeclarativeRefCount
-{
-public:
- QDeclarativeCompositeTypeResource();
- virtual ~QDeclarativeCompositeTypeResource();
-
- enum Status {
- Invalid,
- Complete,
- Error,
- Waiting
- };
- Status status;
-
- QList<QDeclarativeCompositeTypeData *> dependants;
-
- QString url;
- QByteArray data;
-};
-
-QT_END_NAMESPACE
-
-#endif // QDECLARATIVECOMPOSITETYPEDATA_P_H
-
diff --git a/src/declarative/qml/qdeclarativecompositetypemanager.cpp b/src/declarative/qml/qdeclarativecompositetypemanager.cpp
deleted file mode 100644
index 2e77534..0000000
--- a/src/declarative/qml/qdeclarativecompositetypemanager.cpp
+++ /dev/null
@@ -1,776 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "private/qdeclarativecompositetypemanager_p.h"
-
-#include "private/qdeclarativecompositetypedata_p.h"
-#include "private/qdeclarativescriptparser_p.h"
-#include "qdeclarativeengine.h"
-#include "private/qdeclarativeengine_p.h"
-#include "qdeclarativecomponent.h"
-#include "private/qdeclarativecomponent_p.h"
-#include "private/qdeclarativecompiler_p.h"
-
-#include <QtNetwork/qnetworkreply.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/qfile.h>
-
-QT_BEGIN_NAMESPACE
-
-QDeclarativeCompositeTypeData::QDeclarativeCompositeTypeData()
-: status(Invalid), errorType(NoError), component(0), compiledComponent(0)
-{
-}
-
-QDeclarativeCompositeTypeData::~QDeclarativeCompositeTypeData()
-{
- for (int ii = 0; ii < dependants.count(); ++ii)
- dependants.at(ii)->release();
-
- for (int ii = 0; ii < resources.count(); ++ii)
- resources.at(ii)->release();
-
- if (compiledComponent)
- compiledComponent->release();
-
- if (component)
- delete component;
-}
-
-QDeclarativeCompositeTypeResource::QDeclarativeCompositeTypeResource()
-{
-}
-
-QDeclarativeCompositeTypeResource::~QDeclarativeCompositeTypeResource()
-{
- for (int ii = 0; ii < dependants.count(); ++ii)
- dependants.at(ii)->release();
-}
-
-void QDeclarativeCompositeTypeData::addWaiter(QDeclarativeComponentPrivate *p)
-{
- waiters << p;
-}
-
-void QDeclarativeCompositeTypeData::remWaiter(QDeclarativeComponentPrivate *p)
-{
- waiters.removeAll(p);
-}
-
-QDeclarativeComponent *QDeclarativeCompositeTypeData::toComponent(QDeclarativeEngine *engine)
-{
- if (!component) {
-
- QDeclarativeCompiledData *cc = toCompiledComponent(engine);
- if (cc) {
- component = new QDeclarativeComponent(engine, cc, -1, -1, 0);
- cc->release();
- } else {
- component = new QDeclarativeComponent(engine, 0);
- component->d_func()->url = imports.baseUrl();
- component->d_func()->state.errors = errors;
- }
-
- }
-
- return component;
-}
-
-QDeclarativeCompiledData *
-QDeclarativeCompositeTypeData::toCompiledComponent(QDeclarativeEngine *engine)
-{
- if (status == Complete && !compiledComponent) {
-
- // Build script imports
- foreach (const QDeclarativeScriptParser::Import &import, data.imports()) {
- if (import.type == QDeclarativeScriptParser::Import::Script) {
- QString url = imports.baseUrl().resolved(QUrl(import.uri)).toString();
-
- ScriptReference ref;
- ref.qualifier = import.qualifier;
-
- for (int ii = 0; ii < resources.count(); ++ii) {
- if (resources.at(ii)->url == url) {
- ref.resource = resources.at(ii);
- break;
- }
- }
-
- Q_ASSERT(ref.resource);
-
- scripts << ref;
- }
- }
-
- compiledComponent = new QDeclarativeCompiledData(engine);
- compiledComponent->url = imports.baseUrl();
- compiledComponent->name = compiledComponent->url.toString();
-
- QDeclarativeCompiler compiler;
- if (!compiler.compile(engine, this, compiledComponent)) {
- status = Error;
- errors = compiler.errors();
- compiledComponent->release();
- compiledComponent = 0;
- }
-
- // Data is no longer needed once we have a compiled component
- data.clear();
- }
-
- if (compiledComponent)
- compiledComponent->addref();
-
- return compiledComponent;
-}
-
-QDeclarativeCompositeTypeData::TypeReference::TypeReference()
-: type(0), unit(0)
-{
-}
-
-QDeclarativeCompositeTypeData::ScriptReference::ScriptReference()
-: resource(0)
-{
-}
-
-QDeclarativeCompositeTypeManager::QDeclarativeCompositeTypeManager(QDeclarativeEngine *e)
-: engine(e), redirectCount(0)
-{
-}
-
-QDeclarativeCompositeTypeManager::~QDeclarativeCompositeTypeManager()
-{
- for (Components::Iterator iter = components.begin(); iter != components.end();) {
- (*iter)->release();
- iter = components.erase(iter);
- }
- for (Resources::Iterator iter = resources.begin(); iter != resources.end();) {
- (*iter)->release();
- iter = resources.erase(iter);
- }
-}
-
-QDeclarativeCompositeTypeData *QDeclarativeCompositeTypeManager::get(const QUrl &url)
-{
- Redirects::Iterator redir = redirects.find(url);
- if (redir != redirects.end())
- return get(*redir);
-
- QDeclarativeCompositeTypeData *unit = components.value(url);
-
- if (!unit) {
- unit = new QDeclarativeCompositeTypeData;
- unit->status = QDeclarativeCompositeTypeData::Waiting;
- unit->progress = 0.0;
- unit->imports.setBaseUrl(url);
- components.insert(url, unit);
-
- loadSource(unit);
- }
-
- unit->addref();
- return unit;
-}
-
-QDeclarativeCompositeTypeData *
-QDeclarativeCompositeTypeManager::getImmediate(const QByteArray &data, const QUrl &url)
-{
- QDeclarativeCompositeTypeData *unit = new QDeclarativeCompositeTypeData;
- unit->status = QDeclarativeCompositeTypeData::Waiting;
- unit->imports.setBaseUrl(url);
- setData(unit, data, url);
- return unit;
-}
-
-void QDeclarativeCompositeTypeManager::clearCache()
-{
- for (Components::Iterator iter = components.begin(); iter != components.end();) {
- if ((*iter)->status != QDeclarativeCompositeTypeData::Waiting) {
- (*iter)->release();
- iter = components.erase(iter);
- } else {
- ++iter;
- }
- }
-
- for (Resources::Iterator iter = resources.begin(); iter != resources.end();) {
- if ((*iter)->status != QDeclarativeCompositeTypeResource::Waiting) {
- (*iter)->release();
- iter = resources.erase(iter);
- } else {
- ++iter;
- }
- }
-}
-
-#define TYPEMANAGER_MAXIMUM_REDIRECT_RECURSION 16
-
-void QDeclarativeCompositeTypeManager::replyFinished()
-{
- QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
-
- QDeclarativeCompositeTypeData *unit = components.value(reply->url());
- Q_ASSERT(unit);
-
- redirectCount++;
- if (redirectCount < TYPEMANAGER_MAXIMUM_REDIRECT_RECURSION) {
- QVariant redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
- if (redirect.isValid()) {
- QUrl url = reply->url().resolved(redirect.toUrl());
- redirects.insert(reply->url(),url);
- unit->imports.setBaseUrl(url);
- components.remove(reply->url());
- components.insert(url, unit);
- reply->deleteLater();
- reply = engine->networkAccessManager()->get(QNetworkRequest(url));
- QObject::connect(reply, SIGNAL(finished()),
- this, SLOT(replyFinished()));
- QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
- this, SLOT(requestProgress(qint64,qint64)));
- return;
- }
- }
- redirectCount = 0;
-
- if (reply->error() != QNetworkReply::NoError) {
- QString errorDescription;
- // ### - Fill in error
- errorDescription = QLatin1String("Network error for URL ") +
- reply->url().toString();
-
- unit->status = QDeclarativeCompositeTypeData::Error;
- // ### FIXME
- QDeclarativeError error;
- error.setDescription(errorDescription);
- unit->errorType = QDeclarativeCompositeTypeData::AccessError;
- unit->errors << error;
- doComplete(unit);
-
- } else {
- QByteArray data = reply->readAll();
-
- setData(unit, data, reply->url());
- }
-
- reply->deleteLater();
-}
-
-void QDeclarativeCompositeTypeManager::resourceReplyFinished()
-{
- QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
-
- QDeclarativeCompositeTypeResource *resource = resources.value(reply->url());
- Q_ASSERT(resource);
-
- redirectCount++;
- if (redirectCount < TYPEMANAGER_MAXIMUM_REDIRECT_RECURSION) {
- QVariant redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
- if (redirect.isValid()) {
- QUrl url = reply->url().resolved(redirect.toUrl());
- redirects.insert(reply->url(),url);
- resource->url = url.toString();
- resources.remove(reply->url());
- resources.insert(url, resource);
- reply->deleteLater();
- reply = engine->networkAccessManager()->get(QNetworkRequest(url));
- QObject::connect(reply, SIGNAL(finished()),
- this, SLOT(resourceReplyFinished()));
- return;
- }
- }
- redirectCount = 0;
-
- if (reply->error() != QNetworkReply::NoError) {
-
- resource->status = QDeclarativeCompositeTypeResource::Error;
-
- } else {
-
- resource->status = QDeclarativeCompositeTypeResource::Complete;
- resource->data = reply->readAll();
-
- }
-
- doComplete(resource);
- reply->deleteLater();
-}
-
-void QDeclarativeCompositeTypeManager::loadResource(QDeclarativeCompositeTypeResource *resource)
-{
- QUrl url(resource->url);
-
- QString lf = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url);
- if (!lf.isEmpty()) {
-
- QFile file(lf);
- if (file.open(QFile::ReadOnly)) {
- resource->data = file.readAll();
- resource->status = QDeclarativeCompositeTypeResource::Complete;
- } else {
- resource->status = QDeclarativeCompositeTypeResource::Error;
- }
- } else if (url.scheme().isEmpty()) {
-
- // We can't open this, so just declare as an error
- resource->status = QDeclarativeCompositeTypeResource::Error;
- } else {
-
- QNetworkReply *reply =
- engine->networkAccessManager()->get(QNetworkRequest(url));
- QObject::connect(reply, SIGNAL(finished()),
- this, SLOT(resourceReplyFinished()));
-
- }
-}
-
-void QDeclarativeCompositeTypeManager::loadSource(QDeclarativeCompositeTypeData *unit)
-{
- QUrl url(unit->imports.baseUrl());
-
- QString lf = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url);
- if (!lf.isEmpty()) {
-
- QFile file(lf);
- if (file.open(QFile::ReadOnly)) {
- QByteArray data = file.readAll();
- setData(unit, data, url);
- return; // success
- }
- } else if (!url.scheme().isEmpty()) {
- QNetworkReply *reply =
- engine->networkAccessManager()->get(QNetworkRequest(url));
- QObject::connect(reply, SIGNAL(finished()),
- this, SLOT(replyFinished()));
- QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
- this, SLOT(requestProgress(qint64,qint64)));
- return; // waiting
- }
-
- // error happened
- QString errorDescription;
- // ### - Fill in error
- errorDescription = QLatin1String("File error for URL ") + url.toString();
- unit->status = QDeclarativeCompositeTypeData::Error;
- // ### FIXME
- QDeclarativeError error;
- error.setDescription(errorDescription);
- unit->errorType = QDeclarativeCompositeTypeData::AccessError;
- unit->errors << error;
- doComplete(unit);
-}
-
-void QDeclarativeCompositeTypeManager::requestProgress(qint64 received, qint64 total)
-{
- if (total <= 0)
- return;
- QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
-
- QDeclarativeCompositeTypeData *unit = components.value(reply->url());
- Q_ASSERT(unit);
-
- unit->progress = qreal(received)/total;
-
- foreach (QDeclarativeComponentPrivate *comp, unit->waiters)
- comp->updateProgress(unit->progress);
-}
-
-void QDeclarativeCompositeTypeManager::setData(QDeclarativeCompositeTypeData *unit,
- const QByteArray &data,
- const QUrl &url)
-{
- bool ok = true;
- if (!unit->data.parse(data, url)) {
- ok = false;
- unit->errors << unit->data.errors();
- }
-
- if (ok) {
- compile(unit);
- } else {
- unit->status = QDeclarativeCompositeTypeData::Error;
- unit->errorType = QDeclarativeCompositeTypeData::GeneralError;
- doComplete(unit);
- }
-}
-
-void QDeclarativeCompositeTypeManager::doComplete(QDeclarativeCompositeTypeData *unit)
-{
- for (int ii = 0; ii < unit->dependants.count(); ++ii) {
- checkComplete(unit->dependants.at(ii));
- unit->dependants.at(ii)->release();
- }
- unit->dependants.clear();
-
- while(!unit->waiters.isEmpty()) {
- QDeclarativeComponentPrivate *p = unit->waiters.takeFirst();
- p->typeDataReady();
- }
-}
-
-void QDeclarativeCompositeTypeManager::doComplete(QDeclarativeCompositeTypeResource *resource)
-{
- for (int ii = 0; ii < resource->dependants.count(); ++ii) {
- checkComplete(resource->dependants.at(ii));
- resource->dependants.at(ii)->release();
- }
- resource->dependants.clear();
-}
-
-void QDeclarativeCompositeTypeManager::checkComplete(QDeclarativeCompositeTypeData *unit)
-{
- if (unit->status != QDeclarativeCompositeTypeData::Waiting
- && unit->status != QDeclarativeCompositeTypeData::WaitingResources)
- return;
-
- int waiting = 0;
- for (int ii = 0; ii < unit->resources.count(); ++ii) {
- QDeclarativeCompositeTypeResource *r = unit->resources.at(ii);
-
- if (!r)
- continue;
-
- if (r->status == QDeclarativeCompositeTypeResource::Error) {
- unit->status = QDeclarativeCompositeTypeData::Error;
- QDeclarativeError error;
- error.setUrl(unit->imports.baseUrl());
- error.setDescription(tr("Resource %1 unavailable").arg(r->url));
- unit->errors << error;
- doComplete(unit);
- return;
- } else if (r->status == QDeclarativeCompositeTypeResource::Waiting) {
- waiting++;
- }
- }
-
- if (waiting == 0) {
- if (unit->status == QDeclarativeCompositeTypeData::WaitingResources) {
- waiting += resolveTypes(unit);
- if (unit->status != QDeclarativeCompositeTypeData::Error) {
- if (waiting)
- unit->status = QDeclarativeCompositeTypeData::Waiting;
- } else {
- return;
- }
- } else {
- for (int ii = 0; ii < unit->types.count(); ++ii) {
- QDeclarativeCompositeTypeData *u = unit->types.at(ii).unit;
-
- if (!u)
- continue;
-
- if (u->status == QDeclarativeCompositeTypeData::Error) {
- unit->status = QDeclarativeCompositeTypeData::Error;
- unit->errors = u->errors;
- doComplete(unit);
- return;
- } else if (u->status == QDeclarativeCompositeTypeData::Waiting
- || u->status == QDeclarativeCompositeTypeData::WaitingResources)
- {
- waiting++;
- }
- }
- }
- }
-
- if (!waiting) {
- unit->status = QDeclarativeCompositeTypeData::Complete;
- doComplete(unit);
- }
-}
-
-int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData *unit)
-{
- // not called until all resources are loaded (they include import URLs)
- int waiting = 0;
-
- QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
- QDeclarativeImportDatabase &importDatabase = ep->importDatabase;
-
- // For local urls, add an implicit import "." as first (most overridden) lookup.
- // This will also trigger the loading of the qmldir and the import of any native
- // types from available plugins.
- {
- QDeclarativeDirComponents qmldircomponentsnetwork;
- if (QDeclarativeCompositeTypeResource *resource
- = resources.value(unit->imports.baseUrl().resolved(QUrl(QLatin1String("./qmldir"))))) {
- QDeclarativeDirParser parser;
- parser.setSource(QString::fromUtf8(resource->data));
- parser.parse();
- qmldircomponentsnetwork = parser.components();
- }
-
- importDatabase.addToImport(&unit->imports, qmldircomponentsnetwork, QLatin1String("."),
- QString(), -1, -1, QDeclarativeScriptParser::Import::File,
- 0); // error ignored (just means no fallback)
- }
-
-
- foreach (const QDeclarativeScriptParser::Import &imp, unit->data.imports()) {
- QDeclarativeDirComponents qmldircomponentsnetwork;
- if (imp.type == QDeclarativeScriptParser::Import::Script)
- continue;
-
- if (imp.type == QDeclarativeScriptParser::Import::File && imp.qualifier.isEmpty()) {
- QString importUrl = unit->imports.baseUrl().resolved(QUrl(imp.uri + QLatin1String("/qmldir"))).toString();
- for (int ii = 0; ii < unit->resources.count(); ++ii) {
- if (unit->resources.at(ii)->url == importUrl) {
- QDeclarativeDirParser parser;
- parser.setSource(QString::fromUtf8(unit->resources.at(ii)->data));
- parser.parse();
- qmldircomponentsnetwork = parser.components();
- break;
- }
- }
- }
-
-
- int vmaj = -1;
- int vmin = -1;
- if (!imp.version.isEmpty()) {
- int dot = imp.version.indexOf(QLatin1Char('.'));
- if (dot < 0) {
- vmaj = imp.version.toInt();
- vmin = 0;
- } else {
- vmaj = imp.version.left(dot).toInt();
- vmin = imp.version.mid(dot+1).toInt();
- }
- }
-
- QString errorString;
- if (!importDatabase.addToImport(&unit->imports, qmldircomponentsnetwork, imp.uri, imp.qualifier,
- vmaj, vmin, imp.type, &errorString)) {
- QDeclarativeError error;
- error.setUrl(unit->imports.baseUrl());
- error.setDescription(errorString);
- error.setLine(imp.location.start.line);
- error.setColumn(imp.location.start.column);
- unit->status = QDeclarativeCompositeTypeData::Error;
- unit->errorType = QDeclarativeCompositeTypeData::GeneralError;
- unit->errors << error;
- doComplete(unit);
- return 0;
- }
- }
-
-
- QList<QDeclarativeScriptParser::TypeReference*> types = unit->data.referencedTypes();
-
- for (int ii = 0; ii < types.count(); ++ii) {
- QDeclarativeScriptParser::TypeReference *parserRef = types.at(ii);
- QByteArray typeName = parserRef->name.toUtf8();
-
- QDeclarativeCompositeTypeData::TypeReference ref;
-
- QUrl url;
- int majorVersion;
- int minorVersion;
- QDeclarativeImportedNamespace *typeNamespace = 0;
- QString errorString;
- if (!importDatabase.resolveType(unit->imports, typeName, &ref.type, &url, &majorVersion, &minorVersion,
- &typeNamespace, &errorString) || typeNamespace) {
- // Known to not be a type:
- // - known to be a namespace (Namespace {})
- // - type with unknown namespace (UnknownNamespace.SomeType {})
- QDeclarativeError error;
- error.setUrl(unit->imports.baseUrl());
- QString userTypeName = QString::fromUtf8(typeName);
- userTypeName.replace(QLatin1Char('/'),QLatin1Char('.'));
- if (typeNamespace)
- error.setDescription(tr("Namespace %1 cannot be used as a type").arg(userTypeName));
- else
- error.setDescription(tr("%1 %2").arg(userTypeName).arg(errorString));
-
- if (!parserRef->refObjects.isEmpty()) {
- QDeclarativeParser::Object *obj = parserRef->refObjects.first();
- error.setLine(obj->location.start.line);
- error.setColumn(obj->location.start.column);
- }
- unit->status = QDeclarativeCompositeTypeData::Error;
- unit->errorType = QDeclarativeCompositeTypeData::GeneralError;
- unit->errors << error;
- doComplete(unit);
- return 0;
- }
-
- if (ref.type) {
- foreach (QDeclarativeParser::Object *obj, parserRef->refObjects) {
- // store namespace for DOM
- obj->majorVersion = majorVersion;
- obj->minorVersion = minorVersion;
- }
- unit->types << ref;
- continue;
- }
-
- Redirects::Iterator redir = redirects.find(url);
- if (redir != redirects.end())
- url = *redir;
-
- QDeclarativeCompositeTypeData *urlUnit = components.value(url);
-
- if (!urlUnit) {
- urlUnit = new QDeclarativeCompositeTypeData;
- urlUnit->status = QDeclarativeCompositeTypeData::Waiting;
- urlUnit->imports.setBaseUrl(url);
- components.insert(url, urlUnit);
-
- loadSource(urlUnit);
- }
-
- ref.unit = urlUnit;
- switch(urlUnit->status) {
- case QDeclarativeCompositeTypeData::Invalid:
- case QDeclarativeCompositeTypeData::Error:
- unit->status = QDeclarativeCompositeTypeData::Error;
- {
- QDeclarativeError error;
- error.setUrl(unit->imports.baseUrl());
- error.setDescription(tr("Type %1 unavailable").arg(QString::fromUtf8(typeName)));
- if (!parserRef->refObjects.isEmpty()) {
- QDeclarativeParser::Object *obj = parserRef->refObjects.first();
- error.setLine(obj->location.start.line);
- error.setColumn(obj->location.start.column);
- }
- unit->errors << error;
- }
- if (urlUnit->errorType != QDeclarativeCompositeTypeData::AccessError)
- unit->errors << urlUnit->errors;
- doComplete(unit);
- return 0;
-
- case QDeclarativeCompositeTypeData::Complete:
- break;
-
- case QDeclarativeCompositeTypeData::Waiting:
- case QDeclarativeCompositeTypeData::WaitingResources:
- unit->addref();
- ref.unit->dependants << unit;
- waiting++;
- break;
- }
-
- unit->types << ref;
- }
- return waiting;
-}
-
-// ### Check ref counting in here
-void QDeclarativeCompositeTypeManager::compile(QDeclarativeCompositeTypeData *unit)
-{
- int waiting = 0;
-
- QList<QUrl> resourceList = unit->data.referencedResources();
-
- foreach (QDeclarativeScriptParser::Import imp, unit->data.imports()) {
- if (imp.type == QDeclarativeScriptParser::Import::File && imp.qualifier.isEmpty()) {
- QUrl importUrl = unit->imports.baseUrl().resolved(QUrl(imp.uri + QLatin1String("/qmldir")));
- if (QDeclarativeEnginePrivate::urlToLocalFileOrQrc(importUrl).isEmpty()) {
- // Import requires remote qmldir
- resourceList.prepend(importUrl);
- }
- }
- }
-
- QUrl importUrl;
- if (!unit->imports.baseUrl().scheme().isEmpty())
- importUrl = unit->imports.baseUrl().resolved(QUrl(QLatin1String("qmldir")));
- if (!importUrl.scheme().isEmpty() && QDeclarativeEnginePrivate::urlToLocalFileOrQrc(importUrl).isEmpty())
- resourceList.prepend(importUrl);
-
- for (int ii = 0; ii < resourceList.count(); ++ii) {
- QUrl url = unit->imports.baseUrl().resolved(resourceList.at(ii));
-
- QDeclarativeCompositeTypeResource *resource = resources.value(url);
-
- if (!resource) {
- resource = new QDeclarativeCompositeTypeResource;
- resource->status = QDeclarativeCompositeTypeResource::Waiting;
- resource->url = url.toString();
- resources.insert(url, resource);
-
- loadResource(resource);
- }
-
- switch(resource->status) {
- case QDeclarativeCompositeTypeResource::Invalid:
- case QDeclarativeCompositeTypeResource::Error:
- unit->status = QDeclarativeCompositeTypeData::Error;
- {
- QDeclarativeError error;
- error.setUrl(unit->imports.baseUrl());
- error.setDescription(tr("Resource %1 unavailable").arg(resource->url));
- unit->errors << error;
- }
- doComplete(unit);
- return;
-
- case QDeclarativeCompositeTypeData::Complete:
- break;
-
- case QDeclarativeCompositeTypeData::Waiting:
- unit->addref();
- resource->dependants << unit;
- waiting++;
- break;
- }
-
- resource->addref();
- unit->resources << resource;
- }
-
- if (waiting == 0) {
- waiting += resolveTypes(unit);
- if (unit->status != QDeclarativeCompositeTypeData::Error) {
- if (!waiting) {
- unit->status = QDeclarativeCompositeTypeData::Complete;
- doComplete(unit);
- } else {
- unit->status = QDeclarativeCompositeTypeData::Waiting;
- }
- }
- } else {
- unit->status = QDeclarativeCompositeTypeData::WaitingResources;
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecompositetypemanager_p.h b/src/declarative/qml/qdeclarativecompositetypemanager_p.h
deleted file mode 100644
index 5c82c4c..0000000
--- a/src/declarative/qml/qdeclarativecompositetypemanager_p.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDECLARATIVECOMPOSITETYPEMANAGER_P_H
-#define QDECLARATIVECOMPOSITETYPEMANAGER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qdeclarativescriptparser_p.h"
-#include "private/qdeclarativerefcount_p.h"
-#include "qdeclarativeerror.h"
-#include "qdeclarativeengine.h"
-
-#include <QtCore/qglobal.h>
-
-QT_BEGIN_NAMESPACE
-
-class QDeclarativeCompiledData;
-class QDeclarativeComponentPrivate;
-class QDeclarativeComponent;
-class QDeclarativeDomDocument;
-
-class QDeclarativeCompositeTypeData;
-class QDeclarativeCompositeTypeResource;
-
-class QDeclarativeCompositeTypeManager : public QObject
-{
- Q_OBJECT
-public:
- QDeclarativeCompositeTypeManager(QDeclarativeEngine *);
- ~QDeclarativeCompositeTypeManager();
-
- // Return a QDeclarativeCompositeTypeData for url. The QDeclarativeCompositeTypeData may be
- // cached.
- QDeclarativeCompositeTypeData *get(const QUrl &url);
- // Return a QDeclarativeCompositeTypeData for data, with the provided base url. The
- // QDeclarativeCompositeTypeData will not be cached.
- QDeclarativeCompositeTypeData *getImmediate(const QByteArray &data, const QUrl &url);
-
- // Clear cached types. Only types that aren't in the Waiting state will
- // be cleared.
- void clearCache();
-
-private Q_SLOTS:
- void replyFinished();
- void resourceReplyFinished();
- void requestProgress(qint64 received, qint64 total);
-
-private:
- void loadSource(QDeclarativeCompositeTypeData *);
- void loadResource(QDeclarativeCompositeTypeResource *);
- void compile(QDeclarativeCompositeTypeData *);
- void setData(QDeclarativeCompositeTypeData *, const QByteArray &, const QUrl &);
-
- void doComplete(QDeclarativeCompositeTypeData *);
- void doComplete(QDeclarativeCompositeTypeResource *);
- void checkComplete(QDeclarativeCompositeTypeData *);
- int resolveTypes(QDeclarativeCompositeTypeData *);
-
- QDeclarativeEngine *engine;
- typedef QHash<QUrl, QDeclarativeCompositeTypeData *> Components;
- Components components;
- typedef QHash<QUrl, QDeclarativeCompositeTypeResource *> Resources;
- Resources resources;
- typedef QHash<QUrl, QUrl> Redirects;
- Redirects redirects;
- int redirectCount;
-};
-
-QT_END_NAMESPACE
-
-#endif // QDECLARATIVECOMPOSITETYPEMANAGER_P_H
-
diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp
index a3b16d9..de45a95 100644
--- a/src/declarative/qml/qdeclarativecontext.cpp
+++ b/src/declarative/qml/qdeclarativecontext.cpp
@@ -660,14 +660,12 @@ void QDeclarativeContextData::addImportedScript(const QDeclarativeParser::Object
if (!engine)
return;
- Q_ASSERT(script.codes.count() == 1);
-
QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine);
QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
- const QString &code = script.codes.at(0);
- const QString &url = script.files.at(0);
- const QDeclarativeParser::Object::ScriptBlock::Pragmas &pragmas = script.pragmas.at(0);
+ const QString &code = script.code;
+ const QString &url = script.file;
+ const QDeclarativeParser::Object::ScriptBlock::Pragmas &pragmas = script.pragmas;
Q_ASSERT(!url.isEmpty());
diff --git a/src/declarative/qml/qdeclarativedom.cpp b/src/declarative/qml/qdeclarativedom.cpp
index 5b30bde..1a9b501 100644
--- a/src/declarative/qml/qdeclarativedom.cpp
+++ b/src/declarative/qml/qdeclarativedom.cpp
@@ -42,7 +42,6 @@
#include "private/qdeclarativedom_p.h"
#include "private/qdeclarativedom_p_p.h"
-#include "private/qdeclarativecompositetypedata_p.h"
#include "private/qdeclarativecompiler_p.h"
#include "private/qdeclarativeengine_p.h"
#include "private/qdeclarativescriptparser_p.h"
@@ -145,37 +144,23 @@ bool QDeclarativeDomDocument::load(QDeclarativeEngine *engine, const QByteArray
d->errors.clear();
d->imports.clear();
- QDeclarativeCompiledData *component = new QDeclarativeCompiledData(engine);
- QDeclarativeCompiler compiler;
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
+ QDeclarativeTypeData *td = ep->typeLoader.get(data, url, QDeclarativeTypeLoader::PreserveParser);
- QDeclarativeCompositeTypeData *td = ((QDeclarativeEnginePrivate *)QDeclarativeEnginePrivate::get(engine))->typeManager.getImmediate(data, url);
-
- if(td->status == QDeclarativeCompositeTypeData::Error) {
- d->errors = td->errors;
+ if(td->isError()) {
+ d->errors = td->errors();
td->release();
- component->release();
return false;
- } else if(td->status == QDeclarativeCompositeTypeData::Waiting ||
- td->status == QDeclarativeCompositeTypeData::WaitingResources) {
+ } else if(!td->isCompleteOrError()) {
QDeclarativeError error;
error.setDescription(QLatin1String("QDeclarativeDomDocument supports local types only"));
d->errors << error;
td->release();
- component->release();
- return false;
- }
-
- compiler.compile(engine, td, component);
-
- if (compiler.isError()) {
- d->errors = compiler.errors();
- td->release();
- component->release();
return false;
}
- for (int i = 0; i < td->data.imports().size(); ++i) {
- QDeclarativeScriptParser::Import parserImport = td->data.imports().at(i);
+ for (int i = 0; i < td->parser().imports().size(); ++i) {
+ QDeclarativeScriptParser::Import parserImport = td->parser().imports().at(i);
QDeclarativeDomImport domImport;
domImport.d->type = static_cast<QDeclarativeDomImportPrivate::Type>(parserImport.type);
domImport.d->uri = parserImport.uri;
@@ -184,12 +169,12 @@ bool QDeclarativeDomDocument::load(QDeclarativeEngine *engine, const QByteArray
d->imports += domImport;
}
- if (td->data.tree()) {
- d->root = td->data.tree();
+ if (td->parser().tree()) {
+ d->root = td->parser().tree();
d->root->addref();
}
- component->release();
+ td->release();
return true;
}
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp
index 4d244c5..dd8e9cd 100644
--- a/src/declarative/qml/qdeclarativeengine.cpp
+++ b/src/declarative/qml/qdeclarativeengine.cpp
@@ -259,7 +259,7 @@ QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
objectClass(0), valueTypeClass(0), globalClass(0), cleanup(0), erroredBindings(0),
inProgressCreations(0), scriptEngine(this), workerScriptEngine(0), componentAttached(0),
inBeginCreate(false), networkAccessManager(0), networkAccessManagerFactory(0),
- typeManager(e), importDatabase(e), uniqueId(1)
+ typeLoader(e), importDatabase(e), uniqueId(1)
{
if (!qt_QmlQtModule_registered) {
qt_QmlQtModule_registered = true;
@@ -272,8 +272,8 @@ QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
}
/*!
- \qmlmethod url Qt::resolvedUrl(url)
- Returns \c url resolved relative to the URL of the caller.
+ \qmlmethod url Qt::resolvedUrl(url url)
+ Returns \a url resolved relative to the URL of the caller.
*/
QUrl QDeclarativeScriptEngine::resolvedUrl(QScriptContext *context, const QUrl& url)
{
@@ -565,7 +565,7 @@ QDeclarativeEngine::~QDeclarativeEngine()
void QDeclarativeEngine::clearComponentCache()
{
Q_D(QDeclarativeEngine);
- d->typeManager.clearCache();
+ d->typeLoader.clearCache();
}
/*!
@@ -1716,6 +1716,9 @@ void QDeclarativeEnginePrivate::sendQuit()
{
Q_Q(QDeclarativeEngine);
emit q->quit();
+ if (q->receivers(SIGNAL(quit())) == 0) {
+ qWarning("Signal QDeclarativeEngine::quit() emitted, but no receivers connected to handle it.");
+ }
}
static void dumpwarning(const QDeclarativeError &error)
@@ -2110,7 +2113,7 @@ bool QDeclarativeEnginePrivate::isQObject(int t)
QObject *QDeclarativeEnginePrivate::toQObject(const QVariant &v, bool *ok) const
{
int t = v.userType();
- if (m_compositeTypes.contains(t)) {
+ if (t == QMetaType::QObjectStar || m_compositeTypes.contains(t)) {
if (ok) *ok = true;
return *(QObject **)(v.constData());
} else {
diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h
index db2db35..dc7315d 100644
--- a/src/declarative/qml/qdeclarativeengine_p.h
+++ b/src/declarative/qml/qdeclarativeengine_p.h
@@ -56,7 +56,7 @@
#include "qdeclarativeengine.h"
#include "private/qdeclarativeclassfactory_p.h"
-#include "private/qdeclarativecompositetypemanager_p.h"
+#include "private/qdeclarativetypeloader_p.h"
#include "private/qdeclarativeimport_p.h"
#include "private/qpodvector_p.h"
#include "qdeclarative.h"
@@ -239,7 +239,7 @@ public:
mutable QMutex mutex;
- QDeclarativeCompositeTypeManager typeManager;
+ QDeclarativeTypeLoader typeLoader;
QDeclarativeImportDatabase importDatabase;
QString offlineStoragePath;
diff --git a/src/declarative/qml/qdeclarativeimport.cpp b/src/declarative/qml/qdeclarativeimport.cpp
index 5c21ebc..8f95e26 100644
--- a/src/declarative/qml/qdeclarativeimport.cpp
+++ b/src/declarative/qml/qdeclarativeimport.cpp
@@ -109,6 +109,11 @@ public:
QHash<QString,QDeclarativeImportedNamespace* > set;
};
+/*!
+\class QDeclarativeImports
+\brief The QDeclarativeImports class encapsulates one QML document's import statements.
+\internal
+*/
QDeclarativeImports::QDeclarativeImports(const QDeclarativeImports &copy)
: d(copy.d)
{
@@ -181,7 +186,7 @@ cacheForNamespace(QDeclarativeEngine *engine, const QDeclarativeImportedNamespac
return cache;
}
-void QDeclarativeImports::cache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *engine) const
+void QDeclarativeImports::populateCache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *engine) const
{
const QDeclarativeImportedNamespace &set = d->unqualifiedset;
@@ -201,6 +206,67 @@ void QDeclarativeImports::cache(QDeclarativeTypeNameCache *cache, QDeclarativeEn
cacheForNamespace(engine, set, cache);
}
+
+/*!
+ \internal
+
+ The given (namespace qualified) \a type is resolved to either
+ \list
+ \o a QDeclarativeImportedNamespace stored at \a ns_return,
+ \o a QDeclarativeType stored at \a type_return, or
+ \o a component located at \a url_return.
+ \endlist
+
+ If any return pointer is 0, the corresponding search is not done.
+
+ \sa addImport()
+*/
+bool QDeclarativeImports::resolveType(const QByteArray& type,
+ QDeclarativeType** type_return, QUrl* url_return, int *vmaj, int *vmin,
+ QDeclarativeImportedNamespace** ns_return, QString *errorString) const
+{
+ QDeclarativeImportedNamespace* ns = d->findNamespace(QString::fromUtf8(type));
+ if (ns) {
+ if (ns_return)
+ *ns_return = ns;
+ return true;
+ }
+ if (type_return || url_return) {
+ if (d->find(type,vmaj,vmin,type_return,url_return, errorString)) {
+ if (qmlImportTrace()) {
+ if (type_return && *type_return && url_return && !url_return->isEmpty())
+ qDebug().nospace() << "QDeclarativeImports(" << qPrintable(baseUrl().toString()) << ")" << "::resolveType: "
+ << type << " => " << (*type_return)->typeName() << " " << *url_return;
+ if (type_return && *type_return)
+ qDebug().nospace() << "QDeclarativeImports(" << qPrintable(baseUrl().toString()) << ")" << "::resolveType: "
+ << type << " => " << (*type_return)->typeName();
+ if (url_return && !url_return->isEmpty())
+ qDebug().nospace() << "QDeclarativeImports(" << qPrintable(baseUrl().toString()) << ")" << "::resolveType: "
+ << type << " => " << *url_return;
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+/*!
+ \internal
+
+ Searching \e only in the namespace \a ns (previously returned in a call to
+ resolveType(), \a type is found and returned to either
+ a QDeclarativeType stored at \a type_return, or
+ a component located at \a url_return.
+
+ If either return pointer is 0, the corresponding search is not done.
+*/
+bool QDeclarativeImports::resolveType(QDeclarativeImportedNamespace* ns, const QByteArray& type,
+ QDeclarativeType** type_return, QUrl* url_return,
+ int *vmaj, int *vmin) const
+{
+ return ns->find(type,vmaj,vmin,type_return,url_return);
+}
+
bool QDeclarativeImportedNamespace::find_helper(int i, const QByteArray& type, int *vmajor, int *vminor,
QDeclarativeType** type_return, QUrl* url_return,
QUrl *base, bool *typeRecursionDetected)
@@ -280,15 +346,16 @@ QDeclarativeImportsPrivate::~QDeclarativeImportsPrivate()
}
bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath, const QString &uri,
- QDeclarativeImportDatabase *database,
- QDeclarativeDirComponents* components, QString *errorString)
+ QDeclarativeImportDatabase *database,
+ QDeclarativeDirComponents* components, QString *errorString)
{
QFile file(absoluteFilePath);
QString filecontent;
if (file.open(QFile::ReadOnly)) {
filecontent = QString::fromUtf8(file.readAll());
if (qmlImportTrace())
- qDebug() << "QDeclarativeImportDatabase::add: loaded" << absoluteFilePath;
+ qDebug().nospace() << "QDeclarativeImports(" << qPrintable(base.toString()) << "::importExtension: "
+ << "loaded " << absoluteFilePath;
} else {
if (errorString)
*errorString = QDeclarativeImportDatabase::tr("module \"%1\" definition \"%2\" not readable").arg(uri).arg(absoluteFilePath);
@@ -576,6 +643,10 @@ bool QDeclarativeImportedNamespace::find(const QByteArray& type, int *vmajor, in
return false;
}
+/*!
+\class QDeclarativeImportDatabase
+\brief The QDeclarativeImportDatabase class manages the QML imports for a QDeclarativeEngine.
+*/
QDeclarativeImportDatabase::QDeclarativeImportDatabase(QDeclarativeEngine *e)
: engine(e)
{
@@ -619,75 +690,19 @@ QDeclarativeImportDatabase::~QDeclarativeImportDatabase()
The base URL must already have been set with Import::setBaseUrl().
*/
-bool QDeclarativeImportDatabase::addToImport(QDeclarativeImports* imports,
- const QDeclarativeDirComponents &qmldircomponentsnetwork,
- const QString& uri, const QString& prefix, int vmaj, int vmin,
- QDeclarativeScriptParser::Import::Type importType,
- QString *errorString)
+bool QDeclarativeImports::addImport(QDeclarativeImportDatabase *importDb,
+ const QString& uri, const QString& prefix, int vmaj, int vmin,
+ QDeclarativeScriptParser::Import::Type importType,
+ const QDeclarativeDirComponents &qmldircomponentsnetwork,
+ QString *errorString)
{
if (qmlImportTrace())
- qDebug().nospace() << "QDeclarativeImportDatabase::addToImport " << imports << " " << uri << " "
- << vmaj << '.' << vmin << " "
+ qDebug().nospace() << "QDeclarativeImports(" << qPrintable(baseUrl().toString()) << ")" << "::addImport: "
+ << uri << " " << vmaj << '.' << vmin << " "
<< (importType==QDeclarativeScriptParser::Import::Library? "Library" : "File")
<< " as " << prefix;
- bool ok = imports->d->add(qmldircomponentsnetwork, uri, prefix, vmaj, vmin, importType, this, errorString);
- return ok;
-}
-
-/*!
- \internal
-
- Using the given \a imports, the given (namespace qualified) \a type is resolved to either
- a QDeclarativeImportedNamespace stored at \a ns_return,
- a QDeclarativeType stored at \a type_return, or
- a component located at \a url_return.
-
- If any return pointer is 0, the corresponding search is not done.
-
- \sa addToImport()
-*/
-bool QDeclarativeImportDatabase::resolveType(const QDeclarativeImports& imports, const QByteArray& type,
- QDeclarativeType** type_return, QUrl* url_return, int *vmaj, int *vmin,
- QDeclarativeImportedNamespace** ns_return, QString *errorString) const
-{
- QDeclarativeImportedNamespace* ns = imports.d->findNamespace(QString::fromUtf8(type));
- if (ns) {
- if (ns_return)
- *ns_return = ns;
- return true;
- }
- if (type_return || url_return) {
- if (imports.d->find(type,vmaj,vmin,type_return,url_return, errorString)) {
- if (qmlImportTrace()) {
- if (type_return && *type_return && url_return && !url_return->isEmpty())
- qDebug() << "QDeclarativeImportDatabase::resolveType" << type << '=' << (*type_return)->typeName() << *url_return;
- if (type_return && *type_return)
- qDebug() << "QDeclarativeImportDatabase::resolveType" << type << '=' << (*type_return)->typeName();
- if (url_return && !url_return->isEmpty())
- qDebug() << "QDeclarativeImportDatabase::resolveType" << type << '=' << *url_return;
- }
- return true;
- }
- }
- return false;
-}
-
-/*!
- \internal
-
- Searching \e only in the namespace \a ns (previously returned in a call to
- resolveType(), \a type is found and returned to either
- a QDeclarativeType stored at \a type_return, or
- a component located at \a url_return.
-
- If either return pointer is 0, the corresponding search is not done.
-*/
-bool QDeclarativeImportDatabase::resolveTypeInNamespace(QDeclarativeImportedNamespace* ns, const QByteArray& type,
- QDeclarativeType** type_return, QUrl* url_return,
- int *vmaj, int *vmin) const
-{
- return ns->find(type,vmaj,vmin,type_return,url_return);
+ return d->add(qmldircomponentsnetwork, uri, prefix, vmaj, vmin, importType, importDb, errorString);
}
/*!
@@ -834,7 +849,7 @@ void QDeclarativeImportDatabase::setPluginPathList(const QStringList &paths)
void QDeclarativeImportDatabase::addPluginPath(const QString& path)
{
if (qmlImportTrace())
- qDebug() << "QDeclarativeImportDatabase::addPluginPath" << path;
+ qDebug().nospace() << "QDeclarativeImportDatabase::addPluginPath: " << path;
QUrl url = QUrl(path);
if (url.isRelative() || url.scheme() == QLatin1String("file")) {
@@ -848,7 +863,7 @@ void QDeclarativeImportDatabase::addPluginPath(const QString& path)
void QDeclarativeImportDatabase::addImportPath(const QString& path)
{
if (qmlImportTrace())
- qDebug() << "QDeclarativeImportDatabase::addImportPath" << path;
+ qDebug().nospace() << "QDeclarativeImportDatabase::addImportPath: " << path;
if (path.isEmpty())
return;
@@ -882,7 +897,7 @@ void QDeclarativeImportDatabase::setImportPathList(const QStringList &paths)
bool QDeclarativeImportDatabase::importPlugin(const QString &filePath, const QString &uri, QString *errorString)
{
if (qmlImportTrace())
- qDebug() << "QDeclarativeImportDatabase::importPlugin" << uri << "from" << filePath;
+ qDebug().nospace() << "QDeclarativeImportDatabase::importPlugin: " << uri << " from " << filePath;
QFileInfo fileInfo(filePath);
const QString absoluteFilePath = fileInfo.absoluteFilePath();
diff --git a/src/declarative/qml/qdeclarativeimport_p.h b/src/declarative/qml/qdeclarativeimport_p.h
index 88246d4..84802de 100644
--- a/src/declarative/qml/qdeclarativeimport_p.h
+++ b/src/declarative/qml/qdeclarativeimport_p.h
@@ -65,9 +65,10 @@ QT_BEGIN_NAMESPACE
class QDeclarativeTypeNameCache;
class QDeclarativeEngine;
class QDir;
-
class QDeclarativeImportedNamespace;
class QDeclarativeImportsPrivate;
+class QDeclarativeImportDatabase;
+
class QDeclarativeImports
{
public:
@@ -79,7 +80,24 @@ public:
void setBaseUrl(const QUrl &url);
QUrl baseUrl() const;
- void cache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *) const;
+ bool resolveType(const QByteArray& type,
+ QDeclarativeType** type_return, QUrl* url_return,
+ int *version_major, int *version_minor,
+ QDeclarativeImportedNamespace** ns_return,
+ QString *errorString = 0) const;
+ bool resolveType(QDeclarativeImportedNamespace*,
+ const QByteArray& type,
+ QDeclarativeType** type_return, QUrl* url_return,
+ int *version_major, int *version_minor) const;
+
+ bool addImport(QDeclarativeImportDatabase *,
+ const QString& uri, const QString& prefix, int vmaj, int vmin,
+ QDeclarativeScriptParser::Import::Type importType,
+ const QDeclarativeDirComponents &qmldircomponentsnetwork,
+ QString *errorString);
+
+ void populateCache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *) const;
+
private:
friend class QDeclarativeImportDatabase;
QDeclarativeImportsPrivate *d;
@@ -102,21 +120,6 @@ public:
void setPluginPathList(const QStringList &paths);
void addPluginPath(const QString& path);
-
- bool addToImport(QDeclarativeImports*, const QDeclarativeDirComponents &qmldircomponentsnetwork,
- const QString& uri, const QString& prefix, int vmaj, int vmin,
- QDeclarativeScriptParser::Import::Type importType,
- QString *errorString);
- bool resolveType(const QDeclarativeImports&, const QByteArray& type,
- QDeclarativeType** type_return, QUrl* url_return,
- int *version_major, int *version_minor,
- QDeclarativeImportedNamespace** ns_return,
- QString *errorString = 0) const;
- bool resolveTypeInNamespace(QDeclarativeImportedNamespace*, const QByteArray& type,
- QDeclarativeType** type_return, QUrl* url_return,
- int *version_major, int *version_minor ) const;
-
-
private:
friend class QDeclarativeImportsPrivate;
QString resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath,
diff --git a/src/declarative/qml/qdeclarativeinclude.cpp b/src/declarative/qml/qdeclarativeinclude.cpp
index f26b54f..1e240d7 100644
--- a/src/declarative/qml/qdeclarativeinclude.cpp
+++ b/src/declarative/qml/qdeclarativeinclude.cpp
@@ -173,7 +173,7 @@ void QDeclarativeInclude::callback(QScriptEngine *engine, QScriptValue &callback
}
/*!
-\qmlmethod object Qt::include(url, callback)
+\qmlmethod object Qt::include(string url, jsobject callback)
Include another JavaScript file. This method can only be used from within JavaScript files,
and not regular QML files.
diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
index 3af892d..9d74238 100644
--- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
+++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
@@ -192,7 +192,7 @@ QDeclarativeObjectScriptClass::queryProperty(QObject *obj, const Identifier &nam
if (!(hints & ImplicitObject)) {
local.coreIndex = -1;
lastData = &local;
- return QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess;
+ return QScriptClass::HandlesWriteAccess;
}
return 0;
@@ -625,11 +625,12 @@ private:
char data[4 * sizeof(void *)];
int type;
+ bool isObjectType;
};
}
MetaCallArgument::MetaCallArgument()
-: type(QVariant::Invalid)
+: type(QVariant::Invalid), isObjectType(false)
{
}
@@ -744,12 +745,23 @@ void MetaCallArgument::fromScriptValue(int callType, QDeclarativeEngine *engine,
new (&data) QVariant();
type = -1;
- QVariant v = QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value);
+ QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(engine);
+ QVariant v = priv->scriptValueToVariant(value);
if (v.userType() == callType) {
*((QVariant *)&data) = v;
} else if (v.canConvert((QVariant::Type)callType)) {
*((QVariant *)&data) = v;
((QVariant *)&data)->convert((QVariant::Type)callType);
+ } else if (const QMetaObject *mo = priv->rawMetaObjectForType(callType)) {
+ QObject *obj = priv->toQObject(v);
+
+ if (obj) {
+ const QMetaObject *objMo = obj->metaObject();
+ while (objMo && objMo != mo) objMo = objMo->superClass();
+ if (!objMo) obj = 0;
+ }
+
+ *((QVariant *)&data) = QVariant(callType, &obj);
} else {
*((QVariant *)&data) = QVariant(callType, (void *)0);
}
diff --git a/src/declarative/qml/qdeclarativeparser_p.h b/src/declarative/qml/qdeclarativeparser_p.h
index d192f3a..c58aebc 100644
--- a/src/declarative/qml/qdeclarativeparser_p.h
+++ b/src/declarative/qml/qdeclarativeparser_p.h
@@ -183,10 +183,9 @@ namespace QDeclarativeParser
};
Q_DECLARE_FLAGS(Pragmas, Pragma)
- QStringList codes;
- QStringList files;
- QList<int> lineNumbers;
- QList<Pragmas> pragmas;
+ QString code;
+ QString file;
+ Pragmas pragmas;
};
// The bytes to cast instances by to get to the QDeclarativeParserStatus
diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp
index 515c4d6..d0dd2e8 100644
--- a/src/declarative/qml/qdeclarativeproperty.cpp
+++ b/src/declarative/qml/qdeclarativeproperty.cpp
@@ -42,7 +42,6 @@
#include "qdeclarativeproperty.h"
#include "private/qdeclarativeproperty_p.h"
-#include "private/qdeclarativecompositetypedata_p.h"
#include "qdeclarative.h"
#include "private/qdeclarativebinding_p.h"
#include "qdeclarativecontext.h"
diff --git a/src/declarative/qml/qdeclarativepropertycache.cpp b/src/declarative/qml/qdeclarativepropertycache.cpp
index 839d79f..08503c2 100644
--- a/src/declarative/qml/qdeclarativepropertycache.cpp
+++ b/src/declarative/qml/qdeclarativepropertycache.cpp
@@ -134,8 +134,9 @@ QDeclarativePropertyCache::~QDeclarativePropertyCache()
void QDeclarativePropertyCache::clear()
{
- for (int ii = 0; ii < indexCache.count(); ++ii)
- indexCache.at(ii)->release();
+ for (int ii = 0; ii < indexCache.count(); ++ii) {
+ if (indexCache.at(ii)) indexCache.at(ii)->release();
+ }
for (StringCache::ConstIterator iter = stringCache.begin();
iter != stringCache.end(); ++iter)
@@ -156,14 +157,27 @@ QDeclarativePropertyCache::Data QDeclarativePropertyCache::create(const QMetaObj
Q_ASSERT(metaObject);
QDeclarativePropertyCache::Data rv;
- int idx = metaObject->indexOfProperty(property.toUtf8());
- if (idx != -1) {
- rv.load(metaObject->property(idx));
- return rv;
+ {
+ const QMetaObject *cmo = metaObject;
+ while (cmo) {
+ int idx = metaObject->indexOfProperty(property.toUtf8());
+ if (idx != -1) {
+ QMetaProperty p = metaObject->property(idx);
+ if (p.isScriptable()) {
+ rv.load(metaObject->property(idx));
+ return rv;
+ } else {
+ while (cmo && cmo->propertyOffset() >= idx)
+ cmo = cmo->superClass();
+ }
+ } else {
+ cmo = 0;
+ }
+ }
}
int methodCount = metaObject->methodCount();
- for (int ii = methodCount - 1; ii >= 2; --ii) { // >=2 to block the destroyed signal
+ for (int ii = methodCount - 1; ii >= 3; --ii) { // >=3 to block the destroyed signal and deleteLater() slot
QMetaMethod m = metaObject->method(ii);
if (m.access() == QMetaMethod::Private)
continue;
@@ -189,8 +203,9 @@ QDeclarativePropertyCache *QDeclarativePropertyCache::copy() const
cache->stringCache = stringCache;
cache->identifierCache = identifierCache;
- for (int ii = 0; ii < indexCache.count(); ++ii)
- indexCache.at(ii)->addref();
+ for (int ii = 0; ii < indexCache.count(); ++ii) {
+ if (indexCache.at(ii)) indexCache.at(ii)->addref();
+ }
for (StringCache::ConstIterator iter = stringCache.begin(); iter != stringCache.end(); ++iter)
(*iter)->addref();
for (IdentifierCache::ConstIterator iter = identifierCache.begin(); iter != identifierCache.end(); ++iter)
@@ -210,6 +225,9 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb
indexCache.resize(propCount);
for (int ii = propOffset; ii < propCount; ++ii) {
QMetaProperty p = metaObject->property(ii);
+ if (!p.isScriptable())
+ continue;
+
QString propName = QString::fromUtf8(p.name());
RData *data = new RData;
@@ -275,6 +293,10 @@ void QDeclarativePropertyCache::update(QDeclarativeEngine *engine, const QMetaOb
indexCache.resize(propCount);
for (int ii = propCount - 1; ii >= 0; --ii) {
QMetaProperty p = metaObject->property(ii);
+ if (!p.isScriptable()) {
+ indexCache[ii] = 0;
+ continue;
+ }
QString propName = QString::fromUtf8(p.name());
RData *data = new RData;
@@ -294,7 +316,7 @@ void QDeclarativePropertyCache::update(QDeclarativeEngine *engine, const QMetaOb
}
int methodCount = metaObject->methodCount();
- for (int ii = methodCount - 1; ii >= 2; --ii) { // >=2 to block the destroyed signal
+ for (int ii = methodCount - 1; ii >= 3; --ii) { // >=3 to block the destroyed signal and deleteLater() slot
QMetaMethod m = metaObject->method(ii);
if (m.access() == QMetaMethod::Private)
continue;
diff --git a/src/declarative/qml/qdeclarativescriptparser.cpp b/src/declarative/qml/qdeclarativescriptparser.cpp
index 0b3b35f..c956051 100644
--- a/src/declarative/qml/qdeclarativescriptparser.cpp
+++ b/src/declarative/qml/qdeclarativescriptparser.cpp
@@ -387,7 +387,6 @@ bool ProcessAST::visit(AST::UiImport *node)
if (uri.endsWith(QLatin1String(".js"))) {
import.type = QDeclarativeScriptParser::Import::Script;
- _parser->_refUrls << QUrl(uri);
} else {
import.type = QDeclarativeScriptParser::Import::File;
}
@@ -878,11 +877,6 @@ QList<QDeclarativeScriptParser::TypeReference*> QDeclarativeScriptParser::refere
return _refTypes;
}
-QList<QUrl> QDeclarativeScriptParser::referencedResources() const
-{
- return _refUrls;
-}
-
Object *QDeclarativeScriptParser::tree() const
{
return root;
@@ -960,6 +954,217 @@ QDeclarativeParser::Object::ScriptBlock::Pragmas QDeclarativeScriptParser::extra
return rv;
}
+#define CHECK_LINE if(l.currentLineNo() != startLine) return rv;
+#define CHECK_TOKEN(t) if (token != QDeclarativeJSGrammar:: t) return rv;
+
+static const int uriTokens[] = {
+ QDeclarativeJSGrammar::T_IDENTIFIER,
+ QDeclarativeJSGrammar::T_PROPERTY,
+ QDeclarativeJSGrammar::T_SIGNAL,
+ QDeclarativeJSGrammar::T_READONLY,
+ QDeclarativeJSGrammar::T_ON,
+ QDeclarativeJSGrammar::T_BREAK,
+ QDeclarativeJSGrammar::T_CASE,
+ QDeclarativeJSGrammar::T_CATCH,
+ QDeclarativeJSGrammar::T_CONTINUE,
+ QDeclarativeJSGrammar::T_DEFAULT,
+ QDeclarativeJSGrammar::T_DELETE,
+ QDeclarativeJSGrammar::T_DO,
+ QDeclarativeJSGrammar::T_ELSE,
+ QDeclarativeJSGrammar::T_FALSE,
+ QDeclarativeJSGrammar::T_FINALLY,
+ QDeclarativeJSGrammar::T_FOR,
+ QDeclarativeJSGrammar::T_FUNCTION,
+ QDeclarativeJSGrammar::T_IF,
+ QDeclarativeJSGrammar::T_IN,
+ QDeclarativeJSGrammar::T_INSTANCEOF,
+ QDeclarativeJSGrammar::T_NEW,
+ QDeclarativeJSGrammar::T_NULL,
+ QDeclarativeJSGrammar::T_RETURN,
+ QDeclarativeJSGrammar::T_SWITCH,
+ QDeclarativeJSGrammar::T_THIS,
+ QDeclarativeJSGrammar::T_THROW,
+ QDeclarativeJSGrammar::T_TRUE,
+ QDeclarativeJSGrammar::T_TRY,
+ QDeclarativeJSGrammar::T_TYPEOF,
+ QDeclarativeJSGrammar::T_VAR,
+ QDeclarativeJSGrammar::T_VOID,
+ QDeclarativeJSGrammar::T_WHILE,
+ QDeclarativeJSGrammar::T_CONST,
+ QDeclarativeJSGrammar::T_DEBUGGER,
+ QDeclarativeJSGrammar::T_RESERVED_WORD,
+ QDeclarativeJSGrammar::T_WITH,
+
+ QDeclarativeJSGrammar::EOF_SYMBOL
+};
+static inline bool isUriToken(int token)
+{
+ const int *current = uriTokens;
+ while (*current != QDeclarativeJSGrammar::EOF_SYMBOL) {
+ if (*current == token)
+ return true;
+ ++current;
+ }
+ return false;
+}
+
+QDeclarativeScriptParser::JavaScriptMetaData QDeclarativeScriptParser::extractMetaData(QString &script)
+{
+ JavaScriptMetaData rv;
+
+ QDeclarativeParser::Object::ScriptBlock::Pragmas &pragmas = rv.pragmas;
+
+ const QString pragma(QLatin1String("pragma"));
+ const QString js(QLatin1String(".js"));
+ const QString library(QLatin1String("library"));
+
+ QDeclarativeJS::Lexer l(0);
+ l.setCode(script, 0);
+
+ int token = l.lex();
+
+ while (true) {
+ if (token != QDeclarativeJSGrammar::T_DOT)
+ return rv;
+
+ int startOffset = l.tokenOffset();
+ int startLine = l.currentLineNo();
+
+ token = l.lex();
+
+ CHECK_LINE;
+
+ if (token == QDeclarativeJSGrammar::T_IMPORT) {
+
+ // .import <URI> <Version> as <Identifier>
+ // .import <file.js> as <Identifier>
+
+ token = l.lex();
+
+ CHECK_LINE;
+
+ if (token == QDeclarativeJSGrammar::T_STRING_LITERAL) {
+
+ QString file(l.characterBuffer(), l.characterCount());
+ if (!file.endsWith(js))
+ return rv;
+
+ token = l.lex();
+
+ CHECK_TOKEN(T_AS);
+ CHECK_LINE;
+
+ token = l.lex();
+
+ CHECK_TOKEN(T_IDENTIFIER);
+ CHECK_LINE;
+
+ int endOffset = l.tokenLength() + l.tokenOffset();
+
+ QString importId = script.mid(l.tokenOffset(), l.tokenLength());
+
+ if (!importId.at(0).isUpper())
+ return rv;
+
+ token = l.lex();
+ if (l.currentLineNo() == startLine)
+ return rv;
+
+ replaceWithSpace(script, startOffset, endOffset - startOffset);
+
+ Import import;
+ import.type = Import::Script;
+ import.uri = file;
+ import.qualifier = importId;
+
+ rv.imports << import;
+
+ } else {
+ // URI
+ QString uri;
+ QString version;
+
+ while (true) {
+ if (!isUriToken(token))
+ return rv;
+
+ uri.append(QString(l.characterBuffer(), l.characterCount()));
+
+ token = l.lex();
+ CHECK_LINE;
+ if (token != QDeclarativeJSGrammar::T_DOT)
+ break;
+
+ uri.append(QLatin1Char('.'));
+
+ token = l.lex();
+ CHECK_LINE;
+ }
+
+ CHECK_TOKEN(T_NUMERIC_LITERAL);
+ version = script.mid(l.tokenOffset(), l.tokenLength());
+
+ token = l.lex();
+
+ CHECK_TOKEN(T_AS);
+ CHECK_LINE;
+
+ token = l.lex();
+
+ CHECK_TOKEN(T_IDENTIFIER);
+ CHECK_LINE;
+
+ int endOffset = l.tokenLength() + l.tokenOffset();
+
+ QString importId = script.mid(l.tokenOffset(), l.tokenLength());
+
+ if (!importId.at(0).isUpper())
+ return rv;
+
+ token = l.lex();
+ if (l.currentLineNo() == startLine)
+ return rv;
+
+ replaceWithSpace(script, startOffset, endOffset - startOffset);
+
+ Import import;
+ import.type = Import::Library;
+ import.uri = uri;
+ import.version = version;
+ import.qualifier = importId;
+
+ rv.imports << import;
+ }
+
+ } else if (token == QDeclarativeJSGrammar::T_IDENTIFIER &&
+ script.mid(l.tokenOffset(), l.tokenLength()) == pragma) {
+
+ token = l.lex();
+
+ CHECK_TOKEN(T_IDENTIFIER);
+ CHECK_LINE;
+
+ QString pragmaValue = script.mid(l.tokenOffset(), l.tokenLength());
+ int endOffset = l.tokenLength() + l.tokenOffset();
+
+ if (pragmaValue == QLatin1String("library")) {
+ pragmas |= QDeclarativeParser::Object::ScriptBlock::Shared;
+ replaceWithSpace(script, startOffset, endOffset - startOffset);
+ } else {
+ return rv;
+ }
+
+ token = l.lex();
+ if (l.currentLineNo() == startLine)
+ return rv;
+
+ } else {
+ return rv;
+ }
+ }
+ return rv;
+}
+
void QDeclarativeScriptParser::clear()
{
if (root) {
diff --git a/src/declarative/qml/qdeclarativescriptparser_p.h b/src/declarative/qml/qdeclarativescriptparser_p.h
index 28e960b..6319e11 100644
--- a/src/declarative/qml/qdeclarativescriptparser_p.h
+++ b/src/declarative/qml/qdeclarativescriptparser_p.h
@@ -103,7 +103,6 @@ public:
bool parse(const QByteArray &data, const QUrl &url = QUrl());
QList<TypeReference*> referencedTypes() const;
- QList<QUrl> referencedResources() const;
QDeclarativeParser::Object *tree() const;
QList<Import> imports() const;
@@ -112,7 +111,18 @@ public:
QList<QDeclarativeError> errors() const;
+ class JavaScriptMetaData {
+ public:
+ JavaScriptMetaData()
+ : pragmas(QDeclarativeParser::Object::ScriptBlock::None) {}
+
+ QDeclarativeParser::Object::ScriptBlock::Pragmas pragmas;
+ QList<Import> imports;
+ };
+
static QDeclarativeParser::Object::ScriptBlock::Pragmas extractPragmas(QString &);
+ static JavaScriptMetaData extractMetaData(QString &);
+
// ### private:
TypeReference *findOrCreateType(const QString &name);
@@ -127,7 +137,6 @@ public:
QDeclarativeParser::Object *root;
QList<Import> _imports;
QList<TypeReference*> _refTypes;
- QList<QUrl> _refUrls;
QString _scriptFile;
QDeclarativeScriptParserJsASTData *data;
};
diff --git a/src/declarative/qml/qdeclarativetypeloader.cpp b/src/declarative/qml/qdeclarativetypeloader.cpp
new file mode 100644
index 0000000..9b42065
--- /dev/null
+++ b/src/declarative/qml/qdeclarativetypeloader.cpp
@@ -0,0 +1,1079 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativetypeloader_p.h"
+
+#include <private/qdeclarativeengine_p.h>
+#include <private/qdeclarativecompiler_p.h>
+#include <private/qdeclarativecomponent_p.h>
+
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qdir.h>
+#include <QtCore/qfile.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+\class QDeclarativeDataBlob
+\brief The QDeclarativeDataBlob encapsulates a data request that can be issued to a QDeclarativeDataLoader.
+\internal
+
+QDeclarativeDataBlob's are loaded by a QDeclarativeDataLoader. The user creates the QDeclarativeDataBlob
+and then calls QDeclarativeDataLoader::load() or QDeclarativeDataLoader::loadWithStaticData() to load it.
+The QDeclarativeDataLoader invokes callbacks on the QDeclarativeDataBlob as data becomes available.
+*/
+
+/*!
+\enum QDeclarativeDataBlob::Status
+
+This enum describes the status of the data blob.
+
+\list
+\o Null The blob has not yet been loaded by a QDeclarativeDataLoader
+\o Loading The blob is loading network data. The QDeclarativeDataBlob::setData() callback has not yet been
+invoked or has not yet returned.
+\o WaitingForDependencies The blob is waiting for dependencies to be done before continueing. This status
+only occurs after the QDeclarativeDataBlob::setData() callback has been made, and when the blob has outstanding
+dependencies.
+\o Complete The blob's data has been loaded and all dependencies are done.
+\o Error An error has been set on this blob.
+\endlist
+*/
+
+/*!
+\enum QDeclarativeDataBlob::Type
+
+This enum describes the type of the data blob.
+
+\list
+\o QmlFile This is a QDeclarativeTypeData
+\o JavaScriptFile This is a QDeclarativeScriptData
+\o QmldirFile This is a QDeclarativeQmldirData
+\endlist
+*/
+
+/*!
+Create a new QDeclarativeDataBlob for \a url and of the provided \a type.
+*/
+QDeclarativeDataBlob::QDeclarativeDataBlob(const QUrl &url, Type type)
+: m_type(type), m_status(Null), m_progress(0), m_url(url), m_finalUrl(url), m_manager(0),
+ m_redirectCount(0), m_inCallback(false), m_isDone(false)
+{
+}
+
+/*! \internal */
+QDeclarativeDataBlob::~QDeclarativeDataBlob()
+{
+ Q_ASSERT(m_waitingOnMe.isEmpty());
+
+ cancelAllWaitingFor();
+}
+
+/*!
+Returns the type provided to the constructor.
+*/
+QDeclarativeDataBlob::Type QDeclarativeDataBlob::type() const
+{
+ return m_type;
+}
+
+/*!
+Returns the blob's status.
+*/
+QDeclarativeDataBlob::Status QDeclarativeDataBlob::status() const
+{
+ return m_status;
+}
+
+/*!
+Returns true if the status is Null.
+*/
+bool QDeclarativeDataBlob::isNull() const
+{
+ return m_status == Null;
+}
+
+/*!
+Returns true if the status is Loading.
+*/
+bool QDeclarativeDataBlob::isLoading() const
+{
+ return m_status == Loading;
+}
+
+/*!
+Returns true if the status is WaitingForDependencies.
+*/
+bool QDeclarativeDataBlob::isWaiting() const
+{
+ return m_status == WaitingForDependencies;
+}
+
+/*!
+Returns true if the status is Complete.
+*/
+bool QDeclarativeDataBlob::isComplete() const
+{
+ return m_status == Complete;
+}
+
+/*!
+Returns true if the status is Error.
+*/
+bool QDeclarativeDataBlob::isError() const
+{
+ return m_status == Error;
+}
+
+/*!
+Returns true if the status is Complete or Error.
+*/
+bool QDeclarativeDataBlob::isCompleteOrError() const
+{
+ return isComplete() || isError();
+}
+
+/*!
+Returns the data download progress from 0 to 1.
+*/
+qreal QDeclarativeDataBlob::progress() const
+{
+ return m_progress;
+}
+
+/*!
+Returns the blob url passed to the constructor. If a network redirect
+happens while fetching the data, this url remains the same.
+
+\sa finalUrl()
+*/
+QUrl QDeclarativeDataBlob::url() const
+{
+ return m_url;
+}
+
+/*!
+Returns the final url of the data. Initially this is the same as
+url(), but if a network redirect happens while fetching the data, this url
+is updated to reflect the new location.
+*/
+QUrl QDeclarativeDataBlob::finalUrl() const
+{
+ return m_finalUrl;
+}
+
+/*!
+Return the errors on this blob.
+*/
+QList<QDeclarativeError> QDeclarativeDataBlob::errors() const
+{
+ return m_errors;
+}
+
+/*!
+Mark this blob as having \a errors.
+
+All outstanding dependencies will be cancelled. Requests to add new dependencies
+will be ignored. Entry into the Error state is irreversable, although you can change the
+specific errors by additional calls to setError.
+*/
+void QDeclarativeDataBlob::setError(const QDeclarativeError &errors)
+{
+ QList<QDeclarativeError> l;
+ l << errors;
+ setError(l);
+}
+
+/*!
+\overload
+*/
+void QDeclarativeDataBlob::setError(const QList<QDeclarativeError> &errors)
+{
+ m_status = Error;
+ m_errors = errors;
+
+ cancelAllWaitingFor();
+
+ if (!m_inCallback)
+ tryDone();
+}
+
+/*!
+Wait for \a blob to become complete or to error. If \a blob is already
+complete or in error, or this blob is already complete, this has no effect.
+*/
+void QDeclarativeDataBlob::addDependency(QDeclarativeDataBlob *blob)
+{
+ Q_ASSERT(status() != Null);
+
+ if (!blob ||
+ blob->status() == Error || blob->status() == Complete ||
+ status() == Error || status() == Complete ||
+ m_waitingFor.contains(blob))
+ return;
+
+ blob->addref();
+ m_status = WaitingForDependencies;
+ m_waitingFor.append(blob);
+ blob->m_waitingOnMe.append(this);
+}
+
+/*!
+\fn void QDeclarativeDataBlob::dataReceived(const QByteArray &data)
+
+Invoked when data for the blob is received. Implementors should use this callback
+to determine a blob's dependencies. Within this callback you may call setError()
+or addDependency().
+*/
+
+/*!
+Invoked once data has either been received or a network error occurred, and all
+dependencies are complete.
+
+You can set an error in this method, but you cannot add new dependencies. Implementors
+should use this callback to finalize processing of data.
+
+The default implementation does nothing.
+*/
+void QDeclarativeDataBlob::done()
+{
+}
+
+/*!
+Invoked if there is a network error while fetching this blob.
+
+The default implementation sets an appropriate QDeclarativeError.
+*/
+void QDeclarativeDataBlob::networkError(QNetworkReply::NetworkError networkError)
+{
+ Q_UNUSED(networkError);
+
+ QDeclarativeError error;
+ error.setUrl(m_finalUrl);
+
+ const char *errorString = 0;
+ switch (networkError) {
+ default:
+ errorString = "Network error";
+ break;
+ case QNetworkReply::ConnectionRefusedError:
+ errorString = "Connection refused";
+ break;
+ case QNetworkReply::RemoteHostClosedError:
+ errorString = "Remote host closed the connection";
+ break;
+ case QNetworkReply::HostNotFoundError:
+ errorString = "Host not found";
+ break;
+ case QNetworkReply::TimeoutError:
+ errorString = "Timeout";
+ break;
+ case QNetworkReply::ProxyConnectionRefusedError:
+ case QNetworkReply::ProxyConnectionClosedError:
+ case QNetworkReply::ProxyNotFoundError:
+ case QNetworkReply::ProxyTimeoutError:
+ case QNetworkReply::ProxyAuthenticationRequiredError:
+ case QNetworkReply::UnknownProxyError:
+ errorString = "Proxy error";
+ break;
+ case QNetworkReply::ContentAccessDenied:
+ errorString = "Access denied";
+ break;
+ case QNetworkReply::ContentNotFoundError:
+ errorString = "File not found";
+ break;
+ case QNetworkReply::AuthenticationRequiredError:
+ errorString = "Authentication required";
+ break;
+ };
+
+ error.setDescription(QLatin1String(errorString));
+
+ setError(error);
+}
+
+/*!
+Called if \a blob, which was previously waited for, has an error.
+
+The default implementation does nothing.
+*/
+void QDeclarativeDataBlob::dependencyError(QDeclarativeDataBlob *blob)
+{
+ Q_UNUSED(blob);
+}
+
+/*!
+Called if \a blob, which was previously waited for, has completed.
+
+The default implementation does nothing.
+*/
+void QDeclarativeDataBlob::dependencyComplete(QDeclarativeDataBlob *blob)
+{
+ Q_UNUSED(blob);
+}
+
+/*!
+Called when all blobs waited for have completed. This occurs regardless of
+whether they are in error, or complete state.
+
+The default implementation does nothing.
+*/
+void QDeclarativeDataBlob::allDependenciesDone()
+{
+}
+
+/*!
+Called when the download progress of this blob changes. \a progress goes
+from 0 to 1.
+*/
+void QDeclarativeDataBlob::downloadProgressChanged(qreal progress)
+{
+ Q_UNUSED(progress);
+}
+
+void QDeclarativeDataBlob::tryDone()
+{
+ if (status() != Loading && m_waitingFor.isEmpty() && !m_isDone) {
+ if (status() != Error)
+ m_status = Complete;
+
+ m_isDone = true;
+ done();
+ notifyAllWaitingOnMe();
+ }
+}
+
+void QDeclarativeDataBlob::cancelAllWaitingFor()
+{
+ while (m_waitingFor.count()) {
+ QDeclarativeDataBlob *blob = m_waitingFor.takeLast();
+
+ Q_ASSERT(blob->m_waitingOnMe.contains(this));
+
+ blob->m_waitingOnMe.removeOne(this);
+
+ blob->release();
+ }
+}
+
+void QDeclarativeDataBlob::notifyAllWaitingOnMe()
+{
+ while (m_waitingOnMe.count()) {
+ QDeclarativeDataBlob *blob = m_waitingOnMe.takeLast();
+
+ Q_ASSERT(blob->m_waitingFor.contains(this));
+
+ blob->notifyComplete(this);
+ }
+}
+
+void QDeclarativeDataBlob::notifyComplete(QDeclarativeDataBlob *blob)
+{
+ Q_ASSERT(m_waitingFor.contains(blob));
+ Q_ASSERT(blob->status() == Error || blob->status() == Complete);
+
+ m_inCallback = true;
+
+ if (blob->status() == Error) {
+ dependencyError(blob);
+ } else if (blob->status() == Complete) {
+ dependencyComplete(blob);
+ }
+
+ m_waitingFor.removeOne(blob);
+ blob->release();
+
+ if (!isError() && m_waitingFor.isEmpty())
+ allDependenciesDone();
+
+ m_inCallback = false;
+
+ tryDone();
+}
+
+/*!
+\class QDeclarativeDataLoader
+\brief The QDeclarativeDataLoader class abstracts loading files and their dependecies over the network.
+\internal
+
+The QDeclarativeDataLoader class is provided for the exclusive use of the QDeclarativeTypeLoader class.
+
+Clients create QDeclarativeDataBlob instances and submit them to the QDeclarativeDataLoader class
+through the QDeclarativeDataLoader::load() or QDeclarativeDataLoader::loadWithStaticData() methods.
+The loader then fetches the data over the network or from the local file system in an efficient way.
+QDeclarativeDataBlob is an abstract class, so should always be specialized.
+
+Once data is received, the QDeclarativeDataBlob::dataReceived() method is invoked on the blob. The
+derived class should use this callback to process the received data. Processing of the data can
+result in an error being set (QDeclarativeDataBlob::setError()), or one or more dependencies being
+created (QDeclarativeDataBlob::addDependency()). Dependencies are other QDeclarativeDataBlob's that
+are required before processing can fully complete.
+
+To complete processing, the QDeclarativeDataBlob::done() callback is invoked. done() is called when
+one of these three preconditions are met.
+
+1. The QDeclarativeDataBlob has no dependencies.
+2. The QDeclarativeDataBlob has an error set.
+3. All the QDeclarativeDataBlob's dependencies are themselves "done()".
+
+Thus QDeclarativeDataBlob::done() will always eventually be called, even if the blob has an error set.
+*/
+
+/*!
+Create a new QDeclarativeDataLoader for \a engine.
+*/
+QDeclarativeDataLoader::QDeclarativeDataLoader(QDeclarativeEngine *engine)
+: m_engine(engine)
+{
+}
+
+/*! \internal */
+QDeclarativeDataLoader::~QDeclarativeDataLoader()
+{
+ for (NetworkReplies::Iterator iter = m_networkReplies.begin(); iter != m_networkReplies.end(); ++iter)
+ (*iter)->release();
+}
+
+/*!
+Load the provided \a blob from the network or filesystem.
+*/
+void QDeclarativeDataLoader::load(QDeclarativeDataBlob *blob)
+{
+ Q_ASSERT(blob->status() == QDeclarativeDataBlob::Null);
+ Q_ASSERT(blob->m_manager == 0);
+
+ blob->m_status = QDeclarativeDataBlob::Loading;
+
+ if (blob->m_url.isEmpty()) {
+ QDeclarativeError error;
+ error.setDescription(QLatin1String("Invalid null URL"));
+ blob->setError(error);
+ return;
+ }
+
+ QString lf = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(blob->m_url);
+
+ if (!lf.isEmpty()) {
+ QFile file(lf);
+ if (file.open(QFile::ReadOnly)) {
+ QByteArray data = file.readAll();
+
+ blob->m_progress = 1.;
+ blob->downloadProgressChanged(1.);
+
+ setData(blob, data);
+ } else {
+ blob->networkError(QNetworkReply::ContentNotFoundError);
+ }
+
+ } else {
+
+ blob->m_manager = this;
+ QNetworkReply *reply = m_engine->networkAccessManager()->get(QNetworkRequest(blob->m_url));
+ QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
+ this, SLOT(networkReplyProgress(qint64,qint64)));
+ QObject::connect(reply, SIGNAL(finished()),
+ this, SLOT(networkReplyFinished()));
+ m_networkReplies.insert(reply, blob);
+
+ blob->addref();
+ }
+}
+
+#define DATALOADER_MAXIMUM_REDIRECT_RECURSION 16
+
+void QDeclarativeDataLoader::networkReplyFinished()
+{
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
+
+ QDeclarativeDataBlob *blob = m_networkReplies.take(reply);
+
+ Q_ASSERT(blob);
+
+ blob->m_redirectCount++;
+
+ if (blob->m_redirectCount < DATALOADER_MAXIMUM_REDIRECT_RECURSION) {
+ QVariant redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
+ if (redirect.isValid()) {
+ QUrl url = reply->url().resolved(redirect.toUrl());
+ blob->m_finalUrl = url;
+
+ QNetworkReply *reply = m_engine->networkAccessManager()->get(QNetworkRequest(url));
+ QObject::connect(reply, SIGNAL(finished()), this, SLOT(networkReplyFinished()));
+ m_networkReplies.insert(reply, blob);
+ return;
+ }
+ }
+
+ if (reply->error()) {
+ blob->networkError(reply->error());
+ } else {
+ QByteArray data = reply->readAll();
+ setData(blob, data);
+ }
+
+ blob->release();
+}
+
+void QDeclarativeDataLoader::networkReplyProgress(qint64 bytesReceived, qint64 bytesTotal)
+{
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ QDeclarativeDataBlob *blob = m_networkReplies.value(reply);
+
+ Q_ASSERT(blob);
+
+ if (bytesTotal != 0) {
+ blob->m_progress = bytesReceived / bytesTotal;
+ blob->downloadProgressChanged(blob->m_progress);
+ }
+}
+
+/*!
+Load the provided \a blob with \a data. The blob's URL is not used by the data loader in this case.
+*/
+void QDeclarativeDataLoader::loadWithStaticData(QDeclarativeDataBlob *blob, const QByteArray &data)
+{
+ Q_ASSERT(blob->status() == QDeclarativeDataBlob::Null);
+ Q_ASSERT(blob->m_manager == 0);
+
+ blob->m_status = QDeclarativeDataBlob::Loading;
+
+ setData(blob, data);
+}
+
+/*!
+Return the QDeclarativeEngine associated with this loader
+*/
+QDeclarativeEngine *QDeclarativeDataLoader::engine() const
+{
+ return m_engine;
+}
+
+void QDeclarativeDataLoader::setData(QDeclarativeDataBlob *blob, const QByteArray &data)
+{
+ blob->m_inCallback = true;
+
+ blob->dataReceived(data);
+
+ if (!blob->isError() && !blob->isWaiting())
+ blob->allDependenciesDone();
+
+ if (blob->status() != QDeclarativeDataBlob::Error)
+ blob->m_status = QDeclarativeDataBlob::WaitingForDependencies;
+
+ blob->m_inCallback = false;
+
+ blob->tryDone();
+}
+
+/*!
+\class QDeclarativeTypeLoader
+*/
+QDeclarativeTypeLoader::QDeclarativeTypeLoader(QDeclarativeEngine *engine)
+: QDeclarativeDataLoader(engine)
+{
+}
+
+QDeclarativeTypeLoader::~QDeclarativeTypeLoader()
+{
+ clearCache();
+}
+
+/*!
+Return a QDeclarativeTypeData for \a url. The QDeclarativeTypeData may be cached.
+*/
+QDeclarativeTypeData *QDeclarativeTypeLoader::get(const QUrl &url)
+{
+ Q_ASSERT(!url.isRelative() &&
+ (QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url).isEmpty() ||
+ !QDir::isRelativePath(QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url))));
+
+ QDeclarativeTypeData *typeData = m_typeCache.value(url);
+
+ if (!typeData) {
+ typeData = new QDeclarativeTypeData(url, None, this);
+ m_typeCache.insert(url, typeData);
+ QDeclarativeDataLoader::load(typeData);
+ }
+
+ typeData->addref();
+ return typeData;
+}
+
+/*!
+Return a QDeclarativeTypeData for \a data with the provided base \a url. The
+QDeclarativeTypeData will not be cached.
+*/
+QDeclarativeTypeData *QDeclarativeTypeLoader::get(const QByteArray &data, const QUrl &url, Options options)
+{
+ QDeclarativeTypeData *typeData = new QDeclarativeTypeData(url, options, this);
+ QDeclarativeDataLoader::loadWithStaticData(typeData, data);
+ return typeData;
+}
+
+/*!
+Return a QDeclarativeScriptData for \a url. The QDeclarativeScriptData may be cached.
+*/
+QDeclarativeScriptData *QDeclarativeTypeLoader::getScript(const QUrl &url)
+{
+ Q_ASSERT(!url.isRelative() &&
+ (QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url).isEmpty() ||
+ !QDir::isRelativePath(QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url))));
+
+ QDeclarativeScriptData *scriptData = m_scriptCache.value(url);
+
+ if (!scriptData) {
+ scriptData = new QDeclarativeScriptData(url);
+ m_scriptCache.insert(url, scriptData);
+ QDeclarativeDataLoader::load(scriptData);
+ }
+
+ scriptData->addref();
+ return scriptData;
+}
+
+/*!
+Return a QDeclarativeQmldirData for \a url. The QDeclarativeQmldirData may be cached.
+*/
+QDeclarativeQmldirData *QDeclarativeTypeLoader::getQmldir(const QUrl &url)
+{
+ Q_ASSERT(!url.isRelative() &&
+ (QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url).isEmpty() ||
+ !QDir::isRelativePath(QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url))));
+
+ QDeclarativeQmldirData *qmldirData = m_qmldirCache.value(url);
+
+ if (!qmldirData) {
+ qmldirData = new QDeclarativeQmldirData(url);
+ m_qmldirCache.insert(url, qmldirData);
+ QDeclarativeDataLoader::load(qmldirData);
+ }
+
+ qmldirData->addref();
+ return qmldirData;
+}
+
+void QDeclarativeTypeLoader::clearCache()
+{
+ for (TypeCache::Iterator iter = m_typeCache.begin(); iter != m_typeCache.end(); ++iter)
+ (*iter)->release();
+ for (ScriptCache::Iterator iter = m_scriptCache.begin(); iter != m_scriptCache.end(); ++iter)
+ (*iter)->release();
+ for (QmldirCache::Iterator iter = m_qmldirCache.begin(); iter != m_qmldirCache.end(); ++iter)
+ (*iter)->release();
+
+ m_typeCache.clear();
+ m_scriptCache.clear();
+ m_qmldirCache.clear();
+}
+
+
+QDeclarativeTypeData::QDeclarativeTypeData(const QUrl &url, QDeclarativeTypeLoader::Options options,
+ QDeclarativeTypeLoader *manager)
+: QDeclarativeDataBlob(url, QmlFile), m_options(options), m_typesResolved(false),
+ m_compiledData(0), m_component(0), m_typeLoader(manager)
+{
+}
+
+QDeclarativeTypeData::~QDeclarativeTypeData()
+{
+ for (int ii = 0; ii < m_scripts.count(); ++ii)
+ m_scripts.at(ii).script->release();
+ for (int ii = 0; ii < m_qmldirs.count(); ++ii)
+ m_qmldirs.at(ii)->release();
+ for (int ii = 0; ii < m_types.count(); ++ii)
+ if (m_types.at(ii).typeData) m_types.at(ii).typeData->release();
+ if (m_compiledData)
+ m_compiledData->release();
+}
+
+QDeclarativeTypeLoader *QDeclarativeTypeData::typeLoader() const
+{
+ return m_typeLoader;
+}
+
+const QDeclarativeImports &QDeclarativeTypeData::imports() const
+{
+ return m_imports;
+}
+
+const QDeclarativeScriptParser &QDeclarativeTypeData::parser() const
+{
+ return scriptParser;
+}
+
+const QList<QDeclarativeTypeData::TypeReference> &QDeclarativeTypeData::resolvedTypes() const
+{
+ return m_types;
+}
+
+const QList<QDeclarativeTypeData::ScriptReference> &QDeclarativeTypeData::resolvedScripts() const
+{
+ return m_scripts;
+}
+
+QDeclarativeCompiledData *QDeclarativeTypeData::compiledData() const
+{
+ if (m_compiledData)
+ m_compiledData->addref();
+
+ return m_compiledData;
+}
+
+QDeclarativeComponent *QDeclarativeTypeData::component() const
+{
+ if (!m_component) {
+
+ if (m_compiledData) {
+ m_component = new QDeclarativeComponent(typeLoader()->engine(), m_compiledData, -1, -1, 0);
+ } else {
+ m_component = new QDeclarativeComponent(typeLoader()->engine());
+ QDeclarativeComponentPrivate::get(m_component)->url = finalUrl();
+ QDeclarativeComponentPrivate::get(m_component)->state.errors = errors();
+ }
+
+ }
+
+ return m_component;
+}
+
+void QDeclarativeTypeData::registerCallback(TypeDataCallback *callback)
+{
+ Q_ASSERT(!m_callbacks.contains(callback));
+ m_callbacks.append(callback);
+}
+
+void QDeclarativeTypeData::unregisterCallback(TypeDataCallback *callback)
+{
+ Q_ASSERT(m_callbacks.contains(callback));
+ m_callbacks.removeOne(callback);
+ Q_ASSERT(!m_callbacks.contains(callback));
+}
+
+void QDeclarativeTypeData::done()
+{
+ addref();
+
+ // Check all script dependencies for errors
+ for (int ii = 0; !isError() && ii < m_scripts.count(); ++ii) {
+ const ScriptReference &script = m_scripts.at(ii);
+ Q_ASSERT(script.script->isCompleteOrError());
+ if (script.script->isError()) {
+ QList<QDeclarativeError> errors = script.script->errors();
+ QDeclarativeError error;
+ error.setUrl(finalUrl());
+ error.setLine(script.location.line);
+ error.setColumn(script.location.column);
+ error.setDescription(typeLoader()->tr("Script %1 unavailable").arg(script.script->url().toString()));
+ errors.prepend(error);
+ setError(errors);
+ }
+ }
+
+ // Check all type dependencies for errors
+ for (int ii = 0; !isError() && ii < m_types.count(); ++ii) {
+ const TypeReference &type = m_types.at(ii);
+ Q_ASSERT(!type.typeData || type.typeData->isCompleteOrError());
+ if (type.typeData && type.typeData->isError()) {
+ QString typeName = scriptParser.referencedTypes().at(ii)->name;
+
+ QList<QDeclarativeError> errors = type.typeData->errors();
+ QDeclarativeError error;
+ error.setUrl(finalUrl());
+ error.setLine(type.location.line);
+ error.setColumn(type.location.column);
+ error.setDescription(typeLoader()->tr("Type %1 unavailable").arg(typeName));
+ errors.prepend(error);
+ setError(errors);
+ }
+ }
+
+ // Compile component
+ if (!isError())
+ compile();
+
+ if (!(m_options & QDeclarativeTypeLoader::PreserveParser))
+ scriptParser.clear();
+
+ // Notify callbacks
+ while (!m_callbacks.isEmpty()) {
+ TypeDataCallback *callback = m_callbacks.takeFirst();
+ callback->typeDataReady(this);
+ }
+
+ release();
+}
+
+void QDeclarativeTypeData::dataReceived(const QByteArray &data)
+{
+ if (!scriptParser.parse(data, finalUrl())) {
+ setError(scriptParser.errors());
+ return;
+ }
+
+ m_imports.setBaseUrl(finalUrl());
+
+ foreach (const QDeclarativeScriptParser::Import &import, scriptParser.imports()) {
+ if (import.type == QDeclarativeScriptParser::Import::File && import.qualifier.isEmpty()) {
+ QUrl importUrl = finalUrl().resolved(QUrl(import.uri + QLatin1String("/qmldir")));
+ if (QDeclarativeEnginePrivate::urlToLocalFileOrQrc(importUrl).isEmpty()) {
+ QDeclarativeQmldirData *data = typeLoader()->getQmldir(importUrl);
+ addDependency(data);
+ m_qmldirs << data;
+ }
+ } else if (import.type == QDeclarativeScriptParser::Import::Script) {
+ QUrl scriptUrl = finalUrl().resolved(QUrl(import.uri));
+ QDeclarativeScriptData *data = typeLoader()->getScript(scriptUrl);
+ addDependency(data);
+
+ ScriptReference ref;
+ ref.location = import.location.start;
+ ref.qualifier = import.qualifier;
+ ref.script = data;
+ m_scripts << ref;
+
+ }
+ }
+
+ if (!finalUrl().scheme().isEmpty()) {
+ QUrl importUrl = finalUrl().resolved(QUrl(QLatin1String("qmldir")));
+ if (QDeclarativeEnginePrivate::urlToLocalFileOrQrc(importUrl).isEmpty()) {
+ QDeclarativeQmldirData *data = typeLoader()->getQmldir(importUrl);
+ addDependency(data);
+ m_qmldirs << data;
+ }
+ }
+}
+
+void QDeclarativeTypeData::allDependenciesDone()
+{
+ if (!m_typesResolved) {
+ resolveTypes();
+ m_typesResolved = true;
+ }
+}
+
+void QDeclarativeTypeData::downloadProgressChanged(qreal p)
+{
+ for (int ii = 0; ii < m_callbacks.count(); ++ii) {
+ TypeDataCallback *callback = m_callbacks.at(ii);
+ callback->typeDataProgress(this, p);
+ }
+}
+
+void QDeclarativeTypeData::compile()
+{
+ Q_ASSERT(m_compiledData == 0);
+
+ m_compiledData = new QDeclarativeCompiledData(typeLoader()->engine());
+ m_compiledData->url = m_imports.baseUrl();
+ m_compiledData->name = m_compiledData->url.toString();
+
+ QDeclarativeCompiler compiler;
+ if (!compiler.compile(typeLoader()->engine(), this, m_compiledData)) {
+ setError(compiler.errors());
+ m_compiledData->release();
+ m_compiledData = 0;
+ }
+}
+
+void QDeclarativeTypeData::resolveTypes()
+{
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(m_typeLoader->engine());
+ QDeclarativeImportDatabase *importDatabase = &ep->importDatabase;
+
+ // For local urls, add an implicit import "." as first (most overridden) lookup.
+ // This will also trigger the loading of the qmldir and the import of any native
+ // types from available plugins.
+ if (QDeclarativeQmldirData *qmldir = qmldirForUrl(finalUrl().resolved(QUrl(QLatin1String("./qmldir"))))) {
+ m_imports.addImport(importDatabase, QLatin1String("."),
+ QString(), -1, -1, QDeclarativeScriptParser::Import::File,
+ qmldir->dirComponents(), 0);
+ } else {
+ m_imports.addImport(importDatabase, QLatin1String("."),
+ QString(), -1, -1, QDeclarativeScriptParser::Import::File,
+ QDeclarativeDirComponents(), 0);
+ }
+
+ foreach (const QDeclarativeScriptParser::Import &import, scriptParser.imports()) {
+ QDeclarativeDirComponents qmldircomponentsnetwork;
+ if (import.type == QDeclarativeScriptParser::Import::Script)
+ continue;
+
+ if (import.type == QDeclarativeScriptParser::Import::File && import.qualifier.isEmpty()) {
+ QUrl qmldirUrl = finalUrl().resolved(QUrl(import.uri + QLatin1String("/qmldir")));
+ if (QDeclarativeQmldirData *qmldir = qmldirForUrl(qmldirUrl))
+ qmldircomponentsnetwork = qmldir->dirComponents();
+ }
+
+ int vmaj = -1;
+ int vmin = -1;
+
+ if (!import.version.isEmpty()) {
+ int dot = import.version.indexOf(QLatin1Char('.'));
+ if (dot < 0) {
+ vmaj = import.version.toInt();
+ vmin = 0;
+ } else {
+ vmaj = import.version.left(dot).toInt();
+ vmin = import.version.mid(dot+1).toInt();
+ }
+ }
+
+ QString errorString;
+ if (!m_imports.addImport(importDatabase, import.uri, import.qualifier,
+ vmaj, vmin, import.type, qmldircomponentsnetwork, &errorString)) {
+ QDeclarativeError error;
+ error.setUrl(m_imports.baseUrl());
+ error.setDescription(errorString);
+ error.setLine(import.location.start.line);
+ error.setColumn(import.location.start.column);
+
+ setError(error);
+ return;
+ }
+ }
+
+ foreach (QDeclarativeScriptParser::TypeReference *parserRef, scriptParser.referencedTypes()) {
+ QByteArray typeName = parserRef->name.toUtf8();
+
+ TypeReference ref;
+
+ QUrl url;
+ int majorVersion;
+ int minorVersion;
+ QDeclarativeImportedNamespace *typeNamespace = 0;
+ QString errorString;
+
+ if (!m_imports.resolveType(typeName, &ref.type, &url, &majorVersion, &minorVersion,
+ &typeNamespace, &errorString) || typeNamespace) {
+ // Known to not be a type:
+ // - known to be a namespace (Namespace {})
+ // - type with unknown namespace (UnknownNamespace.SomeType {})
+ QDeclarativeError error;
+ error.setUrl(m_imports.baseUrl());
+ QString userTypeName = parserRef->name;
+ userTypeName.replace(QLatin1Char('/'),QLatin1Char('.'));
+ if (typeNamespace)
+ error.setDescription(typeLoader()->tr("Namespace %1 cannot be used as a type").arg(userTypeName));
+ else
+ error.setDescription(typeLoader()->tr("%1 %2").arg(userTypeName).arg(errorString));
+
+ if (!parserRef->refObjects.isEmpty()) {
+ QDeclarativeParser::Object *obj = parserRef->refObjects.first();
+ error.setLine(obj->location.start.line);
+ error.setColumn(obj->location.start.column);
+ }
+
+ setError(error);
+ return;
+ }
+
+ if (ref.type) {
+ foreach (QDeclarativeParser::Object *obj, parserRef->refObjects) {
+ // store namespace for DOM
+ obj->majorVersion = majorVersion;
+ obj->minorVersion = minorVersion;
+ }
+ } else {
+ ref.typeData = typeLoader()->get(url);
+ addDependency(ref.typeData);
+ }
+
+ if (parserRef->refObjects.count())
+ ref.location = parserRef->refObjects.first()->location.start;
+
+ m_types << ref;
+ }
+}
+
+QDeclarativeQmldirData *QDeclarativeTypeData::qmldirForUrl(const QUrl &url)
+{
+ for (int ii = 0; ii < m_qmldirs.count(); ++ii) {
+ if (m_qmldirs.at(ii)->url() == url)
+ return m_qmldirs.at(ii);
+ }
+ return 0;
+}
+
+QDeclarativeScriptData::QDeclarativeScriptData(const QUrl &url)
+: QDeclarativeDataBlob(url, JavaScriptFile), m_pragmas(QDeclarativeParser::Object::ScriptBlock::None)
+{
+}
+
+QDeclarativeParser::Object::ScriptBlock::Pragmas QDeclarativeScriptData::pragmas() const
+{
+ return m_pragmas;
+}
+
+QString QDeclarativeScriptData::scriptSource() const
+{
+ return m_source;
+}
+
+void QDeclarativeScriptData::dataReceived(const QByteArray &data)
+{
+ m_source = QString::fromUtf8(data);
+ m_pragmas = QDeclarativeScriptParser::extractPragmas(m_source);
+}
+
+QDeclarativeQmldirData::QDeclarativeQmldirData(const QUrl &url)
+: QDeclarativeDataBlob(url, QmldirFile)
+{
+}
+
+const QDeclarativeDirComponents &QDeclarativeQmldirData::dirComponents() const
+{
+ return m_components;
+}
+
+void QDeclarativeQmldirData::dataReceived(const QByteArray &data)
+{
+ QDeclarativeDirParser parser;
+ parser.setSource(QString::fromUtf8(data));
+ parser.parse();
+ m_components = parser.components();
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/declarative/qml/qdeclarativetypeloader_p.h b/src/declarative/qml/qdeclarativetypeloader_p.h
new file mode 100644
index 0000000..7381f28
--- /dev/null
+++ b/src/declarative/qml/qdeclarativetypeloader_p.h
@@ -0,0 +1,321 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVETYPELOADER_P_H
+#define QDECLARATIVETYPELOADER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qobject.h>
+#include <QtNetwork/qnetworkreply.h>
+#include <QtDeclarative/qdeclarativeerror.h>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <private/qdeclarativescriptparser_p.h>
+#include <private/qdeclarativedirparser_p.h>
+#include <private/qdeclarativeimport_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeScriptData;
+class QDeclarativeQmldirData;
+class QDeclarativeTypeLoader;
+class QDeclarativeCompiledData;
+class QDeclarativeComponentPrivate;
+class QDeclarativeTypeData;
+class QDeclarativeDataLoader;
+
+class Q_AUTOTEST_EXPORT QDeclarativeDataBlob : public QDeclarativeRefCount
+{
+public:
+ enum Status {
+ Null, // Prior to QDeclarativeDataLoader::load()
+ Loading, // Prior to data being received and dataReceived() being called
+ WaitingForDependencies, // While there are outstanding addDependency()s
+ Complete, // Finished
+ Error, // Error
+ };
+
+ enum Type {
+ QmlFile,
+ JavaScriptFile,
+ QmldirFile
+ };
+
+ QDeclarativeDataBlob(const QUrl &, Type);
+ virtual ~QDeclarativeDataBlob();
+
+ Type type() const;
+
+ Status status() const;
+ bool isNull() const;
+ bool isLoading() const;
+ bool isWaiting() const;
+ bool isComplete() const;
+ bool isError() const;
+ bool isCompleteOrError() const;
+
+ qreal progress() const;
+
+ QUrl url() const;
+ QUrl finalUrl() const;
+
+ QList<QDeclarativeError> errors() const;
+
+ void setError(const QDeclarativeError &);
+ void setError(const QList<QDeclarativeError> &errors);
+
+ void addDependency(QDeclarativeDataBlob *);
+
+protected:
+ virtual void dataReceived(const QByteArray &) = 0;
+
+ virtual void done();
+ virtual void networkError(QNetworkReply::NetworkError);
+
+ virtual void dependencyError(QDeclarativeDataBlob *);
+ virtual void dependencyComplete(QDeclarativeDataBlob *);
+ virtual void allDependenciesDone();
+
+ virtual void downloadProgressChanged(qreal);
+
+private:
+ friend class QDeclarativeDataLoader;
+ void tryDone();
+ void cancelAllWaitingFor();
+ void notifyAllWaitingOnMe();
+ void notifyComplete(QDeclarativeDataBlob *);
+
+ Type m_type;
+ Status m_status;
+ qreal m_progress;
+
+ QUrl m_url;
+ QUrl m_finalUrl;
+
+ // List of QDeclarativeDataBlob's that are waiting for me to complete.
+ QList<QDeclarativeDataBlob *> m_waitingOnMe;
+
+ // List of QDeclarativeDataBlob's that I am waiting for to complete.
+ QList<QDeclarativeDataBlob *> m_waitingFor;
+
+ // Manager that is currently fetching data for me
+ QDeclarativeDataLoader *m_manager;
+ int m_redirectCount:30;
+ bool m_inCallback:1;
+ bool m_isDone:1;
+
+ QList<QDeclarativeError> m_errors;
+};
+
+class Q_AUTOTEST_EXPORT QDeclarativeDataLoader : public QObject
+{
+ Q_OBJECT
+public:
+ QDeclarativeDataLoader(QDeclarativeEngine *);
+ ~QDeclarativeDataLoader();
+
+ void load(QDeclarativeDataBlob *);
+ void loadWithStaticData(QDeclarativeDataBlob *, const QByteArray &);
+
+ QDeclarativeEngine *engine() const;
+
+private slots:
+ void networkReplyFinished();
+ void networkReplyProgress(qint64,qint64);
+
+private:
+ void setData(QDeclarativeDataBlob *, const QByteArray &);
+
+ QDeclarativeEngine *m_engine;
+ typedef QHash<QNetworkReply *, QDeclarativeDataBlob *> NetworkReplies;
+ NetworkReplies m_networkReplies;
+};
+
+
+class Q_AUTOTEST_EXPORT QDeclarativeTypeLoader : public QDeclarativeDataLoader
+{
+ Q_OBJECT
+public:
+ QDeclarativeTypeLoader(QDeclarativeEngine *);
+ ~QDeclarativeTypeLoader();
+
+ enum Option {
+ None,
+ PreserveParser
+ };
+ Q_DECLARE_FLAGS(Options, Option)
+
+ QDeclarativeTypeData *get(const QUrl &url);
+ QDeclarativeTypeData *get(const QByteArray &, const QUrl &url, Options = None);
+ void clearCache();
+
+ QDeclarativeScriptData *getScript(const QUrl &);
+ QDeclarativeQmldirData *getQmldir(const QUrl &);
+private:
+ typedef QHash<QUrl, QDeclarativeTypeData *> TypeCache;
+ typedef QHash<QUrl, QDeclarativeScriptData *> ScriptCache;
+ typedef QHash<QUrl, QDeclarativeQmldirData *> QmldirCache;
+
+ TypeCache m_typeCache;
+ ScriptCache m_scriptCache;
+ QmldirCache m_qmldirCache;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeTypeLoader::Options)
+
+class Q_AUTOTEST_EXPORT QDeclarativeTypeData : public QDeclarativeDataBlob
+{
+public:
+ struct TypeReference
+ {
+ TypeReference() : type(0), typeData(0) {}
+
+ QDeclarativeParser::Location location;
+ QDeclarativeType *type;
+ QDeclarativeTypeData *typeData;
+ };
+
+ struct ScriptReference
+ {
+ ScriptReference() : script(0) {}
+
+ QDeclarativeParser::Location location;
+ QString qualifier;
+ QDeclarativeScriptData *script;
+ };
+
+ QDeclarativeTypeData(const QUrl &, QDeclarativeTypeLoader::Options, QDeclarativeTypeLoader *);
+ ~QDeclarativeTypeData();
+
+ QDeclarativeTypeLoader *typeLoader() const;
+
+ const QDeclarativeImports &imports() const;
+ const QDeclarativeScriptParser &parser() const;
+
+ const QList<TypeReference> &resolvedTypes() const;
+ const QList<ScriptReference> &resolvedScripts() const;
+
+ QDeclarativeCompiledData *compiledData() const;
+ QDeclarativeComponent *component() const;
+
+ // Used by QDeclarativeComponent to get notifications
+ struct TypeDataCallback {
+ ~TypeDataCallback() {}
+ virtual void typeDataProgress(QDeclarativeTypeData *, qreal) {}
+ virtual void typeDataReady(QDeclarativeTypeData *) {}
+ };
+ void registerCallback(TypeDataCallback *);
+ void unregisterCallback(TypeDataCallback *);
+
+protected:
+ virtual void done();
+ virtual void dataReceived(const QByteArray &);
+ virtual void allDependenciesDone();
+ virtual void downloadProgressChanged(qreal);
+
+private:
+ void resolveTypes();
+ void compile();
+
+ QDeclarativeTypeLoader::Options m_options;
+
+ QDeclarativeQmldirData *qmldirForUrl(const QUrl &);
+
+ QDeclarativeScriptParser scriptParser;
+ QDeclarativeImports m_imports;
+
+ QList<ScriptReference> m_scripts;
+ QList<QDeclarativeQmldirData *> m_qmldirs;
+
+ QList<TypeReference> m_types;
+ bool m_typesResolved:1;
+
+ QDeclarativeCompiledData *m_compiledData;
+ mutable QDeclarativeComponent *m_component;
+
+ QList<TypeDataCallback *> m_callbacks;
+
+ QDeclarativeTypeLoader *m_typeLoader;
+};
+
+class Q_AUTOTEST_EXPORT QDeclarativeScriptData : public QDeclarativeDataBlob
+{
+public:
+ QDeclarativeScriptData(const QUrl &);
+
+ QDeclarativeParser::Object::ScriptBlock::Pragmas pragmas() const;
+ QString scriptSource() const;
+
+protected:
+ virtual void dataReceived(const QByteArray &);
+
+private:
+ QDeclarativeParser::Object::ScriptBlock::Pragmas m_pragmas;
+ QString m_source;
+};
+
+class Q_AUTOTEST_EXPORT QDeclarativeQmldirData : public QDeclarativeDataBlob
+{
+public:
+ QDeclarativeQmldirData(const QUrl &);
+
+ const QDeclarativeDirComponents &dirComponents() const;
+
+protected:
+ virtual void dataReceived(const QByteArray &);
+
+private:
+ QDeclarativeDirComponents m_components;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QDECLARATIVETYPELOADER_P_H
diff --git a/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
index f06d6ae..60f2cb3 100644
--- a/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
+++ b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
@@ -168,7 +168,7 @@ void QDeclarativeValueTypeScriptClass::setProperty(Object *obj, const Identifier
ref->type->read(ref->object, ref->property);
QMetaProperty p = ref->type->metaObject()->property(m_lastIndex);
- if (p.isEnumType() && (QMetaType::Type)v.type() == QMetaType::QReal)
+ if (p.isEnumType() && (QMetaType::Type)v.type() == QMetaType::Double)
v = v.toInt();
p.write(ref->type, v);
ref->type->write(ref->object, ref->property, 0);
diff --git a/src/declarative/qml/qdeclarativevmemetaobject.cpp b/src/declarative/qml/qdeclarativevmemetaobject.cpp
index 689ed92..3e32006 100644
--- a/src/declarative/qml/qdeclarativevmemetaobject.cpp
+++ b/src/declarative/qml/qdeclarativevmemetaobject.cpp
@@ -707,11 +707,19 @@ void QDeclarativeVMEMetaObject::writeVarProperty(int id, const QScriptValue &val
void QDeclarativeVMEMetaObject::writeVarProperty(int id, const QVariant &value)
{
- if (value.userType() == QMetaType::QObjectStar)
+ bool needActivate = false;
+ if (value.userType() == QMetaType::QObjectStar) {
+ QObject *o = qvariant_cast<QObject *>(value);
+ needActivate = (data[id].dataType() != QMetaType::QObjectStar || data[id].asQObject() != o);
data[id].setValue(qvariant_cast<QObject *>(value));
- else
+ } else {
+ needActivate = (data[id].dataType() != qMetaTypeId<QVariant>() ||
+ data[id].asQVariant().userType() != value.userType() ||
+ data[id].asQVariant() != value);
data[id].setValue(value);
- activate(object, methodOffset + id, 0);
+ }
+ if (needActivate)
+ activate(object, methodOffset + id, 0);
}
void QDeclarativeVMEMetaObject::listChanged(int id)
diff --git a/src/declarative/qml/qmetaobjectbuilder.cpp b/src/declarative/qml/qmetaobjectbuilder.cpp
index 0954248..58f8811 100644
--- a/src/declarative/qml/qmetaobjectbuilder.cpp
+++ b/src/declarative/qml/qmetaobjectbuilder.cpp
@@ -205,7 +205,7 @@ public:
(const QByteArray& _name, const QByteArray& _type, int notifierIdx=-1)
: name(_name),
type(QMetaObject::normalizedType(_type.constData())),
- flags(Readable | Writable), notifySignal(-1)
+ flags(Readable | Writable | Scriptable), notifySignal(-1)
{
if (notifierIdx >= 0) {
flags |= Notify;
@@ -2187,7 +2187,7 @@ bool QMetaPropertyBuilder::isDesignable() const
/*!
Returns true if the property is scriptable; otherwise returns false.
- This default value is false.
+ This default value is true.
\sa setScriptable(), isDesignable(), isStored()
*/
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index 12f9794..687ff52 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -24,7 +24,7 @@ SOURCES += \
$$PWD/qdeclarativestringconverters.cpp \
$$PWD/qdeclarativeclassfactory.cpp \
$$PWD/qdeclarativeparserstatus.cpp \
- $$PWD/qdeclarativecompositetypemanager.cpp \
+ $$PWD/qdeclarativetypeloader.cpp \
$$PWD/qdeclarativeinfo.cpp \
$$PWD/qdeclarativeerror.cpp \
$$PWD/qdeclarativescriptparser.cpp \
@@ -94,8 +94,7 @@ HEADERS += \
$$PWD/qdeclarativeproperty_p.h \
$$PWD/qdeclarativecontext_p.h \
$$PWD/qdeclarativeinclude_p.h \
- $$PWD/qdeclarativecompositetypedata_p.h \
- $$PWD/qdeclarativecompositetypemanager_p.h \
+ $$PWD/qdeclarativetypeloader_p.h \
$$PWD/qdeclarativelist.h \
$$PWD/qdeclarativelist_p.h \
$$PWD/qdeclarativedata_p.h \
diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp
index 4e9e8d5..6637282 100644
--- a/src/declarative/util/qdeclarativeanimation.cpp
+++ b/src/declarative/util/qdeclarativeanimation.cpp
@@ -84,11 +84,6 @@ QT_BEGIN_NAMESPACE
element directly will result in an error.
*/
-/*!
- \class QDeclarativeAbstractAnimation
- \internal
-*/
-
QDeclarativeAbstractAnimation::QDeclarativeAbstractAnimation(QObject *parent)
: QObject(*(new QDeclarativeAbstractAnimationPrivate), parent)
{
@@ -337,7 +332,7 @@ void QDeclarativeAbstractAnimation::setAlwaysRunToEnd(bool f)
stopped - either by setting the \c running property to false, or by calling
the \c stop() method.
- In the following example, the rectangle will spin indefinately.
+ In the following example, the rectangle will spin indefinitely.
\code
Rectangle {
@@ -574,12 +569,6 @@ void QDeclarativeAbstractAnimation::timelineComplete()
\sa {QML Animation}, {declarative/animation/basics}{Animation basics example}
*/
-/*!
- \internal
- \class QDeclarativePauseAnimation
-*/
-
-
QDeclarativePauseAnimation::QDeclarativePauseAnimation(QObject *parent)
: QDeclarativeAbstractAnimation(*(new QDeclarativePauseAnimationPrivate), parent)
{
@@ -659,11 +648,6 @@ QAbstractAnimation *QDeclarativePauseAnimation::qtAnimation()
\sa {QML Animation}, {declarative/animation/basics}{Animation basics example}
*/
-/*!
- \internal
- \class QDeclarativeColorAnimation
-*/
-
QDeclarativeColorAnimation::QDeclarativeColorAnimation(QObject *parent)
: QDeclarativePropertyAnimation(parent)
{
@@ -776,10 +760,6 @@ void QDeclarativeColorAnimation::setTo(const QColor &t)
\sa StateChangeScript
*/
-/*!
- \internal
- \class QDeclarativeScriptAction
-*/
QDeclarativeScriptAction::QDeclarativeScriptAction(QObject *parent)
:QDeclarativeAbstractAnimation(*(new QDeclarativeScriptActionPrivate), parent)
{
@@ -933,10 +913,6 @@ QAbstractAnimation *QDeclarativeScriptAction::qtAnimation()
\sa {QML Animation}, QtDeclarative
*/
-/*!
- \internal
- \class QDeclarativePropertyAction
-*/
QDeclarativePropertyAction::QDeclarativePropertyAction(QObject *parent)
: QDeclarativeAbstractAnimation(*(new QDeclarativePropertyActionPrivate), parent)
{
@@ -1185,12 +1161,6 @@ void QDeclarativePropertyAction::transition(QDeclarativeStateActions &actions,
\sa {QML Animation}, {declarative/animation/basics}{Animation basics example}
*/
-
-/*!
- \internal
- \class QDeclarativeNumberAnimation
-*/
-
QDeclarativeNumberAnimation::QDeclarativeNumberAnimation(QObject *parent)
: QDeclarativePropertyAnimation(parent)
{
@@ -1276,7 +1246,7 @@ void QDeclarativeNumberAnimation::setTo(qreal t)
/*!
\qmlclass Vector3dAnimation QDeclarativeVector3dAnimation
- \ingroup qml-animation-transition
+ \ingroup qml-animation-transition
\since 4.7
\inherits PropertyAnimation
\brief The Vector3dAnimation element animates changes in QVector3d values.
@@ -1291,12 +1261,6 @@ void QDeclarativeNumberAnimation::setTo(qreal t)
\sa {QML Animation}, {declarative/animation/basics}{Animation basics example}
*/
-
-/*!
- \internal
- \class QDeclarativeVector3dAnimation
-*/
-
QDeclarativeVector3dAnimation::QDeclarativeVector3dAnimation(QObject *parent)
: QDeclarativePropertyAnimation(parent)
{
@@ -1396,12 +1360,6 @@ void QDeclarativeVector3dAnimation::setTo(QVector3D t)
\sa {QML Animation}, {declarative/animation/basics}{Animation basics example}
*/
-
-/*!
- \internal
- \class QDeclarativeRotationAnimation
-*/
-
QVariant _q_interpolateShortestRotation(qreal &f, qreal &t, qreal progress)
{
qreal newt = t;
@@ -1702,11 +1660,6 @@ void QDeclarativeSequentialAnimation::transition(QDeclarativeStateActions &actio
\sa SequentialAnimation, {QML Animation}, {declarative/animation/basics}{Animation basics example}
*/
-/*!
- \internal
- \class QDeclarativeParallelAnimation
-*/
-
QDeclarativeParallelAnimation::QDeclarativeParallelAnimation(QObject *parent) :
QDeclarativeAnimationGroup(parent)
{
@@ -2512,11 +2465,6 @@ void QDeclarativePropertyAnimation::transition(QDeclarativeStateActions &actions
\sa {QML Animation}, {declarative/animation/basics}{Animation basics example}
*/
-
-/*!
- \internal
- \class QDeclarativeParentAnimation
-*/
QDeclarativeParentAnimation::QDeclarativeParentAnimation(QObject *parent)
: QDeclarativeAnimationGroup(*(new QDeclarativeParentAnimationPrivate), parent)
{
@@ -2991,4 +2939,8 @@ void QDeclarativeAnchorAnimation::transition(QDeclarativeStateActions &actions,
}
}
+QDeclarativeScriptActionPrivate::QDeclarativeScriptActionPrivate()
+ : QDeclarativeAbstractAnimationPrivate(), hasRunScriptScript(false), reversing(false), proxy(this), rsa(0) {}
+
+
QT_END_NAMESPACE
diff --git a/src/declarative/util/qdeclarativeanimation_p_p.h b/src/declarative/util/qdeclarativeanimation_p_p.h
index e38580c..26c04d4 100644
--- a/src/declarative/util/qdeclarativeanimation_p_p.h
+++ b/src/declarative/util/qdeclarativeanimation_p_p.h
@@ -247,8 +247,7 @@ class QDeclarativeScriptActionPrivate : public QDeclarativeAbstractAnimationPriv
{
Q_DECLARE_PUBLIC(QDeclarativeScriptAction)
public:
- QDeclarativeScriptActionPrivate()
- : QDeclarativeAbstractAnimationPrivate(), hasRunScriptScript(false), reversing(false), proxy(this), rsa(0) {}
+ QDeclarativeScriptActionPrivate();
void init();
diff --git a/src/declarative/util/qdeclarativebind.cpp b/src/declarative/util/qdeclarativebind.cpp
index 86d08f5..88b45ae 100644
--- a/src/declarative/util/qdeclarativebind.cpp
+++ b/src/declarative/util/qdeclarativebind.cpp
@@ -72,7 +72,7 @@ public:
/*!
\qmlclass Binding QDeclarativeBind
- \ingroup qml-working-with-data
+ \ingroup qml-working-with-data
\since 4.7
\brief The Binding element allows arbitrary property bindings to be created.
@@ -95,18 +95,7 @@ public:
immediately pushed onto the new target.
\sa QtDeclarative
- */
-/*!
- \internal
- \class QDeclarativeBind
- \brief The QDeclarativeBind class allows arbitrary property bindings to be created.
-
- Simple bindings are usually earier to do in-place rather than creating a
- QDeclarativeBind item. For that reason, QDeclarativeBind is usually used to transfer property information
- from Qml to C++.
-
- \sa cppqml
- */
+*/
QDeclarativeBind::QDeclarativeBind(QObject *parent)
: QObject(*(new QDeclarativeBindPrivate), parent)
{
diff --git a/src/declarative/util/qdeclarativeconnections.cpp b/src/declarative/util/qdeclarativeconnections.cpp
index 293928e..15e5ac5 100644
--- a/src/declarative/util/qdeclarativeconnections.cpp
+++ b/src/declarative/util/qdeclarativeconnections.cpp
@@ -124,13 +124,6 @@ public:
\sa QtDeclarative
*/
-
-/*!
- \internal
- \class QDeclarativeConnections
- \brief The QDeclarativeConnections class describes generalized connections to signals.
-
-*/
QDeclarativeConnections::QDeclarativeConnections(QObject *parent) :
QObject(*(new QDeclarativeConnectionsPrivate), parent)
{
diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp
index d84de26..c7d5024 100644
--- a/src/declarative/util/qdeclarativelistmodel.cpp
+++ b/src/declarative/util/qdeclarativelistmodel.cpp
@@ -58,9 +58,6 @@ Q_DECLARE_METATYPE(QListModelInterface *)
QT_BEGIN_NAMESPACE
-#define DATA_ROLE_ID 1
-#define DATA_ROLE_NAME "data"
-
QDeclarativeListModelParser::ListInstruction *QDeclarativeListModelParser::ListModelData::instructions() const
{
return (QDeclarativeListModelParser::ListInstruction *)((char *)this + sizeof(ListModelData));
@@ -769,7 +766,7 @@ bool QDeclarativeListModelParser::definesEmptyList(const QString &s)
}
/*!
- \qmlclass ListElement
+ \qmlclass ListElement QDeclarativeListElement
\ingroup qml-working-with-data
\since 4.7
\brief The ListElement element defines a data item in a ListModel.
@@ -1250,7 +1247,6 @@ void ModelNode::setObjectValue(const QScriptValue& valuemap) {
}
void ModelNode::setListValue(const QScriptValue& valuelist) {
- QScriptValueIterator it(valuelist);
values.clear();
int size = valuelist.property(QLatin1String("length")).toInt32();
for (int i=0; i<size; i++) {
diff --git a/src/declarative/util/qdeclarativelistmodelworkeragent.cpp b/src/declarative/util/qdeclarativelistmodelworkeragent.cpp
index 498de6d..d9df169 100644
--- a/src/declarative/util/qdeclarativelistmodelworkeragent.cpp
+++ b/src/declarative/util/qdeclarativelistmodelworkeragent.cpp
@@ -232,7 +232,7 @@ bool QDeclarativeListModelWorkerAgent::event(QEvent *e)
emit m_orig->itemsMoved(change.index, change.to, change.count);
break;
case Change::Changed:
- emit m_orig->itemsMoved(change.index, change.to, change.count);
+ emit m_orig->itemsChanged(change.index, change.to, orig->m_roles.keys());
break;
}
}
diff --git a/src/declarative/util/qdeclarativepixmapcache.cpp b/src/declarative/util/qdeclarativepixmapcache.cpp
index de2de21..4fc52f5 100644
--- a/src/declarative/util/qdeclarativepixmapcache.cpp
+++ b/src/declarative/util/qdeclarativepixmapcache.cpp
@@ -155,7 +155,7 @@ protected:
private:
friend class QDeclarativePixmapReaderThreadObject;
void processJobs();
- void processJob(QDeclarativePixmapReply *);
+ void processJob(QDeclarativePixmapReply *, const QUrl &, const QSize &);
void networkRequestDone(QNetworkReply *);
QList<QDeclarativePixmapReply*> jobs;
@@ -434,23 +434,24 @@ void QDeclarativePixmapReader::processJobs()
QDeclarativePixmapReply *runningJob = jobs.takeLast();
runningJob->loading = true;
+ QUrl url = runningJob->data->url;
+ QSize requestSize = runningJob->data->requestSize;
locker.unlock();
- processJob(runningJob);
+ processJob(runningJob, url, requestSize);
locker.relock();
}
}
}
-void QDeclarativePixmapReader::processJob(QDeclarativePixmapReply *runningJob)
+void QDeclarativePixmapReader::processJob(QDeclarativePixmapReply *runningJob, const QUrl &url,
+ const QSize &requestSize)
{
- QUrl url = runningJob->data->url;
-
// fetch
if (url.scheme() == QLatin1String("image")) {
// Use QmlImageProvider
QSize readSize;
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
- QImage image = ep->getImageFromProvider(url, &readSize, runningJob->data->requestSize);
+ QImage image = ep->getImageFromProvider(url, &readSize, requestSize);
QDeclarativePixmapReply::ReadError errorCode = QDeclarativePixmapReply::NoError;
QString errorStr;
@@ -472,7 +473,7 @@ void QDeclarativePixmapReader::processJob(QDeclarativePixmapReply *runningJob)
QFile f(lf);
QSize readSize;
if (f.open(QIODevice::ReadOnly)) {
- if (!readImage(url, &f, &image, &errorStr, &readSize, runningJob->data->requestSize))
+ if (!readImage(url, &f, &image, &errorStr, &readSize, requestSize))
errorCode = QDeclarativePixmapReply::Loading;
} else {
errorStr = QDeclarativePixmap::tr("Cannot open: %1").arg(url.toString());
@@ -663,6 +664,7 @@ void QDeclarativePixmapStore::shrinkCache(int remove)
data->prevUnreferenced = 0;
remove -= data->cost();
+ m_unreferencedCost -= data->cost();
data->removeFromCache();
delete data;
}
diff --git a/src/declarative/util/qdeclarativepropertychanges.cpp b/src/declarative/util/qdeclarativepropertychanges.cpp
index c28ada3..e897458 100644
--- a/src/declarative/util/qdeclarativepropertychanges.cpp
+++ b/src/declarative/util/qdeclarativepropertychanges.cpp
@@ -127,12 +127,6 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \internal
- \class QDeclarativePropertyChanges
- \brief The QDeclarativePropertyChanges class describes new property values for a state.
-*/
-
-/*!
\qmlproperty Object PropertyChanges::target
This property holds the object which contains the properties to be changed.
*/
diff --git a/src/declarative/util/qdeclarativesmoothedanimation.cpp b/src/declarative/util/qdeclarativesmoothedanimation.cpp
index b2f02e6..ca83c52 100644
--- a/src/declarative/util/qdeclarativesmoothedanimation.cpp
+++ b/src/declarative/util/qdeclarativesmoothedanimation.cpp
@@ -214,22 +214,23 @@ void QSmoothedAnimation::init()
}
bool hasReversed = trackVelocity != 0. &&
- ((trackVelocity > 0) == ((initialValue - to) > 0));
+ ((!invert) == ((initialValue - to) > 0));
if (hasReversed) {
switch (reversingMode) {
default:
case QDeclarativeSmoothedAnimation::Eased:
+ initialVelocity = -trackVelocity;
break;
case QDeclarativeSmoothedAnimation::Sync:
QDeclarativePropertyPrivate::write(target, to,
QDeclarativePropertyPrivate::BypassInterceptor
| QDeclarativePropertyPrivate::DontRemoveBinding);
+ trackVelocity = 0;
stop();
return;
case QDeclarativeSmoothedAnimation::Immediate:
initialVelocity = 0;
- delayedStop();
break;
}
}
@@ -311,6 +312,17 @@ QDeclarativeSmoothedAnimationPrivate::QDeclarativeSmoothedAnimationPrivate()
QDeclarative_setParent_noEvent(anim, q);
}
+void QDeclarativeSmoothedAnimationPrivate::updateRunningAnimations()
+{
+ foreach(QSmoothedAnimation* ease, activeAnimations.values()){
+ ease->maximumEasingTime = anim->maximumEasingTime;
+ ease->reversingMode = anim->reversingMode;
+ ease->velocity = anim->velocity;
+ ease->userDuration = anim->userDuration;
+ ease->init();
+ }
+}
+
QAbstractAnimation* QDeclarativeSmoothedAnimation::qtAnimation()
{
Q_D(QDeclarativeSmoothedAnimation);
@@ -340,7 +352,6 @@ void QDeclarativeSmoothedAnimation::transition(QDeclarativeStateActions &actions
ease = d->activeAnimations.value((*d->actions)[i].property);
needsRestart = true;
}
-
ease->target = (*d->actions)[i].property;
ease->to = (*d->actions)[i].toValue.toReal();
@@ -394,6 +405,7 @@ void QDeclarativeSmoothedAnimation::setReversingMode(ReversingMode m)
d->anim->reversingMode = m;
emit reversingModeChanged();
+ d->updateRunningAnimations();
}
/*!
@@ -402,6 +414,9 @@ void QDeclarativeSmoothedAnimation::setReversingMode(ReversingMode m)
This property holds the animation duration, in msecs, used when tracking the source.
Setting this to -1 (the default) disables the duration value.
+
+ If the velocity value and the duration value are both enabled, then the animation will
+ use whichever gives the shorter duration.
*/
int QDeclarativeSmoothedAnimation::duration() const
{
@@ -414,7 +429,10 @@ void QDeclarativeSmoothedAnimation::setDuration(int duration)
Q_D(QDeclarativeSmoothedAnimation);
if (duration != -1)
QDeclarativeNumberAnimation::setDuration(duration);
+ if(duration == d->anim->userDuration)
+ return;
d->anim->userDuration = duration;
+ d->updateRunningAnimations();
}
qreal QDeclarativeSmoothedAnimation::velocity() const
@@ -431,6 +449,9 @@ qreal QDeclarativeSmoothedAnimation::velocity() const
The default velocity of SmoothedAnimation is 200 units/second.
Setting this to -1 disables the velocity value.
+
+ If the velocity value and the duration value are both enabled, then the animation will
+ use whichever gives the shorter duration.
*/
void QDeclarativeSmoothedAnimation::setVelocity(qreal v)
{
@@ -440,12 +461,13 @@ void QDeclarativeSmoothedAnimation::setVelocity(qreal v)
d->anim->velocity = v;
emit velocityChanged();
+ d->updateRunningAnimations();
}
/*!
\qmlproperty int SmoothedAnimation::maximumEasingTime
- This property specifies the maximum time, in msecs, an "eases" during the follow should take.
+ This property specifies the maximum time, in msecs, any "eases" during the follow should take.
Setting this property causes the velocity to "level out" after at a time. Setting
a negative value reverts to the normal mode of easing over the entire animation
duration.
@@ -461,8 +483,11 @@ int QDeclarativeSmoothedAnimation::maximumEasingTime() const
void QDeclarativeSmoothedAnimation::setMaximumEasingTime(int v)
{
Q_D(QDeclarativeSmoothedAnimation);
+ if(v == d->anim->maximumEasingTime)
+ return;
d->anim->maximumEasingTime = v;
emit maximumEasingTimeChanged();
+ d->updateRunningAnimations();
}
QT_END_NAMESPACE
diff --git a/src/declarative/util/qdeclarativesmoothedanimation_p_p.h b/src/declarative/util/qdeclarativesmoothedanimation_p_p.h
index 8cdbea2..cb0f4c2 100644
--- a/src/declarative/util/qdeclarativesmoothedanimation_p_p.h
+++ b/src/declarative/util/qdeclarativesmoothedanimation_p_p.h
@@ -123,6 +123,7 @@ class QDeclarativeSmoothedAnimationPrivate : public QDeclarativePropertyAnimatio
Q_DECLARE_PUBLIC(QDeclarativeSmoothedAnimation)
public:
QDeclarativeSmoothedAnimationPrivate();
+ void updateRunningAnimations();
QParallelAnimationGroup *wrapperGroup;
QSmoothedAnimation *anim;
diff --git a/src/declarative/util/qdeclarativespringanimation.cpp b/src/declarative/util/qdeclarativespringanimation.cpp
index fce4097..e0fc45d 100644
--- a/src/declarative/util/qdeclarativespringanimation.cpp
+++ b/src/declarative/util/qdeclarativespringanimation.cpp
@@ -62,10 +62,12 @@ public:
struct SpringAnimation {
SpringAnimation()
- : currentValue(0), to(0), velocity(0){}
+ : currentValue(0), to(0), velocity(0), start(0), duration(0) {}
qreal currentValue;
qreal to;
qreal velocity;
+ int start;
+ int duration;
};
QHash<QDeclarativeProperty, SpringAnimation> activeAnimations;
@@ -135,7 +137,6 @@ void QDeclarativeSpringAnimationPrivate::tick(int time)
bool QDeclarativeSpringAnimationPrivate::animate(const QDeclarativeProperty &property, SpringAnimation &animation, int elapsed)
{
-
qreal srcVal = animation.to;
bool stop = false;
@@ -192,18 +193,14 @@ bool QDeclarativeSpringAnimationPrivate::animate(const QDeclarativeProperty &pro
animation.currentValue += moveBy;
if (haveModulus)
animation.currentValue = fmod(animation.currentValue, modulus);
- if (animation.currentValue > animation.to) {
- animation.currentValue = animation.to;
- stop = true;
- }
} else {
animation.currentValue -= moveBy;
if (haveModulus && animation.currentValue < 0.0)
animation.currentValue = fmod(animation.currentValue, modulus) + modulus;
- if (animation.currentValue < animation.to) {
- animation.currentValue = animation.to;
- stop = true;
- }
+ }
+ if (lastTime - animation.start >= animation.duration) {
+ animation.currentValue = animation.to;
+ stop = true;
}
}
@@ -222,8 +219,18 @@ void QDeclarativeSpringAnimationPrivate::updateMode()
mode = Track;
else if (spring > 0.)
mode = Spring;
- else
+ else {
mode = Velocity;
+ QHash<QDeclarativeProperty, SpringAnimation>::iterator it;
+ for (it = activeAnimations.begin(); it != activeAnimations.end(); ++it) {
+ SpringAnimation &animation = *it;
+ animation.start = lastTime;
+ qreal dist = qAbs(animation.currentValue - animation.to);
+ if (haveModulus && dist > modulus / 2)
+ dist = modulus - fmod(dist, modulus);
+ animation.duration = dist / velocityms;
+ }
+ }
}
/*!
@@ -378,6 +385,7 @@ void QDeclarativeSpringAnimation::setModulus(qreal modulus)
if (d->modulus != modulus) {
d->haveModulus = modulus != 0.0;
d->modulus = modulus;
+ d->updateMode();
emit modulusChanged();
}
}
@@ -429,10 +437,17 @@ void QDeclarativeSpringAnimation::transition(QDeclarativeStateActions &actions,
QDeclarativeSpringAnimationPrivate::SpringAnimation &animation
= d->activeAnimations[property];
animation.to = d->actions->at(i).toValue.toReal();
+ animation.start = d->lastTime;
if (d->fromIsDefined)
animation.currentValue = d->actions->at(i).fromValue.toReal();
else
animation.currentValue = property.read().toReal();
+ if (d->mode == QDeclarativeSpringAnimationPrivate::Velocity) {
+ qreal dist = qAbs(animation.currentValue - animation.to);
+ if (d->haveModulus && dist > d->modulus / 2)
+ dist = d->modulus - fmod(dist, d->modulus);
+ animation.duration = dist / d->velocityms;
+ }
}
}
}
diff --git a/src/declarative/util/qdeclarativestate.cpp b/src/declarative/util/qdeclarativestate.cpp
index 6e17cf2..1ed7923 100644
--- a/src/declarative/util/qdeclarativestate.cpp
+++ b/src/declarative/util/qdeclarativestate.cpp
@@ -123,9 +123,6 @@ bool QDeclarativeActionEvent::override(QDeclarativeActionEvent *other)
return false;
}
-/*!
- \internal
-*/
QDeclarativeStateOperation::QDeclarativeStateOperation(QObjectPrivate &dd, QObject *parent)
: QObject(dd, parent)
{
@@ -164,20 +161,6 @@ QDeclarativeStateOperation::QDeclarativeStateOperation(QObjectPrivate &dd, QObje
\sa {declarative/animation/states}{states example}, {qmlstates}{States},
{qdeclarativeanimation.html#transitions}{QML Transitions}, QtDeclarative
*/
-
-/*!
- \internal
- \class QDeclarativeState
- \brief The QDeclarativeState class allows you to define configurations of objects and properties.
-
-
- QDeclarativeState allows you to specify a state as a set of batched changes from the default
- configuration.
-
- \sa {states-transitions}{States and Transitions}
-*/
-
-
QDeclarativeState::QDeclarativeState(QObject *parent)
: QObject(*(new QDeclarativeStatePrivate), parent)
{
diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp
index 6e6f0cb..845b3da 100644
--- a/src/declarative/util/qdeclarativestateoperations.cpp
+++ b/src/declarative/util/qdeclarativestateoperations.cpp
@@ -1427,6 +1427,7 @@ void QDeclarativeAnchorChanges::clearBindings()
if (!d->target)
return;
+ //### should this (saving "from" values) be moved to saveCurrentValues()?
d->fromX = d->target->x();
d->fromY = d->target->y();
d->fromWidth = d->target->width();
@@ -1486,22 +1487,8 @@ void QDeclarativeAnchorChanges::rewind()
return;
QDeclarativeItemPrivate *targetPrivate = QDeclarativeItemPrivate::get(d->target);
- //restore previous anchors
- if (d->rewindLeft.anchorLine != QDeclarativeAnchorLine::Invalid)
- targetPrivate->anchors()->setLeft(d->rewindLeft);
- if (d->rewindRight.anchorLine != QDeclarativeAnchorLine::Invalid)
- targetPrivate->anchors()->setRight(d->rewindRight);
- if (d->rewindHCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
- targetPrivate->anchors()->setHorizontalCenter(d->rewindHCenter);
- if (d->rewindTop.anchorLine != QDeclarativeAnchorLine::Invalid)
- targetPrivate->anchors()->setTop(d->rewindTop);
- if (d->rewindBottom.anchorLine != QDeclarativeAnchorLine::Invalid)
- targetPrivate->anchors()->setBottom(d->rewindBottom);
- if (d->rewindVCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
- targetPrivate->anchors()->setVerticalCenter(d->rewindVCenter);
- if (d->rewindBaseline.anchorLine != QDeclarativeAnchorLine::Invalid)
- targetPrivate->anchors()->setBaseline(d->rewindBaseline);
+ //restore previous values (but not previous bindings, i.e. anchors)
d->target->setX(d->rewindX);
d->target->setY(d->rewindY);
if (targetPrivate->widthValid) {
diff --git a/src/declarative/util/qdeclarativetransition.cpp b/src/declarative/util/qdeclarativetransition.cpp
index 21d7ded..478c7f4 100644
--- a/src/declarative/util/qdeclarativetransition.cpp
+++ b/src/declarative/util/qdeclarativetransition.cpp
@@ -99,12 +99,6 @@ QT_BEGIN_NAMESPACE
\sa {QML Animation}, {declarative/animation/states}{states example}, {qmlstates}{States}, {QtDeclarative}
*/
-/*!
- \internal
- \class QDeclarativeTransition
- \brief The QDeclarativeTransition class allows you to define animated transitions that occur on state changes.
-*/
-
//ParallelAnimationWrapper allows us to do a "callback" when the animation finishes, rather than connecting
//and disconnecting signals and slots frequently
class ParallelAnimationWrapper : public QParallelAnimationGroup
diff --git a/src/declarative/util/qdeclarativetransitionmanager.cpp b/src/declarative/util/qdeclarativetransitionmanager.cpp
index 9f198e4..d82c4bb 100644
--- a/src/declarative/util/qdeclarativetransitionmanager.cpp
+++ b/src/declarative/util/qdeclarativetransitionmanager.cpp
@@ -176,7 +176,7 @@ void QDeclarativeTransitionManager::transition(const QList<QDeclarativeAction> &
if (action.event->isReversable()) {
action.event->clearBindings();
action.event->rewind();
- action.event->clearBindings();
+ action.event->clearBindings(); //### shouldn't be needed
}
continue;
}
diff --git a/src/declarative/util/qdeclarativeview.cpp b/src/declarative/util/qdeclarativeview.cpp
index 8f06858..7b88610 100644
--- a/src/declarative/util/qdeclarativeview.cpp
+++ b/src/declarative/util/qdeclarativeview.cpp
@@ -702,6 +702,23 @@ void QDeclarativeView::paintEvent(QPaintEvent *event)
if (frameRateDebug())
qDebug() << "paintEvent:" << d->frameTimer.elapsed() << "time since last frame:" << time;
+
+#if QT_SHOW_DECLARATIVEVIEW_FPS
+ static QTime timer;
+ static int frames;
+
+ if (frames == 0) {
+ timer.start();
+ } else if (timer.elapsed() > 5000) {
+ qreal avgtime = timer.elapsed() / (qreal) frames;
+ qDebug("Average time per frame: %f ms (%i fps)", avgtime, int(1000 / avgtime));
+ timer.start();
+ frames = 0;
+ }
+ ++frames;
+ scene()->update();
+#endif
+
}
QT_END_NAMESPACE
diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp
index cef78af..905ef1e 100644
--- a/src/declarative/util/qdeclarativexmllistmodel.cpp
+++ b/src/declarative/util/qdeclarativexmllistmodel.cpp
@@ -466,8 +466,6 @@ public:
QList<QDeclarativeXmlListModelRole *> roleObjects;
static void append_role(QDeclarativeListProperty<QDeclarativeXmlListModelRole> *list, QDeclarativeXmlListModelRole *role);
static void clear_role(QDeclarativeListProperty<QDeclarativeXmlListModelRole> *list);
- static void removeAt_role(QDeclarativeListProperty<QDeclarativeXmlListModelRole> *list, int i);
- static void insert_role(QDeclarativeListProperty<QDeclarativeXmlListModelRole> *list, int i, QDeclarativeXmlListModelRole *role);
QList<QList<QVariant> > data;
int redirectCount;
};
@@ -500,11 +498,6 @@ void QDeclarativeXmlListModelPrivate::clear_role(QDeclarativeListProperty<QDecla
}
/*!
- \class QDeclarativeXmlListModel
- \internal
-*/
-
-/*!
\qmlclass XmlListModel QDeclarativeXmlListModel
\ingroup qml-working-with-data
\since 4.7