diff options
Diffstat (limited to 'src')
126 files changed, 3271 insertions, 2836 deletions
diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index 9c46467..dfc4244 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -2,6 +2,12 @@ The changes below are pre Qt 4.7.0 RC Flickable: overShoot is replaced by boundsBehavior enumeration. +Component: isReady, isLoading, isError and isNull properties removed, use + status property instead +QList<QObject*> models no longer provide properties in model object. The +properties are now updated when the object changes. An object's property +"foo" may now be accessed as "foo", modelData.foo" or model.modelData.foo" + C++ API ------- diff --git a/src/declarative/graphicsitems/qdeclarativeanchors.cpp b/src/declarative/graphicsitems/qdeclarativeanchors.cpp index f15316b..ef07cbb 100644 --- a/src/declarative/graphicsitems/qdeclarativeanchors.cpp +++ b/src/declarative/graphicsitems/qdeclarativeanchors.cpp @@ -128,7 +128,6 @@ static qreal adjustedPosition(QGraphicsObject *item, QDeclarativeAnchorLine::Anc \internal \class QDeclarativeAnchors \since 4.7 - \ingroup group_layouts \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. diff --git a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp index 06f8363..018bd55 100644 --- a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp @@ -57,9 +57,25 @@ QT_BEGIN_NAMESPACE \inherits Item \since 4.7 + A BorderImage breaks an image into 9 sections, as shown below: + + \image declarative-scalegrid.png + + When the image is scaled: + \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} + \endlist + + Examples: \snippet snippets/declarative/border-image.qml 0 \image BorderImage.png + + The \l{declarative/border-image}{BorderImage example} shows how a BorderImage can be used to simulate a shadow effect on a + rectangular item. */ /*! @@ -86,10 +102,10 @@ QDeclarativeBorderImage::~QDeclarativeBorderImage() This property holds the status of image loading. It can be one of: \list - \o Null - no image has been set - \o Ready - the image has been loaded - \o Loading - the image is currently being loaded - \o Error - an error occurred while loading the image + \o BorderImage.Null - no image has been set + \o BorderImage.Ready - the image has been loaded + \o BorderImage.Loading - the image is currently being loaded + \o BorderImage.Error - an error occurred while loading the image \endlist \sa progress @@ -255,21 +271,17 @@ void QDeclarativeBorderImage::load() \qmlproperty int BorderImage::border.top \qmlproperty int BorderImage::border.bottom - \target ImagexmlpropertiesscaleGrid - - The 4 border lines (2 horizontal and 2 vertical) break an 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 - When the image is scaled: - \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} - \endlist + 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 from the respective side. For example, \c{border.bottom: 10} 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}. @@ -288,9 +300,9 @@ QDeclarativeScaleGrid *QDeclarativeBorderImage::border() This property describes how to repeat or stretch the middle parts of the border image. \list - \o Stretch - Scale the image to fit to the available area. - \o Repeat - Tile the image until there is no more space. May crop the last image. - \o Round - Like Repeat, but scales the images down to ensure that the last image is not cropped. + \o BorderImage.Stretch - Scale 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 */ QDeclarativeBorderImage::TileMode QDeclarativeBorderImage::horizontalTileMode() const diff --git a/src/declarative/graphicsitems/qdeclarativeevents.cpp b/src/declarative/graphicsitems/qdeclarativeevents.cpp index 4425c97..81ec6e1 100644 --- a/src/declarative/graphicsitems/qdeclarativeevents.cpp +++ b/src/declarative/graphicsitems/qdeclarativeevents.cpp @@ -151,7 +151,7 @@ Item { \list \o Qt.LeftButton \o Qt.RightButton - \o Qt.MidButton + \o Qt.MiddleButton \endlist */ @@ -174,7 +174,7 @@ Item { \list \o Qt.LeftButton \o Qt.RightButton - \o Qt.MidButton + \o Qt.MiddleButton \endlist */ diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp index b462443..34b0606 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp @@ -345,19 +345,21 @@ void QDeclarativeFlickablePrivate::updateBeginningEnd() \code Flickable { - width: 200; height: 200; contentWidth: image.width; contentHeight: image.height - Image { id: image; source: "bigimage.png" } + width: 200; height: 200 + contentWidth: image.width; contentHeight: image.height + + Image { id: image; source: "bigImage.png" } } \endcode \image flickable.gif - \note Flickable does not automatically clip its contents. If - it is not full-screen it is likely that \c clip should be set - to true. + 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. - \note Due to an implementation detail items placed inside a flickable cannot anchor to it by - id, use 'parent' instead. + \note Due to an implementation detail, items placed inside a Flickable cannot anchor to it by + \c id. Use \c parent instead. */ /*! @@ -400,18 +402,17 @@ void QDeclarativeFlickablePrivate::updateBeginningEnd() These properties describe the position and size of the currently viewed area. The size is defined as the percentage of the full view currently visible, scaled to 0.0 - 1.0. The page position is usually in the range 0.0 (beginning) to - 1.0 minus size ratio (end), i.e. yPosition is in the range 0.0 to 1.0-heightRatio. + 1.0 minus size ratio (end), i.e. \c yPosition is in the range 0.0 to 1.0-\c heightRatio. However, it is possible for the contents to be dragged outside of the normal range, resulting in the page positions also being outside the normal range. - These properties are typically used to draw a scrollbar, for example: - \code - Rectangle { - opacity: 0.5; anchors.right: MyListView.right-2; width: 6 - y: MyListView.visibleArea.yPosition * MyListView.height - height: MyListView.visibleArea.heightRatio * MyListView.height - } - \endcode + These properties are typically used to draw a scrollbar. For example: + + \snippet doc/src/snippets/declarative/flickableScrollbar.qml 0 + \dots 4 + \snippet doc/src/snippets/declarative/flickableScrollbar.qml 1 + + \sa {declarative/scrollbar}{scrollbar example} */ QDeclarativeFlickable::QDeclarativeFlickable(QDeclarativeItem *parent) @@ -479,11 +480,12 @@ void QDeclarativeFlickable::setContentY(qreal pos) /*! \qmlproperty bool Flickable::interactive - A user cannot drag or flick a Flickable that is not 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 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 viewing detailed information on a location popup that is a child of the Flickable. + freeze a flickable map while scrolling through a pop-up dialog that is a child of the Flickable. */ bool QDeclarativeFlickable::isInteractive() const { @@ -585,13 +587,13 @@ QDeclarativeFlickableVisibleArea *QDeclarativeFlickable::visibleArea() This property determines which directions the view can be flicked. \list - \o AutoFlickDirection (default) - allows flicking vertically if the + \o Flickable.AutoFlickDirection (default) - allows flicking vertically if the \e contentHeight is not equal to the \e height of the Flickable. Allows flicking horizontally if the \e contentWidth is not equal to the \e width of the Flickable. - \o HorizontalFlick - allows flicking horizontally. - \o VerticalFlick - allows flicking vertically. - \o HorizontalAndVerticalFlick - allows flicking in both directions. + \o Flickable.HorizontalFlick - allows flicking horizontally. + \o Flickable.VerticalFlick - allows flicking vertically. + \o Flickable.HorizontalAndVerticalFlick - allows flicking in both directions. \endlist */ QDeclarativeFlickable::FlickDirection QDeclarativeFlickable::flickDirection() const @@ -1026,14 +1028,14 @@ void QDeclarativeFlickable::setOverShoot(bool o) This enables the feeling that the edges of the view are soft, rather than a hard physical boundary. - boundsBehavior can be one of: + The \c boundsBehavior can be one of: \list - \o \e StopAtBounds - the contents can not be dragged beyond the boundary + \o \e Flickable.StopAtBounds - the contents can not be dragged beyond the boundary of the flickable, and flicks will not overshoot. - \o \e DragOverBounds - the contents can be dragged beyond the boundary + \o \e Flickable.DragOverBounds - the contents can be dragged beyond the boundary of the Flickable, but flicks will not overshoot. - \o \e DragAndOvershootBounds (default) - the contents can be dragged + \o \e Flickable.DragAndOvershootBounds (default) - the contents can be dragged beyond the boundary of the Flickable, and can overshoot the boundary when flicked. \endlist @@ -1059,12 +1061,16 @@ void QDeclarativeFlickable::setBoundsBehavior(BoundsBehavior b) \qmlproperty int Flickable::contentHeight The dimensions of the content (the surface controlled by Flickable). Typically this - should be set to the combined size of the items placed in the Flickable. + should be set to the combined size of the items placed in the Flickable. Note this + can be set automatically using \l {Item::childrenRect.width}{childrenRect.width} + and \l {Item::childrenRect.height}{childrenRect.height}. For example: \code Flickable { - width: 320; height: 480; contentWidth: image.width; contentHeight: image.height - Image { id: image; source: "bigimage.png" } + width: 320; height: 480 + contentWidth: childrenRect.width; contentHeight: childrenRect.height + + Image { id: image; source: "bigImage.png" } } \endcode */ @@ -1085,7 +1091,7 @@ void QDeclarativeFlickable::setContentWidth(qreal w) else d->viewport->setWidth(w); // Make sure that we're entirely in view. - if (!d->pressed) { + if (!d->pressed && !d->moving) { int oldDuration = d->fixupDuration; d->fixupDuration = 0; d->fixupX(); @@ -1112,7 +1118,7 @@ void QDeclarativeFlickable::setContentHeight(qreal h) else d->viewport->setHeight(h); // Make sure that we're entirely in view. - if (!d->pressed) { + if (!d->pressed && !d->moving) { int oldDuration = d->fixupDuration; d->fixupDuration = 0; d->fixupY(); diff --git a/src/declarative/graphicsitems/qdeclarativeflipable.cpp b/src/declarative/graphicsitems/qdeclarativeflipable.cpp index 57045f1..d926119 100644 --- a/src/declarative/graphicsitems/qdeclarativeflipable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflipable.cpp @@ -94,8 +94,6 @@ public: \class QDeclarativeFlipable \brief The Flipable item provides a surface that can be flipped. - \ingroup group_widgets - Flipable is an item that can be visibly "flipped" between its front and back sides. */ @@ -169,7 +167,7 @@ void QDeclarativeFlipable::retransformBack() \qmlproperty enumeration Flipable::side The side of the Flippable currently visible. Possible values are \c - Front and \c Back. + Flippable.Front and \c Flippable.Back. */ QDeclarativeFlipable::Side QDeclarativeFlipable::side() const { @@ -192,12 +190,15 @@ void QDeclarativeFlipablePrivate::updateSceneTransformFromParent() QPointF p2(1, 0); QPointF p3(1, 1); - p1 = sceneTransform.map(p1); - p2 = sceneTransform.map(p2); - p3 = sceneTransform.map(p3); + QPointF scenep1 = sceneTransform.map(p1); + QPointF scenep2 = sceneTransform.map(p2); + QPointF scenep3 = sceneTransform.map(p3); + p1 = q->mapToParent(p1); + p2 = q->mapToParent(p2); + p3 = q->mapToParent(p3); - qreal cross = (p1.x() - p2.x()) * (p3.y() - p2.y()) - - (p1.y() - p2.y()) * (p3.x() - p2.x()); + qreal cross = (scenep1.x() - scenep2.x()) * (scenep3.y() - scenep2.y()) - + (scenep1.y() - scenep2.y()) * (scenep3.x() - scenep2.x()); wantBackYFlipped = p1.x() >= p2.x(); wantBackXFlipped = p2.y() >= p3.y(); diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index f79a853..7b413fb 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -108,7 +108,7 @@ public: , highlightComponent(0), highlight(0), trackedItem(0) , moveReason(Other), buffer(0), highlightXAnimator(0), highlightYAnimator(0) , highlightMoveDuration(150) - , bufferMode(NoBuffer), snapMode(QDeclarativeGridView::NoSnap) + , bufferMode(BufferBefore | BufferAfter), snapMode(QDeclarativeGridView::NoSnap) , ownModel(false), wrap(false), autoHighlight(true) , fixCurrentVisibility(false), lazyRelease(false), layoutScheduled(false) , deferredRelease(false), haveHighlightRange(false) {} @@ -331,7 +331,7 @@ public: QSmoothedAnimation *highlightYAnimator; int highlightMoveDuration; enum BufferMode { NoBuffer = 0x00, BufferBefore = 0x01, BufferAfter = 0x02 }; - BufferMode bufferMode; + int bufferMode; QDeclarativeGridView::SnapMode snapMode; bool ownModel : 1; @@ -378,9 +378,11 @@ FxGridItem *QDeclarativeGridViewPrivate::createItem(int modelIndex) if (model->completePending()) { // complete listItem->item->setZValue(1); + listItem->item->setParentItem(q->viewport()); model->completeItem(); + } else { + listItem->item->setParentItem(q->viewport()); } - listItem->item->setParentItem(q->viewport()); unrequestedItems.remove(listItem->item); } requestedIndex = -1; @@ -855,10 +857,13 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m qreal adjDist = -data.flickTarget + data.move.value(); if (qAbs(adjDist) > qAbs(dist)) { // Prevent painfully slow flicking - adjust velocity to suit flickDeceleration - v2 = accel * 2.0f * qAbs(dist); - v = qSqrt(v2); - if (dist > 0) - v = -v; + qreal adjv2 = accel * 2.0f * qAbs(adjDist); + if (adjv2 > v2) { + v2 = adjv2; + v = qSqrt(v2); + if (dist > 0) + v = -v; + } } dist = adjDist; accel = v2 / (2.0f * qAbs(dist)); @@ -905,6 +910,9 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m In this case ListModel is a handy way for us to test our UI. In practice the model would be implemented in C++, or perhaps via a SQL data source. + Delegates are instantiated as needed and may be destroyed at any time. + State should \e never be stored in a delegate. + \bold Note that views do not enable \e clip automatically. If the view is not clipped by another item or the screen, it will be necessary to set \e {clip: true} in order to have the out of view items clipped @@ -958,7 +966,7 @@ QDeclarativeGridView::~QDeclarativeGridView() id: wrapper GridView.onRemove: SequentialAnimation { PropertyAction { target: wrapper; property: "GridView.delayRemove"; value: true } - NumberAnimation { target: wrapper; property: "scale"; to: 0; duration: 250; easing.type: "InOutQuad" } + NumberAnimation { target: wrapper; property: "scale"; to: 0; duration: 250; easing.type: Easing.InOutQuad } PropertyAction { target: wrapper; property: "GridView.delayRemove"; value: false } } } @@ -1026,6 +1034,7 @@ void QDeclarativeGridView::setModel(const QVariant &model) dataModel->setModel(model); } if (d->model) { + d->bufferMode = QDeclarativeGridViewPrivate::BufferBefore | QDeclarativeGridViewPrivate::BufferAfter; if (isComponentComplete()) { refill(); if (d->currentIndex >= d->model->count() || d->currentIndex < 0) { @@ -1047,12 +1056,17 @@ void QDeclarativeGridView::setModel(const QVariant &model) } /*! - \qmlproperty component GridView::delegate + \qmlproperty Component GridView::delegate The delegate provides a template defining each item instantiated by the view. The index is exposed as an accessible \c index property. Properties of the model are also available depending upon the type of \l {qmlmodels}{Data Model}. + The number of elements in the delegate has a direct effect on the + flicking performance of the view. If at all possible, place functionality + that is not needed for the normal display of the delegate in a \l Loader which + can load additional elements when needed. + Note that the GridView will layout the items based on the size of the root item in the delegate. @@ -1160,7 +1174,7 @@ int QDeclarativeGridView::count() const } /*! - \qmlproperty component GridView::highlight + \qmlproperty Component GridView::highlight This property holds the component to use as the highlight. An instance of the highlight component will be created for each view. @@ -1271,17 +1285,17 @@ void QDeclarativeGridView::setHighlightMoveDuration(int duration) highlight range. Furthermore, the behaviour of the current item index will occur whether or not a highlight exists. - If highlightRangeMode is set to \e ApplyRange the view will + If highlightRangeMode is set to \e GridView.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 list or due to a mouse interaction. - If highlightRangeMode is set to \e StrictlyEnforceRange the highlight will never + If highlightRangeMode is set to \e GridView.StrictlyEnforceRange the highlight will never move outside of the range. This means that the current item will change if a keyboard or mouse action would cause the highlight to move outside of the range. - The default value is \e NoHighlightRange. + The default value is \e GridView.NoHighlightRange. Note that a valid range requires preferredHighlightEnd to be greater than or equal to preferredHighlightBegin. @@ -1339,10 +1353,10 @@ void QDeclarativeGridView::setHighlightRangeMode(HighlightRangeMode mode) \qmlproperty enumeration GridView::flow This property holds the flow of the grid. - Possible values are \c LeftToRight (default) and \c TopToBottom. + Possible values are \c GridView.LeftToRight (default) and \c GridView.TopToBottom. - If \a flow is \c LeftToRight, the view will scroll vertically. - If \a flow is \c TopToBottom, the view will scroll horizontally. + If \a flow is \c GridView.LeftToRight, the view will scroll vertically. + If \a flow is \c GridView.TopToBottom, the view will scroll horizontally. */ QDeclarativeGridView::Flow QDeclarativeGridView::flow() const { @@ -1393,12 +1407,23 @@ void QDeclarativeGridView::setWrapEnabled(bool wrap) } /*! - \qmlproperty int GridView::cacheBuffer - This property holds the number of off-screen pixels to cache. - - This property determines the number of pixels above the top of the view - and below the bottom of the view to cache. Setting this value can make - scrolling the view smoother at the expense of additional memory usage. + \qmlproperty int GridView::cacheBuffer + This property determines whether delegates are retained outside the + visible area of the view. + + If non-zero the view will keep as many delegates + instantiated as will fit within the buffer specified. For example, + if in a vertical view the delegate is 20 pixels high and \c cacheBuffer is + set to 40, then up to 2 delegates above and 2 delegates below the visible + area may be retained. + + Note that cacheBuffer is not a pixel buffer - it only maintains additional + instantiated delegates. + + Setting this value can make scrolling the list smoother at the expense + of additional memory usage. It is not a substitute for creating efficient + delegates; the fewer elements in a delegate, the faster a view may be + scrolled. */ int QDeclarativeGridView::cacheBuffer() const { @@ -1465,10 +1490,10 @@ void QDeclarativeGridView::setCellHeight(int cellHeight) The allowed values are: \list - \o NoSnap (default) - the view will stop anywhere within the visible area. - \o SnapToRow - the view will settle with a row (or column for TopToBottom flow) + \o GridView.NoSnap (default) - the view will stop anywhere within the visible area. + \o GridView.SnapToRow - the view will settle with a row (or column for TopToBottom flow) aligned with the start of the view. - \o SnapOneRow - the view will settle no more than one row (or column for TopToBottom flow) + \o GridView.SnapOneRow - the view will settle no more than one row (or column for TopToBottom flow) away from the first visible row at the time the mouse button is released. This mode is particularly useful for moving one page at a time. \endlist diff --git a/src/declarative/graphicsitems/qdeclarativeimage.cpp b/src/declarative/graphicsitems/qdeclarativeimage.cpp index 247e348..aeddb15 100644 --- a/src/declarative/graphicsitems/qdeclarativeimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeimage.cpp @@ -54,7 +54,27 @@ QT_BEGIN_NAMESPACE \brief The Image element allows you to add bitmaps to a scene. \inherits Item - The Image element supports untransformed, stretched and tiled. + Displays the image from the specified \l source. If a size is not specified explicitly, + the Image element will be sized to the loaded image. + + If the source resolves to a network resource, the image will be loaded asynchronously, + updating the \l progress and \l status properties appropriately. + + Images which are available locally + will be loaded immediately, blocking the user interface. This is typically the + correct behavior for user interface elements. For large local images, which do not need + to be visible immediately, it may be preferable to enable \l asynchronous loading. + This will load the image in the background using a low priority thread. + + Images are cached and shared internally, so if several Image elements have the same source + only one copy of the image will be loaded. + + \bold Note: Images are often the greatest user of memory in QML UIs. It is recommended + that images which do not form part of the user interface have their + size bounded via the \l sourceSize property. This is especially important for content + that is loaded from external sources or provided by the user. + + The Image element supports untransformed, stretched and tiled images. For an explanation of stretching and tiling, see the fillMode property description. @@ -107,15 +127,13 @@ QT_BEGIN_NAMESPACE } \endqml \endtable - */ +*/ /*! \internal \class QDeclarativeImage Image \brief The QDeclarativeImage class provides an image item that you can add to a QDeclarativeView. - \ingroup group_coreitems - Example: \qml Image { source: "pics/star.png" } @@ -181,12 +199,12 @@ void QDeclarativeImagePrivate::setPixmap(const QPixmap &pixmap) than the size of the item. \list - \o Stretch - the image is scaled to fit - \o PreserveAspectFit - the image is scaled uniformly to fit without cropping - \o PreserveAspectCrop - the image is scaled uniformly to fill, cropping if necessary - \o Tile - the image is duplicated horizontally and vertically - \o TileVertically - the image is stretched horizontally and tiled vertically - \o TileHorizontally - the image is stretched vertically and tiled horizontally + \o Image.Stretch - the image is scaled to fit + \o Image.PreserveAspectFit - the image is scaled uniformly to fit without cropping + \o Image.PreserveAspectCrop - the image is scaled uniformly to fill, cropping if necessary + \o Image.Tile - the image is duplicated horizontally and vertically + \o Image.TileVertically - the image is stretched horizontally and tiled vertically + \o Image.TileHorizontally - the image is stretched vertically and tiled horizontally \endlist \image declarative-image_fillMode.gif @@ -225,10 +243,10 @@ qreal QDeclarativeImage::paintedHeight() const This property holds the status of image loading. It can be one of: \list - \o Null - no image has been set - \o Ready - the image has been loaded - \o Loading - the image is currently being loaded - \o Error - an error occurred while loading the image + \o Image.Null - no image has been set + \o Image.Ready - the image has been loaded + \o Image.Loading - the image is currently being loaded + \o Image.Error - an error occurred while loading the image \endlist Note that a change in the status property does not cause anything to happen @@ -296,6 +314,32 @@ qreal QDeclarativeImage::paintedHeight() const If the source is a non-scalable image (eg. JPEG), the loaded image will be no greater than this property specifies. For some formats (currently only JPEG), the whole image will never actually be loaded into memory. + + The example below will ensure that the size of the image in memory is + no larger than 1024x1024 pixels, regardless of the size of the Image element. + + \code + Image { + anchors.fill: parent + source: "images/reallyBigImage.jpg" + sourceSize.width: 1024 + sourceSize.height: 1024 + } + \endcode + + The example below will ensure that the memory used by the image is + no more than necessary to display the image at the size of the Image element. + Of course if the Image element is resized a costly reload will be required, so + use this technique \e only when the Image size is fixed. + + \code + Image { + anchors.fill: parent + source: "images/reallyBigImage.jpg" + sourceSize.width: width + sourceSize.height: height + } + \endcode */ void QDeclarativeImage::updatePaintedGeometry() diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp index 096e4bf..9433ba0 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp @@ -219,46 +219,9 @@ QT_BEGIN_NAMESPACE The angle to rotate, in degrees clockwise. */ - -/*! - \group group_animation - \title Animation -*/ - -/*! - \group group_coreitems - \title Basic Items -*/ - -/*! - \group group_layouts - \title Layouts -*/ - -/*! - \group group_states - \title States and Transitions -*/ - -/*! - \group group_utility - \title Utility -*/ - -/*! - \group group_views - \title Views -*/ - -/*! - \group group_widgets - \title Widgets -*/ - /*! \internal \class QDeclarativeContents - \ingroup group_utility \brief The QDeclarativeContents class gives access to the height and width of an item's contents. */ @@ -267,62 +230,93 @@ QDeclarativeContents::QDeclarativeContents() : m_x(0), m_y(0), m_width(0), m_hei { } +QDeclarativeContents::~QDeclarativeContents() +{ + QList<QGraphicsItem *> children = m_item->childItems(); + for (int i = 0; i < children.count(); ++i) { + QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i)); + if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects? + continue; + QDeclarativeItemPrivate::get(child)->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry | QDeclarativeItemPrivate::Destroyed); + } +} + QRectF QDeclarativeContents::rectF() const { return QRectF(m_x, m_y, m_width, m_height); } -//TODO: optimization: only check sender(), if there is one -void QDeclarativeContents::calcHeight() +void QDeclarativeContents::calcHeight(QDeclarativeItem *changed) { qreal oldy = m_y; qreal oldheight = m_height; - qreal top = FLT_MAX; - qreal bottom = 0; - - QList<QGraphicsItem *> children = m_item->childItems(); - for (int i = 0; i < children.count(); ++i) { - QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i)); - if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects? - continue; - qreal y = child->y(); - if (y + child->height() > bottom) - bottom = y + child->height(); + if (changed) { + qreal top = oldy; + qreal bottom = oldy + oldheight; + qreal y = changed->y(); + if (y + changed->height() > bottom) + bottom = y + changed->height(); if (y < top) top = y; - } - if (!children.isEmpty()) m_y = top; - m_height = qMax(bottom - top, qreal(0.0)); + m_height = bottom - top; + } else { + qreal top = FLT_MAX; + qreal bottom = 0; + QList<QGraphicsItem *> children = m_item->childItems(); + for (int i = 0; i < children.count(); ++i) { + QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i)); + if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects? + continue; + qreal y = child->y(); + if (y + child->height() > bottom) + bottom = y + child->height(); + if (y < top) + top = y; + } + if (!children.isEmpty()) + m_y = top; + m_height = qMax(bottom - top, qreal(0.0)); + } if (m_height != oldheight || m_y != oldy) emit rectChanged(rectF()); } -//TODO: optimization: only check sender(), if there is one -void QDeclarativeContents::calcWidth() +void QDeclarativeContents::calcWidth(QDeclarativeItem *changed) { qreal oldx = m_x; qreal oldwidth = m_width; - qreal left = FLT_MAX; - qreal right = 0; - - QList<QGraphicsItem *> children = m_item->childItems(); - for (int i = 0; i < children.count(); ++i) { - QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i)); - if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects? - continue; - qreal x = child->x(); - if (x + child->width() > right) - right = x + child->width(); + if (changed) { + qreal left = oldx; + qreal right = oldx + oldwidth; + qreal x = changed->x(); + if (x + changed->width() > right) + right = x + changed->width(); if (x < left) left = x; - } - if (!children.isEmpty()) m_x = left; - m_width = qMax(right - left, qreal(0.0)); + m_width = right - left; + } else { + qreal left = FLT_MAX; + qreal right = 0; + QList<QGraphicsItem *> children = m_item->childItems(); + for (int i = 0; i < children.count(); ++i) { + QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i)); + if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects? + continue; + qreal x = child->x(); + if (x + child->width() > right) + right = x + child->width(); + if (x < left) + left = x; + } + if (!children.isEmpty()) + m_x = left; + m_width = qMax(right - left, qreal(0.0)); + } if (m_width != oldwidth || m_x != oldx) emit rectChanged(rectF()); @@ -331,23 +325,55 @@ void QDeclarativeContents::calcWidth() void QDeclarativeContents::setItem(QDeclarativeItem *item) { m_item = item; + //### optimize + connect(this, SIGNAL(rectChanged(QRectF)), m_item, SIGNAL(childrenRectChanged(QRectF))); QList<QGraphicsItem *> children = m_item->childItems(); for (int i = 0; i < children.count(); ++i) { QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i)); if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects? continue; - connect(child, SIGNAL(heightChanged()), this, SLOT(calcHeight())); - connect(child, SIGNAL(yChanged()), this, SLOT(calcHeight())); - connect(child, SIGNAL(widthChanged()), this, SLOT(calcWidth())); - connect(child, SIGNAL(xChanged()), this, SLOT(calcWidth())); - connect(this, SIGNAL(rectChanged(QRectF)), m_item, SIGNAL(childrenRectChanged(QRectF))); + QDeclarativeItemPrivate::get(child)->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry | QDeclarativeItemPrivate::Destroyed); + //###what about changes to visibility? } + //### defer until componentComplete calcHeight(); calcWidth(); } +void QDeclarativeContents::itemGeometryChanged(QDeclarativeItem *changed, const QRectF &newGeometry, const QRectF &oldGeometry) +{ + if (newGeometry.width() != oldGeometry.width()) + calcWidth(changed); + if (newGeometry.height() != oldGeometry.height()) + calcHeight(changed); +} + +void QDeclarativeContents::itemDestroyed(QDeclarativeItem *item) +{ + if (item) + QDeclarativeItemPrivate::get(item)->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry | QDeclarativeItemPrivate::Destroyed); + calcWidth(); + calcHeight(); +} + +void QDeclarativeContents::childRemoved(QDeclarativeItem *item) +{ + if (item) + QDeclarativeItemPrivate::get(item)->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry | QDeclarativeItemPrivate::Destroyed); + calcWidth(); + calcHeight(); +} + +void QDeclarativeContents::childAdded(QDeclarativeItem *item) +{ + if (item) + QDeclarativeItemPrivate::get(item)->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry | QDeclarativeItemPrivate::Destroyed); + calcWidth(item); + calcHeight(item); +} + QDeclarativeItemKeyFilter::QDeclarativeItemKeyFilter(QDeclarativeItem *item) : m_next(0) { @@ -444,7 +470,7 @@ void QDeclarativeItemKeyFilter::componentComplete() If an item has been set for a direction and the KeyNavigation attached property receives the corresponding key press and release events, the events will be accepted by - KeyNaviagtion and will not propagate any further. + KeyNavigation and will not propagate any further. \sa {Keys}{Keys attached property} */ @@ -694,7 +720,7 @@ void QDeclarativeKeyNavigationAttached::keyReleased(QKeyEvent *event) */ /*! - \qmlproperty List<Object> Keys::forwardTo + \qmlproperty list<Object> Keys::forwardTo This property provides a way to forward key presses, key releases, and keyboard input coming from input methods to other items. This can be useful when you want @@ -1258,8 +1284,6 @@ QDeclarativeKeysAttached *QDeclarativeKeysAttached::qmlAttachedProperties(QObjec changes. For many properties in Item or Item derivatives this can be used to add a touch of imperative logic to your application (when absolutely necessary). - - \ingroup group_coreitems */ /*! @@ -1388,6 +1412,7 @@ QDeclarativeItem::~QDeclarativeItem() delete d->_anchorLines; d->_anchorLines = 0; delete d->_anchors; d->_anchors = 0; delete d->_stateGroup; d->_stateGroup = 0; + delete d->_contents; d->_contents = 0; } /*! @@ -1407,7 +1432,7 @@ QDeclarativeItem::~QDeclarativeItem() } \endqml - The default transform origin is \c Center. + The default transform origin is \c Item.Center. */ /*! @@ -1472,11 +1497,6 @@ QDeclarativeItem *QDeclarativeItem::parentItem() const */ /*! - \property QDeclarativeItem::resources - \internal -*/ - -/*! Returns true if construction of the QML component is complete; otherwise returns false. @@ -1491,18 +1511,6 @@ bool QDeclarativeItem::isComponentComplete() const return d->_componentComplete; } -/*! - \property QDeclarativeItem::anchors - \internal -*/ - -/*! \internal */ -QDeclarativeAnchors *QDeclarativeItem::anchors() -{ - Q_D(QDeclarativeItem); - return d->anchors(); -} - void QDeclarativeItemPrivate::data_append(QDeclarativeListProperty<QObject> *prop, QObject *o) { if (!o) @@ -1624,29 +1632,23 @@ void QDeclarativeItemPrivate::parentProperty(QObject *o, void *rv, QDeclarativeN specify it. */ -/*! - \property QDeclarativeItem::data - \internal -*/ - /*! \internal */ -QDeclarativeListProperty<QObject> QDeclarativeItem::data() +QDeclarativeListProperty<QObject> QDeclarativeItemPrivate::data() { - return QDeclarativeListProperty<QObject>(this, 0, QDeclarativeItemPrivate::data_append); + return QDeclarativeListProperty<QObject>(q_func(), 0, QDeclarativeItemPrivate::data_append); } /*! \property QDeclarativeItem::childrenRect \brief The geometry of an item's children. - childrenRect provides an easy way to access the (collective) position and size of the item's children. + This property holds the (collective) position and size of the item's children. */ QRectF QDeclarativeItem::childrenRect() { Q_D(QDeclarativeItem); if (!d->_contents) { d->_contents = new QDeclarativeContents; - QDeclarative_setParent_noEvent(d->_contents, this); d->_contents->setItem(this); } return d->_contents->rectF(); @@ -1860,98 +1862,61 @@ QVariant QDeclarativeItem::inputMethodQuery(Qt::InputMethodQuery query) const /*! \internal */ -QDeclarativeAnchorLine QDeclarativeItem::left() const +QDeclarativeAnchorLine QDeclarativeItemPrivate::left() const { - Q_D(const QDeclarativeItem); - return d->anchorLines()->left; + return anchorLines()->left; } /*! \internal */ -QDeclarativeAnchorLine QDeclarativeItem::right() const +QDeclarativeAnchorLine QDeclarativeItemPrivate::right() const { - Q_D(const QDeclarativeItem); - return d->anchorLines()->right; + return anchorLines()->right; } /*! \internal */ -QDeclarativeAnchorLine QDeclarativeItem::horizontalCenter() const +QDeclarativeAnchorLine QDeclarativeItemPrivate::horizontalCenter() const { - Q_D(const QDeclarativeItem); - return d->anchorLines()->hCenter; + return anchorLines()->hCenter; } /*! \internal */ -QDeclarativeAnchorLine QDeclarativeItem::top() const +QDeclarativeAnchorLine QDeclarativeItemPrivate::top() const { - Q_D(const QDeclarativeItem); - return d->anchorLines()->top; + return anchorLines()->top; } /*! \internal */ -QDeclarativeAnchorLine QDeclarativeItem::bottom() const +QDeclarativeAnchorLine QDeclarativeItemPrivate::bottom() const { - Q_D(const QDeclarativeItem); - return d->anchorLines()->bottom; + return anchorLines()->bottom; } /*! \internal */ -QDeclarativeAnchorLine QDeclarativeItem::verticalCenter() const +QDeclarativeAnchorLine QDeclarativeItemPrivate::verticalCenter() const { - Q_D(const QDeclarativeItem); - return d->anchorLines()->vCenter; + return anchorLines()->vCenter; } /*! \internal */ -QDeclarativeAnchorLine QDeclarativeItem::baseline() const +QDeclarativeAnchorLine QDeclarativeItemPrivate::baseline() const { - Q_D(const QDeclarativeItem); - return d->anchorLines()->baseline; + return anchorLines()->baseline; } /*! - \property QDeclarativeItem::top - \internal -*/ - -/*! - \property QDeclarativeItem::bottom - \internal -*/ - -/*! - \property QDeclarativeItem::left - \internal -*/ - -/*! - \property QDeclarativeItem::right - \internal -*/ - -/*! - \property QDeclarativeItem::horizontalCenter - \internal -*/ - -/*! - \property QDeclarativeItem::verticalCenter - \internal -*/ - -/*! \qmlproperty AnchorLine Item::top \qmlproperty AnchorLine Item::bottom \qmlproperty AnchorLine Item::left @@ -2291,9 +2256,9 @@ void QDeclarativeItemPrivate::focusChanged(bool flag) } /*! \internal */ -QDeclarativeListProperty<QObject> QDeclarativeItem::resources() +QDeclarativeListProperty<QObject> QDeclarativeItemPrivate::resources() { - return QDeclarativeListProperty<QObject>(this, 0, QDeclarativeItemPrivate::resources_append, + return QDeclarativeListProperty<QObject>(q_func(), 0, QDeclarativeItemPrivate::resources_append, QDeclarativeItemPrivate::resources_count, QDeclarativeItemPrivate::resources_at); } @@ -2315,15 +2280,10 @@ QDeclarativeListProperty<QObject> QDeclarativeItem::resources() \sa {qmlstate}{States} */ -/*! - \property QDeclarativeItem::states - \internal -*/ /*! \internal */ -QDeclarativeListProperty<QDeclarativeState> QDeclarativeItem::states() +QDeclarativeListProperty<QDeclarativeState> QDeclarativeItemPrivate::states() { - Q_D(QDeclarativeItem); - return d->states()->statesProperty(); + return _states()->statesProperty(); } /*! @@ -2343,16 +2303,11 @@ QDeclarativeListProperty<QDeclarativeState> QDeclarativeItem::states() \sa {state-transitions}{Transitions} */ -/*! - \property QDeclarativeItem::transitions - \internal -*/ /*! \internal */ -QDeclarativeListProperty<QDeclarativeTransition> QDeclarativeItem::transitions() +QDeclarativeListProperty<QDeclarativeTransition> QDeclarativeItemPrivate::transitions() { - Q_D(QDeclarativeItem); - return d->states()->transitionsProperty(); + return _states()->transitionsProperty(); } /* @@ -2426,20 +2381,18 @@ QDeclarativeListProperty<QDeclarativeTransition> QDeclarativeItem::transitions() */ /*! \internal */ -QString QDeclarativeItem::state() const +QString QDeclarativeItemPrivate::state() const { - Q_D(const QDeclarativeItem); - if (!d->_stateGroup) + if (!_stateGroup) return QString(); else - return d->_stateGroup->state(); + return _stateGroup->state(); } /*! \internal */ -void QDeclarativeItem::setState(const QString &state) +void QDeclarativeItemPrivate::setState(const QString &state) { - Q_D(QDeclarativeItem); - d->states()->setState(state); + _states()->setState(state); } /*! @@ -2502,7 +2455,7 @@ void QDeclarativeItem::componentComplete() d->keyHandler->componentComplete(); } -QDeclarativeStateGroup *QDeclarativeItemPrivate::states() +QDeclarativeStateGroup *QDeclarativeItemPrivate::_states() { Q_Q(QDeclarativeItem); if (!_stateGroup) { @@ -2618,6 +2571,16 @@ QVariant QDeclarativeItem::itemChange(GraphicsItemChange change, } } break; + case ItemChildAddedChange: + if (d->_contents) + d->_contents->childAdded(qobject_cast<QDeclarativeItem*>( + value.value<QGraphicsItem*>())); + break; + case ItemChildRemovedChange: + if (d->_contents) + d->_contents->childRemoved(qobject_cast<QDeclarativeItem*>( + value.value<QGraphicsItem*>())); + break; default: break; } @@ -2723,29 +2686,48 @@ void QDeclarativeItem::setSmooth(bool smooth) update(); } +/*! + \internal + Return the width of the item +*/ qreal QDeclarativeItem::width() const { Q_D(const QDeclarativeItem); return d->width(); } +/*! + \internal + Set the width of the item +*/ void QDeclarativeItem::setWidth(qreal w) { Q_D(QDeclarativeItem); d->setWidth(w); } +/*! + \internal + Reset the width of the item +*/ void QDeclarativeItem::resetWidth() { Q_D(QDeclarativeItem); d->resetWidth(); } +/*! + \internal + Return the width of the item +*/ qreal QDeclarativeItemPrivate::width() const { return mWidth; } +/*! + \internal +*/ void QDeclarativeItemPrivate::setWidth(qreal w) { Q_Q(QDeclarativeItem); @@ -2765,7 +2747,10 @@ void QDeclarativeItemPrivate::setWidth(qreal w) QRectF(q->x(), q->y(), oldWidth, height())); } -void QDeclarativeItemPrivate ::resetWidth() +/*! + \internal +*/ +void QDeclarativeItemPrivate::resetWidth() { Q_Q(QDeclarativeItem); widthValid = false; @@ -2810,29 +2795,47 @@ bool QDeclarativeItem::widthValid() const return d->widthValid; } +/*! + \internal + Return the height of the item +*/ qreal QDeclarativeItem::height() const { Q_D(const QDeclarativeItem); return d->height(); } +/*! + \internal + Set the height of the item +*/ void QDeclarativeItem::setHeight(qreal h) { Q_D(QDeclarativeItem); d->setHeight(h); } +/*! + \internal + Reset the height of the item +*/ void QDeclarativeItem::resetHeight() { Q_D(QDeclarativeItem); d->resetHeight(); } +/*! + \internal +*/ qreal QDeclarativeItemPrivate::height() const { return mHeight; } +/*! + \internal +*/ void QDeclarativeItemPrivate::setHeight(qreal h) { Q_Q(QDeclarativeItem); @@ -2852,6 +2855,9 @@ void QDeclarativeItemPrivate::setHeight(qreal h) QRectF(q->x(), q->y(), width(), oldHeight)); } +/*! + \internal +*/ void QDeclarativeItemPrivate::resetHeight() { Q_Q(QDeclarativeItem); @@ -2956,7 +2962,6 @@ void QDeclarativeItem::setFocus(bool focus) } /*! - \reimp \internal */ void QDeclarativeItem::paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) @@ -2964,7 +2969,6 @@ void QDeclarativeItem::paint(QPainter *, const QStyleOptionGraphicsItem *, QWidg } /*! - \reimp \internal */ bool QDeclarativeItem::event(QEvent *ev) diff --git a/src/declarative/graphicsitems/qdeclarativeitem.h b/src/declarative/graphicsitems/qdeclarativeitem.h index da5a36e..3b05b09 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.h +++ b/src/declarative/graphicsitems/qdeclarativeitem.h @@ -70,20 +70,20 @@ class Q_DECLARATIVE_EXPORT QDeclarativeItem : public QGraphicsObject, public QDe Q_INTERFACES(QDeclarativeParserStatus) Q_PROPERTY(QDeclarativeItem * parent READ parentItem WRITE setParentItem NOTIFY parentChanged DESIGNABLE false FINAL) - Q_PROPERTY(QDeclarativeListProperty<QObject> data READ data DESIGNABLE false) - Q_PROPERTY(QDeclarativeListProperty<QObject> resources READ resources DESIGNABLE false) - Q_PROPERTY(QDeclarativeListProperty<QDeclarativeState> states READ states DESIGNABLE false) - Q_PROPERTY(QDeclarativeListProperty<QDeclarativeTransition> transitions READ transitions DESIGNABLE false) - Q_PROPERTY(QString state READ state WRITE setState NOTIFY stateChanged) + Q_PRIVATE_PROPERTY(QDeclarativeItem::d_func(), QDeclarativeListProperty<QObject> data READ data DESIGNABLE false) + Q_PRIVATE_PROPERTY(QDeclarativeItem::d_func(), QDeclarativeListProperty<QObject> resources READ resources DESIGNABLE false) + Q_PRIVATE_PROPERTY(QDeclarativeItem::d_func(), QDeclarativeListProperty<QDeclarativeState> states READ states DESIGNABLE false) + Q_PRIVATE_PROPERTY(QDeclarativeItem::d_func(), QDeclarativeListProperty<QDeclarativeTransition> transitions READ transitions DESIGNABLE false) + Q_PRIVATE_PROPERTY(QDeclarativeItem::d_func(), QString state READ state WRITE setState NOTIFY stateChanged) Q_PROPERTY(QRectF childrenRect READ childrenRect NOTIFY childrenRectChanged DESIGNABLE false FINAL) - Q_PROPERTY(QDeclarativeAnchors * anchors READ anchors DESIGNABLE false CONSTANT FINAL) - Q_PROPERTY(QDeclarativeAnchorLine left READ left CONSTANT FINAL) - Q_PROPERTY(QDeclarativeAnchorLine right READ right CONSTANT FINAL) - Q_PROPERTY(QDeclarativeAnchorLine horizontalCenter READ horizontalCenter CONSTANT FINAL) - Q_PROPERTY(QDeclarativeAnchorLine top READ top CONSTANT FINAL) - Q_PROPERTY(QDeclarativeAnchorLine bottom READ bottom CONSTANT FINAL) - Q_PROPERTY(QDeclarativeAnchorLine verticalCenter READ verticalCenter CONSTANT FINAL) - Q_PROPERTY(QDeclarativeAnchorLine baseline READ baseline CONSTANT FINAL) + Q_PRIVATE_PROPERTY(QDeclarativeItem::d_func(), QDeclarativeAnchors * anchors READ anchors DESIGNABLE false CONSTANT FINAL) + Q_PRIVATE_PROPERTY(QDeclarativeItem::d_func(), QDeclarativeAnchorLine left READ left CONSTANT FINAL) + Q_PRIVATE_PROPERTY(QDeclarativeItem::d_func(), QDeclarativeAnchorLine right READ right CONSTANT FINAL) + Q_PRIVATE_PROPERTY(QDeclarativeItem::d_func(), QDeclarativeAnchorLine horizontalCenter READ horizontalCenter CONSTANT FINAL) + Q_PRIVATE_PROPERTY(QDeclarativeItem::d_func(), QDeclarativeAnchorLine top READ top CONSTANT FINAL) + Q_PRIVATE_PROPERTY(QDeclarativeItem::d_func(), QDeclarativeAnchorLine bottom READ bottom CONSTANT FINAL) + Q_PRIVATE_PROPERTY(QDeclarativeItem::d_func(), QDeclarativeAnchorLine verticalCenter READ verticalCenter CONSTANT FINAL) + Q_PRIVATE_PROPERTY(QDeclarativeItem::d_func(), QDeclarativeAnchorLine baseline READ baseline CONSTANT FINAL) Q_PROPERTY(qreal baselineOffset READ baselineOffset WRITE setBaselineOffset NOTIFY baselineOffsetChanged) Q_PROPERTY(bool clip READ clip WRITE setClip NOTIFY clipChanged) // ### move to QGI/QGO, NOTIFY Q_PROPERTY(bool focus READ hasFocus WRITE setFocus NOTIFY focusChanged FINAL) @@ -107,21 +107,11 @@ public: QDeclarativeItem *parentItem() const; void setParentItem(QDeclarativeItem *parent); - QDeclarativeListProperty<QObject> data(); - QDeclarativeListProperty<QObject> resources(); - - QDeclarativeAnchors *anchors(); QRectF childrenRect(); bool clip() const; void setClip(bool); - QDeclarativeListProperty<QDeclarativeState> states(); - QDeclarativeListProperty<QDeclarativeTransition> transitions(); - - QString state() const; - void setState(const QString &); - qreal baselineOffset() const; void setBaselineOffset(qreal); @@ -159,14 +149,6 @@ public: Q_INVOKABLE QScriptValue mapToItem(const QScriptValue &item, qreal x, qreal y) const; Q_INVOKABLE void forceFocus(); - QDeclarativeAnchorLine left() const; - QDeclarativeAnchorLine right() const; - QDeclarativeAnchorLine horizontalCenter() const; - QDeclarativeAnchorLine top() const; - QDeclarativeAnchorLine bottom() const; - QDeclarativeAnchorLine verticalCenter() const; - QDeclarativeAnchorLine baseline() const; - Q_SIGNALS: void childrenChanged(); void childrenRectChanged(const QRectF &); diff --git a/src/declarative/graphicsitems/qdeclarativeitem_p.h b/src/declarative/graphicsitems/qdeclarativeitem_p.h index 3f5bf1a..516d6d0 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem_p.h +++ b/src/declarative/graphicsitems/qdeclarativeitem_p.h @@ -79,24 +79,32 @@ class QNetworkReply; class QDeclarativeItemKeyFilter; //### merge into private? -class QDeclarativeContents : public QObject +class QDeclarativeContents : public QObject, public QDeclarativeItemChangeListener { Q_OBJECT public: QDeclarativeContents(); + ~QDeclarativeContents(); QRectF rectF() const; void setItem(QDeclarativeItem *item); -public Q_SLOTS: - void calcHeight(); - void calcWidth(); + void childRemoved(QDeclarativeItem *item); + void childAdded(QDeclarativeItem *item); Q_SIGNALS: void rectChanged(QRectF); +protected: + void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry); + void itemDestroyed(QDeclarativeItem *item); + //void itemVisibilityChanged(QDeclarativeItem *item) + private: + void calcHeight(QDeclarativeItem *changed = 0); + void calcWidth(QDeclarativeItem *changed = 0); + QDeclarativeItem *m_item; qreal m_x; qreal m_y; @@ -150,6 +158,22 @@ public: void setHeight(qreal); void resetHeight(); + QDeclarativeListProperty<QObject> data(); + QDeclarativeListProperty<QObject> resources(); + + QDeclarativeListProperty<QDeclarativeState> states(); + QDeclarativeListProperty<QDeclarativeTransition> transitions(); + + QString state() const; + void setState(const QString &); + + QDeclarativeAnchorLine left() const; + QDeclarativeAnchorLine right() const; + QDeclarativeAnchorLine horizontalCenter() const; + QDeclarativeAnchorLine top() const; + QDeclarativeAnchorLine bottom() const; + QDeclarativeAnchorLine verticalCenter() const; + QDeclarativeAnchorLine baseline() const; // data property static void data_append(QDeclarativeListProperty<QObject> *, QObject *); @@ -165,6 +189,11 @@ public: static QGraphicsTransform *transform_at(QDeclarativeListProperty<QGraphicsTransform> *list, int); static void transform_clear(QDeclarativeListProperty<QGraphicsTransform> *list); + static QDeclarativeItemPrivate* get(QDeclarativeItem *item) + { + return item->d_func(); + } + // Accelerated property accessors QDeclarativeNotifier parentNotifier; static void parentProperty(QObject *o, void *rv, QDeclarativeNotifierEndpoint *e); @@ -224,7 +253,7 @@ public: void removeItemChangeListener(QDeclarativeItemChangeListener *, ChangeTypes types); QPODVector<ChangeListener,4> changeListeners; - QDeclarativeStateGroup *states(); + QDeclarativeStateGroup *_states(); QDeclarativeStateGroup *_stateGroup; QDeclarativeItem::TransformOrigin origin:4; diff --git a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp index 2945b6c..7c55009 100644 --- a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp @@ -143,7 +143,9 @@ void QDeclarativeItemModule::defineModule() qmlRegisterType<QAction>(); qmlRegisterType<QDeclarativePen>(); qmlRegisterType<QDeclarativeFlickableVisibleArea>(); +#ifndef QT_NO_GRAPHICSEFFECT qmlRegisterType<QGraphicsEffect>(); +#endif qmlRegisterUncreatableType<QDeclarativeKeyNavigationAttached>("Qt",4,7,"KeyNavigation",QDeclarativeKeyNavigationAttached::tr("KeyNavigation is only available via attached properties")); qmlRegisterUncreatableType<QDeclarativeKeysAttached>("Qt",4,7,"Keys",QDeclarativeKeysAttached::tr("Keys is only available via attached properties")); diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index c88dab2..416e0a8 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -161,9 +161,9 @@ public: , highlightResizeSpeed(400), highlightResizeDuration(-1), highlightRange(QDeclarativeListView::NoHighlightRange) , snapMode(QDeclarativeListView::NoSnap), overshootDist(0.0) , footerComponent(0), footer(0), headerComponent(0), header(0) - , bufferMode(NoBuffer) + , bufferMode(BufferBefore | BufferAfter) , ownModel(false), wrap(false), autoHighlight(true), haveHighlightRange(false) - , correctFlick(true), inFlickCorrection(false), lazyRelease(false) + , correctFlick(false), inFlickCorrection(false), lazyRelease(false) , deferredRelease(false), layoutScheduled(false), minExtentDirty(true), maxExtentDirty(true) {} @@ -573,9 +573,11 @@ FxListItem *QDeclarativeListViewPrivate::createItem(int modelIndex) if (model->completePending()) { // complete listItem->item->setZValue(1); + listItem->item->setParentItem(q->viewport()); model->completeItem(); + } else { + listItem->item->setParentItem(q->viewport()); } - listItem->item->setParentItem(q->viewport()); QDeclarativeItemPrivate *itemPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(item)); itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); if (sectionCriteria && sectionCriteria->delegate()) { @@ -648,7 +650,7 @@ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer) FxListItem *item = 0; int pos = itemEnd + 1; while (modelIndex < model->count() && pos <= fillTo) { - //qDebug() << "refill: append item" << modelIndex << "pos" << pos; +// qDebug() << "refill: append item" << modelIndex << "pos" << pos; if (!(item = createItem(modelIndex))) break; item->setPosition(pos); @@ -659,8 +661,8 @@ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer) if (doBuffer) // never buffer more than one item per frame break; } - while (visibleIndex > 0 && visibleIndex <= model->count() && visiblePos > fillFrom) { - //qDebug() << "refill: prepend item" << visibleIndex-1 << "current top pos" << visiblePos; + while (visibleIndex > 0 && visibleIndex <= model->count() && visiblePos-1 >= fillFrom) { +// qDebug() << "refill: prepend item" << visibleIndex-1 << "current top pos" << visiblePos; if (!(item = createItem(visibleIndex-1))) break; --visibleIndex; @@ -676,7 +678,7 @@ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer) while (visibleItems.count() > 1 && (item = visibleItems.first()) && item->endPosition() < bufferFrom) { if (item->attached->delayRemove()) break; - //qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endPosition(); +// qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endPosition(); if (item->index != -1) visibleIndex++; visibleItems.removeFirst(); @@ -686,7 +688,7 @@ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer) while (visibleItems.count() > 1 && (item = visibleItems.last()) && item->position() > bufferTo) { if (item->attached->delayRemove()) break; - //qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1; +// qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1 << item->position(); visibleItems.removeLast(); releaseItem(item); changed = true; @@ -1164,6 +1166,7 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m moveReason = Mouse; if ((!haveHighlightRange || highlightRange != QDeclarativeListView::StrictlyEnforceRange) && snapMode == QDeclarativeListView::NoSnap) { + correctFlick = true; QDeclarativeFlickablePrivate::flick(data, minExtent, maxExtent, vSize, fixupCallback, velocity); return; } @@ -1230,10 +1233,13 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m qreal adjDist = -data.flickTarget + data.move.value(); if (qAbs(adjDist) > qAbs(dist)) { // Prevent painfully slow flicking - adjust velocity to suit flickDeceleration - v2 = accel * 2.0f * qAbs(dist); - v = qSqrt(v2); - if (dist > 0) - v = -v; + qreal adjv2 = accel * 2.0f * qAbs(adjDist); + if (adjv2 > v2) { + v2 = adjv2; + v = qSqrt(v2); + if (dist > 0) + v = -v; + } } dist = adjDist; accel = v2 / (2.0f * qAbs(dist)); @@ -1310,6 +1316,9 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m In this case ListModel is a handy way for us to test our UI. In practice the model would be implemented in C++, or perhaps via a SQL data source. + Delegates are instantiated as needed and may be destroyed at any time. + State should \e never be stored in a delegate. + \bold Note that views do not enable \e clip automatically. If the view is not clipped by another item or the screen, it will be necessary to set \e {clip: true} in order to have the out of view items clipped @@ -1388,7 +1397,7 @@ QDeclarativeListView::~QDeclarativeListView() id: wrapper ListView.onRemove: SequentialAnimation { PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: true } - NumberAnimation { target: wrapper; property: "scale"; to: 0; duration: 250; easing.type: "InOutQuad" } + NumberAnimation { target: wrapper; property: "scale"; to: 0; duration: 250; easing.type: Easing.InOutQuad } PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: false } } } @@ -1459,6 +1468,7 @@ void QDeclarativeListView::setModel(const QVariant &model) dataModel->setModel(model); } if (d->model) { + d->bufferMode = QDeclarativeListViewPrivate::BufferBefore | QDeclarativeListViewPrivate::BufferAfter; if (isComponentComplete()) { refill(); if (d->currentIndex >= d->model->count() || d->currentIndex < 0) { @@ -1480,12 +1490,17 @@ void QDeclarativeListView::setModel(const QVariant &model) } /*! - \qmlproperty component ListView::delegate + \qmlproperty Component ListView::delegate The delegate provides a template defining each item instantiated by the view. The index is exposed as an accessible \c index property. Properties of the model are also available depending upon the type of \l {qmlmodels}{Data Model}. + The number of elements in the delegate has a direct effect on the + flicking performance of the view. If at all possible, place functionality + that is not needed for the normal display of the delegate in a \l Loader which + can load additional elements when needed. + Note that the ListView will layout the items based on the size of the root item in the delegate. @@ -1595,7 +1610,7 @@ int QDeclarativeListView::count() const } /*! - \qmlproperty component ListView::highlight + \qmlproperty Component ListView::highlight This property holds the component to use as the highlight. An instance of the highlight component will be created for each list. @@ -1681,17 +1696,17 @@ void QDeclarativeListView::setHighlightFollowsCurrentItem(bool autoHighlight) highlight range. Furthermore, the behaviour of the current item index will occur whether or not a highlight exists. - If highlightRangeMode is set to \e ApplyRange the view will + If highlightRangeMode is set to \e ListView.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 list or due to a mouse interaction. - If highlightRangeMode is set to \e StrictlyEnforceRange the highlight will never + If highlightRangeMode is set to \e ListView.StrictlyEnforceRange the highlight will never move outside of the range. This means that the current item will change if a keyboard or mouse action would cause the highlight to move outside of the range. - The default value is \e NoHighlightRange. + The default value is \e ListView.NoHighlightRange. Note that a valid range requires preferredHighlightEnd to be greater than or equal to preferredHighlightBegin. @@ -1771,9 +1786,9 @@ void QDeclarativeListView::setSpacing(qreal spacing) Possible values are \c Vertical (default) and \c Horizontal. - Vertical Example: + ListView.Vertical Example: \image trivialListView.png - Horizontal Example: + ListView.Horizontal Example: \image ListViewHorizontal.png */ QDeclarativeListView::Orientation QDeclarativeListView::orientation() const @@ -1826,11 +1841,22 @@ void QDeclarativeListView::setWrapEnabled(bool wrap) /*! \qmlproperty int ListView::cacheBuffer - This property holds the number of off-screen pixels to cache. - - This property determines the number of pixels above the top of the list - and below the bottom of the list to cache. Setting this value can make - scrolling the list smoother at the expense of additional memory usage. + This property determines whether delegates are retained outside the + visible area of the view. + + If non-zero the view will keep as many delegates + instantiated as will fit within the buffer specified. For example, + if in a vertical view the delegate is 20 pixels high and \c cacheBuffer is + set to 40, then up to 2 delegates above and 2 delegates below the visible + area may be retained. + + Note that cacheBuffer is not a pixel buffer - it only maintains additional + instantiated delegates. + + Setting this value can make scrolling the list smoother at the expense + of additional memory usage. It is not a substitute for creating efficient + delegates; the fewer elements in a delegate, the faster a view may be + scrolled. */ int QDeclarativeListView::cacheBuffer() const { @@ -1987,17 +2013,17 @@ void QDeclarativeListView::setHighlightResizeDuration(int duration) The allowed values are: \list - \o NoSnap (default) - the view will stop anywhere within the visible area. - \o SnapToItem - the view will settle with an item aligned with the start of + \o ListView.NoSnap (default) - the view will stop anywhere within the visible area. + \o ListView.SnapToItem - the view will settle with an item aligned with the start of the view. - \o SnapOneItem - the view will settle no more than one item away from the first + \o ListView.SnapOneItem - the view will settle no more than one item away from the first visible item at the time the mouse button is released. This mode is particularly useful for moving one page at a time. \endlist snapMode does not affect the currentIndex. To update the currentIndex as the list is moved set \e highlightRangeMode - to \e StrictlyEnforceRange. + to \e ListView.StrictlyEnforceRange. \sa highlightRangeMode */ diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp index bdd2c87..7edd53c 100644 --- a/src/declarative/graphicsitems/qdeclarativeloader.cpp +++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp @@ -49,7 +49,6 @@ QT_BEGIN_NAMESPACE QDeclarativeLoaderPrivate::QDeclarativeLoaderPrivate() : item(0), component(0), ownComponent(false) - , resizeMode(QDeclarativeLoader::SizeLoaderToItem) { } @@ -59,9 +58,8 @@ QDeclarativeLoaderPrivate::~QDeclarativeLoaderPrivate() void QDeclarativeLoaderPrivate::itemGeometryChanged(QDeclarativeItem *resizeItem, const QRectF &newGeometry, const QRectF &oldGeometry) { - if (resizeItem == item && resizeMode == QDeclarativeLoader::SizeLoaderToItem) { - _q_updateSize(); - } + if (resizeItem == item) + _q_updateSize(false); QDeclarativeItemChangeListener::itemGeometryChanged(resizeItem, newGeometry, oldGeometry); } @@ -76,11 +74,9 @@ void QDeclarativeLoaderPrivate::clear() if (item) { if (QDeclarativeItem *qmlItem = qobject_cast<QDeclarativeItem*>(item)) { - if (resizeMode == QDeclarativeLoader::SizeLoaderToItem) { - QDeclarativeItemPrivate *p = + QDeclarativeItemPrivate *p = static_cast<QDeclarativeItemPrivate *>(QGraphicsItemPrivate::get(qmlItem)); - p->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry); - } + p->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry); } // We can't delete immediately because our item may have triggered @@ -96,16 +92,12 @@ void QDeclarativeLoaderPrivate::initResize() { Q_Q(QDeclarativeLoader); if (QDeclarativeItem *qmlItem = qobject_cast<QDeclarativeItem*>(item)) { - if (resizeMode == QDeclarativeLoader::SizeLoaderToItem) { - QDeclarativeItemPrivate *p = + QDeclarativeItemPrivate *p = static_cast<QDeclarativeItemPrivate *>(QGraphicsItemPrivate::get(qmlItem)); - p->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); - } + p->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); } else if (item && item->isWidget()) { QGraphicsWidget *widget = static_cast<QGraphicsWidget*>(item); - if (resizeMode == QDeclarativeLoader::SizeLoaderToItem) { - widget->installEventFilter(q); - } + widget->installEventFilter(q); } _q_updateSize(); } @@ -337,10 +329,10 @@ void QDeclarativeLoaderPrivate::_q_sourceLoaded() This property holds the status of QML loading. It can be one of: \list - \o Null - no QML source has been set - \o Ready - the QML source has been loaded - \o Loading - the QML source is currently being loaded - \o Error - an error occurred while loading the QML source + \o Loader.Null - no QML source has been set + \o Loader.Ready - the QML source has been loaded + \o Loader.Loading - the QML source is currently being loaded + \o Loader.Error - an error occurred while loading the QML source \endlist Note that a change in the status property does not cause anything to happen @@ -390,83 +382,30 @@ qreal QDeclarativeLoader::progress() const return 0.0; } -/*! - \qmlproperty enumeration Loader::resizeMode - - This property determines how the Loader or item are resized: - \list - \o NoResize - no item will be resized - \o SizeLoaderToItem - the Loader will be sized to the size of the item, unless the size of the Loader has been otherwise specified. - \o SizeItemToLoader - the item will be sized to the size of the Loader. - \endlist - - Note that changing from SizeItemToLoader to SizeLoaderToItem - after the component is loaded will not return the item or Loader - to it's original size. This is due to the item size being adjusted - to the Loader size, thereby losing the original size of the item. - Future changes to the item's size will affect the loader, however. - - The default resizeMode is SizeLoaderToItem. -*/ -QDeclarativeLoader::ResizeMode QDeclarativeLoader::resizeMode() const -{ - Q_D(const QDeclarativeLoader); - return d->resizeMode; -} - -void QDeclarativeLoader::setResizeMode(ResizeMode mode) -{ - Q_D(QDeclarativeLoader); - if (mode == d->resizeMode) - return; - - if (QDeclarativeItem *qmlItem = qobject_cast<QDeclarativeItem*>(d->item)) { - if (d->resizeMode == SizeLoaderToItem) { - QDeclarativeItemPrivate *p = - static_cast<QDeclarativeItemPrivate *>(QGraphicsItemPrivate::get(qmlItem)); - p->removeItemChangeListener(d, QDeclarativeItemPrivate::Geometry); - } - } else if (d->item && d->item->isWidget()) { - if (d->resizeMode == SizeLoaderToItem) - d->item->removeEventFilter(this); - } - d->resizeMode = mode; - emit resizeModeChanged(); - d->initResize(); -} - -void QDeclarativeLoaderPrivate::_q_updateSize() +void QDeclarativeLoaderPrivate::_q_updateSize(bool loaderGeometryChanged) { Q_Q(QDeclarativeLoader); if (!item) return; if (QDeclarativeItem *qmlItem = qobject_cast<QDeclarativeItem*>(item)) { - if (resizeMode == QDeclarativeLoader::SizeLoaderToItem) { - q->setWidth(qmlItem->width()); - q->setHeight(qmlItem->height()); - } else if (resizeMode == QDeclarativeLoader::SizeItemToLoader) { + q->setImplicitWidth(qmlItem->width()); + if (loaderGeometryChanged && q->widthValid()) qmlItem->setWidth(q->width()); + q->setImplicitHeight(qmlItem->height()); + if (loaderGeometryChanged && q->heightValid()) qmlItem->setHeight(q->height()); - } } else if (item && item->isWidget()) { QGraphicsWidget *widget = static_cast<QGraphicsWidget*>(item); - if (resizeMode == QDeclarativeLoader::SizeLoaderToItem) { - QSizeF newSize = widget->size(); - if (newSize.isValid()) { - q->setWidth(newSize.width()); - q->setHeight(newSize.height()); - } - } else if (resizeMode == QDeclarativeLoader::SizeItemToLoader) { - QSizeF oldSize = widget->size(); - QSizeF newSize = oldSize; - if (q->heightValid()) - newSize.setHeight(q->height()); - if (q->widthValid()) - newSize.setWidth(q->width()); - if (oldSize != newSize) - widget->resize(newSize); - } + QSizeF widgetSize = widget->size(); + q->setImplicitWidth(widgetSize.width()); + if (loaderGeometryChanged && q->widthValid()) + widgetSize.setWidth(q->width()); + q->setImplicitHeight(widgetSize.height()); + if (loaderGeometryChanged && q->heightValid()) + widgetSize.setHeight(q->height()); + if (widget->size() != widgetSize) + widget->resize(widgetSize); } } @@ -484,9 +423,7 @@ void QDeclarativeLoader::geometryChanged(const QRectF &newGeometry, const QRectF { Q_D(QDeclarativeLoader); if (newGeometry != oldGeometry) { - if (d->resizeMode == SizeItemToLoader) { - d->_q_updateSize(); - } + d->_q_updateSize(); } QDeclarativeItem::geometryChanged(newGeometry, oldGeometry); } @@ -496,10 +433,8 @@ QVariant QDeclarativeLoader::itemChange(GraphicsItemChange change, const QVarian Q_D(QDeclarativeLoader); if (change == ItemSceneHasChanged) { if (d->item && d->item->isWidget()) { - if (d->resizeMode == SizeLoaderToItem) { - d->item->removeEventFilter(this); - d->item->installEventFilter(this); - } + d->item->removeEventFilter(this); + d->item->installEventFilter(this); } } return QDeclarativeItem::itemChange(change, value); @@ -509,9 +444,8 @@ bool QDeclarativeLoader::eventFilter(QObject *watched, QEvent *e) { Q_D(QDeclarativeLoader); if (watched == d->item && e->type() == QEvent::GraphicsSceneResize) { - if (d->item && d->item->isWidget() && d->resizeMode == SizeLoaderToItem) { - d->_q_updateSize(); - } + if (d->item && d->item->isWidget()) + d->_q_updateSize(false); } return QDeclarativeItem::eventFilter(watched, e); } diff --git a/src/declarative/graphicsitems/qdeclarativeloader_p.h b/src/declarative/graphicsitems/qdeclarativeloader_p.h index e9fd8e9..49dfa11 100644 --- a/src/declarative/graphicsitems/qdeclarativeloader_p.h +++ b/src/declarative/graphicsitems/qdeclarativeloader_p.h @@ -55,11 +55,9 @@ class Q_DECLARATIVE_EXPORT QDeclarativeLoader : public QDeclarativeItem { Q_OBJECT Q_ENUMS(Status) - Q_ENUMS(ResizeMode) Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) Q_PROPERTY(QDeclarativeComponent *sourceComponent READ sourceComponent WRITE setSourceComponent RESET resetSourceComponent NOTIFY sourceChanged) - Q_PROPERTY(ResizeMode resizeMode READ resizeMode WRITE setResizeMode NOTIFY resizeModeChanged) Q_PROPERTY(QGraphicsObject *item READ item NOTIFY itemChanged) Q_PROPERTY(Status status READ status NOTIFY statusChanged) Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged) @@ -79,10 +77,6 @@ public: Status status() const; qreal progress() const; - enum ResizeMode { NoResize, SizeLoaderToItem, SizeItemToLoader }; - ResizeMode resizeMode() const; - void setResizeMode(ResizeMode mode); - QGraphicsObject *item() const; Q_SIGNALS: @@ -90,7 +84,6 @@ Q_SIGNALS: void sourceChanged(); void statusChanged(); void progressChanged(); - void resizeModeChanged(); protected: void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); diff --git a/src/declarative/graphicsitems/qdeclarativeloader_p_p.h b/src/declarative/graphicsitems/qdeclarativeloader_p_p.h index 49069f9..0d4c4d0 100644 --- a/src/declarative/graphicsitems/qdeclarativeloader_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativeloader_p_p.h @@ -77,10 +77,9 @@ public: QGraphicsObject *item; QDeclarativeComponent *component; bool ownComponent : 1; - QDeclarativeLoader::ResizeMode resizeMode; void _q_sourceLoaded(); - void _q_updateSize(); + void _q_updateSize(bool loaderGeometryChanged = true); }; QT_END_NAMESPACE diff --git a/src/declarative/graphicsitems/qdeclarativemousearea.cpp b/src/declarative/graphicsitems/qdeclarativemousearea.cpp index 126d041..1947c00 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea.cpp +++ b/src/declarative/graphicsitems/qdeclarativemousearea.cpp @@ -197,8 +197,8 @@ QDeclarativeMouseAreaPrivate::~QDeclarativeMouseAreaPrivate() This handler is called when the mouse enters the mouse area. By default the onEntered handler is only called while a button is - pressed. Setting hoverEnabled to true enables handling of - onExited when no mouse button is pressed. + pressed. Setting hoverEnabled to true enables handling of + onEntered when no mouse button is pressed. \sa hoverEnabled */ @@ -209,7 +209,7 @@ QDeclarativeMouseAreaPrivate::~QDeclarativeMouseAreaPrivate() This handler is called when the mouse exists the mouse area. By default the onExited handler is only called while a button is - pressed. Setting hoverEnabled to true enables handling of + pressed. Setting hoverEnabled to true enables handling of onExited when no mouse button is pressed. \sa hoverEnabled @@ -288,12 +288,21 @@ QDeclarativeMouseAreaPrivate::~QDeclarativeMouseAreaPrivate() */ /*! + \qmlsignal MouseArea::onCanceled() + + This handler is called when the mouse events are canceled, either because the event was not accepted or + another element stole the mouse event handling. This signal is for advanced users, it's useful in case there + is more than one mouse areas handling input, or when there is a mouse area inside a flickable. In the latter + case, if you do some logic on pressed and then start dragging, the flickable will steal the mouse handling + from the mouse area. In these cases, to reset the logic when there is no mouse handling anymore, you should + use onCanceled, in addition to onReleased. +*/ + +/*! \internal \class QDeclarativeMouseArea \brief The QDeclarativeMouseArea class provides a simple mouse handling abstraction for use within Qml. - \ingroup group_coreitems - 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. @@ -365,7 +374,7 @@ void QDeclarativeMouseArea::setEnabled(bool a) \list \o Qt.LeftButton \o Qt.RightButton - \o Qt.MidButton + \o Qt.MiddleButton \endlist The code below displays "right" when the right mouse buttons is pressed: @@ -564,10 +573,12 @@ bool QDeclarativeMouseArea::sceneEvent(QEvent *event) // state d->pressed = false; setKeepMouseGrab(false); - QDeclarativeMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, false); - emit released(&me); + emit canceled(); emit pressedChanged(); - setHovered(false); + if (d->hovered) { + d->hovered = false; + emit hoveredChanged(); + } } } return rv; @@ -599,6 +610,23 @@ void QDeclarativeMouseArea::geometryChanged(const QRectF &newGeometry, d->lastPos = mapFromScene(d->lastScenePos); } +/*! \internal */ +QVariant QDeclarativeMouseArea::itemChange(GraphicsItemChange change, + const QVariant &value) +{ + Q_D(QDeclarativeMouseArea); + switch (change) { + case ItemVisibleHasChanged: + if (acceptHoverEvents() && d->hovered != (isVisible() && isUnderMouse())) + setHovered(!d->hovered); + break; + default: + break; + } + + return QDeclarativeItem::itemChange(change, value); +} + /*! \qmlproperty bool MouseArea::hoverEnabled This property holds whether hover events are handled. @@ -609,6 +637,22 @@ void QDeclarativeMouseArea::geometryChanged(const QRectF &newGeometry, This property affects the containsMouse property and the onEntered, onExited and onPositionChanged signals. */ +bool QDeclarativeMouseArea::hoverEnabled() const +{ + return acceptHoverEvents(); +} + +void QDeclarativeMouseArea::setHoverEnabled(bool h) +{ + Q_D(QDeclarativeMouseArea); + if (h == acceptHoverEvents()) + return; + + setAcceptHoverEvents(h); + emit hoverEnabledChanged(); + if (d->hovered != isUnderMouse()) + setHovered(!d->hovered); +} /*! \qmlproperty bool MouseArea::containsMouse @@ -651,7 +695,7 @@ void QDeclarativeMouseArea::setHovered(bool h) \list \o Qt.LeftButton \o Qt.RightButton - \o Qt.MidButton + \o Qt.MiddleButton \endlist To accept more than one button the flags can be combined with the @@ -715,7 +759,7 @@ QDeclarativeDrag *QDeclarativeMouseArea::drag() /*! \qmlproperty Item MouseArea::drag.target \qmlproperty bool MouseArea::drag.active - \qmlproperty Axis MouseArea::drag.axis + \qmlproperty enumeration MouseArea::drag.axis \qmlproperty real MouseArea::drag.minimumX \qmlproperty real MouseArea::drag.maximumX \qmlproperty real MouseArea::drag.minimumY @@ -726,7 +770,7 @@ QDeclarativeDrag *QDeclarativeMouseArea::drag() \list \i \c target specifies the item to drag. \i \c active specifies if the target item is being currently dragged. - \i \c axis specifies whether dragging can be done horizontally (XAxis), vertically (YAxis), or both (XandYAxis) + \i \c axis specifies whether dragging can be done horizontally (Drag.XAxis), vertically (Drag.YAxis), or both (Drag.XandYAxis) \i the minimum and maximum properties limit how far the target can be dragged along the corresponding axes. \endlist diff --git a/src/declarative/graphicsitems/qdeclarativemousearea_p.h b/src/declarative/graphicsitems/qdeclarativemousearea_p.h index 4f7df62..df77ac6 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea_p.h +++ b/src/declarative/graphicsitems/qdeclarativemousearea_p.h @@ -121,7 +121,7 @@ class Q_DECLARATIVE_EXPORT QDeclarativeMouseArea : public QDeclarativeItem Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged) Q_PROPERTY(Qt::MouseButtons pressedButtons READ pressedButtons NOTIFY pressedChanged) Q_PROPERTY(Qt::MouseButtons acceptedButtons READ acceptedButtons WRITE setAcceptedButtons NOTIFY acceptedButtonsChanged) - Q_PROPERTY(bool hoverEnabled READ acceptHoverEvents WRITE setAcceptHoverEvents) + Q_PROPERTY(bool hoverEnabled READ hoverEnabled WRITE setHoverEnabled NOTIFY hoverEnabledChanged) Q_PROPERTY(QDeclarativeDrag *drag READ drag CONSTANT) //### add flicking to QDeclarativeDrag or add a QDeclarativeFlick ??? public: @@ -142,6 +142,9 @@ public: Qt::MouseButtons acceptedButtons() const; void setAcceptedButtons(Qt::MouseButtons buttons); + bool hoverEnabled() const; + void setHoverEnabled(bool h); + QDeclarativeDrag *drag(); Q_SIGNALS: @@ -149,6 +152,7 @@ Q_SIGNALS: void pressedChanged(); void enabledChanged(); void acceptedButtonsChanged(); + void hoverEnabledChanged(); void positionChanged(QDeclarativeMouseEvent *mouse); void mousePositionChanged(QDeclarativeMouseEvent *mouse); @@ -159,6 +163,7 @@ Q_SIGNALS: void doubleClicked(QDeclarativeMouseEvent *mouse); void entered(); void exited(); + void canceled(); protected: void setHovered(bool); @@ -176,6 +181,7 @@ protected: virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); + virtual QVariant itemChange(GraphicsItemChange change, const QVariant& value); private: void handlePress(); diff --git a/src/declarative/graphicsitems/qdeclarativepainteditem.cpp b/src/declarative/graphicsitems/qdeclarativepainteditem.cpp index f52636f..c4f0b86 100644 --- a/src/declarative/graphicsitems/qdeclarativepainteditem.cpp +++ b/src/declarative/graphicsitems/qdeclarativepainteditem.cpp @@ -59,8 +59,8 @@ QT_BEGIN_NAMESPACE \brief The QDeclarativePaintedItem class is an abstract base class for QDeclarativeView items that want cached painting. \internal - This is a convenience class for implementing items that paint their contents - using a QPainter. The contents of the item are cached behind the scenes. + This is a convenience class for implementing items that cache their painting. + The contents of the item are cached behind the scenes. The dirtyCache() function should be called if the contents change to ensure the cache is refreshed the next time painting occurs. @@ -184,7 +184,6 @@ void QDeclarativePaintedItem::setContentsScale(qreal scale) QDeclarativePaintedItem::QDeclarativePaintedItem(QDeclarativeItem *parent) : QDeclarativeItem(*(new QDeclarativePaintedItemPrivate), parent) { - init(); } /*! @@ -195,7 +194,6 @@ QDeclarativePaintedItem::QDeclarativePaintedItem(QDeclarativeItem *parent) QDeclarativePaintedItem::QDeclarativePaintedItem(QDeclarativePaintedItemPrivate &dd, QDeclarativeItem *parent) : QDeclarativeItem(dd, parent) { - init(); } /*! @@ -206,14 +204,23 @@ QDeclarativePaintedItem::~QDeclarativePaintedItem() clearCache(); } -/*! - \internal -*/ -void QDeclarativePaintedItem::init() +void QDeclarativePaintedItem::geometryChanged(const QRectF &newGeometry, + const QRectF &oldGeometry) { - connect(this,SIGNAL(widthChanged()),this,SLOT(clearCache())); - connect(this,SIGNAL(heightChanged()),this,SLOT(clearCache())); - connect(this,SIGNAL(visibleChanged()),this,SLOT(clearCache())); + if (newGeometry.width() != oldGeometry.width() || + newGeometry.height() != oldGeometry.height()) + clearCache(); + + QDeclarativeItem::geometryChanged(newGeometry, oldGeometry); +} + +QVariant QDeclarativePaintedItem::itemChange(GraphicsItemChange change, + const QVariant &value) +{ + if (change == ItemVisibleHasChanged) + clearCache(); + + return QDeclarativeItem::itemChange(change, value); } void QDeclarativePaintedItem::setCacheFrozen(bool frozen) @@ -226,7 +233,7 @@ void QDeclarativePaintedItem::setCacheFrozen(bool frozen) } /*! - \reimp + \internal */ void QDeclarativePaintedItem::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) { diff --git a/src/declarative/graphicsitems/qdeclarativepainteditem_p.h b/src/declarative/graphicsitems/qdeclarativepainteditem_p.h index cc616af..8d08ba2 100644 --- a/src/declarative/graphicsitems/qdeclarativepainteditem_p.h +++ b/src/declarative/graphicsitems/qdeclarativepainteditem_p.h @@ -87,6 +87,10 @@ protected: QDeclarativePaintedItem(QDeclarativePaintedItemPrivate &dd, QDeclarativeItem *parent); virtual void drawContents(QPainter *p, const QRect &) = 0; + virtual void geometryChanged(const QRectF &newGeometry, + const QRectF &oldGeometry); + virtual QVariant itemChange(GraphicsItemChange change, + const QVariant &value); void setCacheFrozen(bool); @@ -100,7 +104,6 @@ protected Q_SLOTS: void clearCache(); private: - void init(); Q_DISABLE_COPY(QDeclarativePaintedItem) Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QDeclarativePaintedItem) }; diff --git a/src/declarative/graphicsitems/qdeclarativepath.cpp b/src/declarative/graphicsitems/qdeclarativepath.cpp index e2042fc..4d8b619 100644 --- a/src/declarative/graphicsitems/qdeclarativepath.cpp +++ b/src/declarative/graphicsitems/qdeclarativepath.cpp @@ -63,7 +63,6 @@ QT_BEGIN_NAMESPACE /*! \internal \class QDeclarativePathElement - \ingroup group_utility */ /*! @@ -86,7 +85,6 @@ QT_BEGIN_NAMESPACE /*! \internal \class QDeclarativePath - \ingroup group_utility \brief The QDeclarativePath class defines a path. \sa QDeclarativePathView */ @@ -117,6 +115,7 @@ void QDeclarativePath::setStartX(qreal x) return; d->startX = x; emit startXChanged(); + processPath(); } qreal QDeclarativePath::startY() const @@ -132,6 +131,7 @@ void QDeclarativePath::setStartY(qreal y) return; d->startY = y; emit startYChanged(); + processPath(); } /*! @@ -220,6 +220,9 @@ void QDeclarativePath::processPath() { Q_D(QDeclarativePath); + if (!d->componentComplete) + return; + d->_pointCache.clear(); d->_attributePoints.clear(); d->_path = QPainterPath(); @@ -284,10 +287,18 @@ void QDeclarativePath::processPath() emit changed(); } +void QDeclarativePath::classBegin() +{ + Q_D(QDeclarativePath); + d->componentComplete = false; +} + void QDeclarativePath::componentComplete() { Q_D(QDeclarativePath); QSet<QString> attrs; + d->componentComplete = true; + // First gather up all the attributes foreach (QDeclarativePathElement *pathElement, d->_pathElements) { if (QDeclarativePathAttribute *attribute = @@ -500,7 +511,6 @@ void QDeclarativeCurve::setY(qreal y) /*! \internal \class QDeclarativePathAttribute - \ingroup group_utility \brief The QDeclarativePathAttribute class allows to set the value of an attribute at a given position in the path. \sa QDeclarativePath @@ -573,7 +583,6 @@ void QDeclarativePathAttribute::setValue(qreal value) /*! \internal \class QDeclarativePathLine - \ingroup group_utility \brief The QDeclarativePathLine class defines a straight line. \sa QDeclarativePath @@ -617,7 +626,6 @@ void QDeclarativePathLine::addToPath(QPainterPath &path) /*! \internal \class QDeclarativePathQuad - \ingroup group_utility \brief The QDeclarativePathQuad class defines a quadratic Bezier curve with a control point. \sa QDeclarativePath @@ -705,7 +713,6 @@ void QDeclarativePathQuad::addToPath(QPainterPath &path) /*! \internal \class QDeclarativePathCubic - \ingroup group_utility \brief The QDeclarativePathCubic class defines a cubic Bezier curve with two control points. \sa QDeclarativePath @@ -831,7 +838,6 @@ void QDeclarativePathCubic::addToPath(QPainterPath &path) /*! \internal \class QDeclarativePathPercent - \ingroup group_utility \brief The QDeclarativePathPercent class manipulates the way a path is interpreted. QDeclarativePathPercent allows you to bunch up items (or spread out items) along various diff --git a/src/declarative/graphicsitems/qdeclarativepath_p.h b/src/declarative/graphicsitems/qdeclarativepath_p.h index d7cfca1..17a2ea3 100644 --- a/src/declarative/graphicsitems/qdeclarativepath_p.h +++ b/src/declarative/graphicsitems/qdeclarativepath_p.h @@ -224,6 +224,7 @@ Q_SIGNALS: protected: virtual void componentComplete(); + virtual void classBegin(); private Q_SLOTS: void processPath(); diff --git a/src/declarative/graphicsitems/qdeclarativepath_p_p.h b/src/declarative/graphicsitems/qdeclarativepath_p_p.h index e82bcf5..994090e 100644 --- a/src/declarative/graphicsitems/qdeclarativepath_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativepath_p_p.h @@ -65,7 +65,7 @@ class QDeclarativePathPrivate : public QObjectPrivate Q_DECLARE_PUBLIC(QDeclarativePath) public: - QDeclarativePathPrivate() : startX(0), startY(0), closed(false) { } + QDeclarativePathPrivate() : startX(0), startY(0), closed(false), componentComplete(true) { } QPainterPath _path; QList<QDeclarativePathElement*> _pathElements; @@ -75,6 +75,7 @@ public: int startX; int startY; bool closed; + bool componentComplete; }; QT_END_NAMESPACE diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp index d0a3cd1..040fc98 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview.cpp +++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp @@ -308,12 +308,16 @@ void QDeclarativePathViewPrivate::regenerate() The model is typically provided by a QAbstractListModel "C++ model object", but can also be created directly in QML. - The items are laid out along a path defined by a \l Path and may be flicked to scroll. + The \l delegate is instantiated for each item on the \l path. + The items may be flicked to move them along the path. \snippet doc/src/snippets/declarative/pathview/pathview.qml 0 \image pathview.gif + Delegates are instantiated as needed and may be destroyed at any time. + State should \e never be stored in a delegate. + \bold Note that views do not enable \e clip automatically. If the view is not clipped by another item or the screen, it will be necessary to set \e {clip: true} in order to have the out of view items clipped @@ -557,7 +561,7 @@ void QDeclarativePathViewPrivate::setOffset(qreal o) } /*! - \qmlproperty component PathView::highlight + \qmlproperty Component PathView::highlight This property holds the component to use as the highlight. An instance of the highlight component will be created for each view. @@ -618,12 +622,12 @@ 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 ApplyRange the view will + 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 or due to a mouse interaction. - If highlightRangeMode is set to \e StrictlyEnforceRange the highlight will never + If highlightRangeMode is set to \e PathView.StrictlyEnforceRange the highlight will never move outside of the range. This means that the current item will change if a keyboard or mouse action would cause the highlight to move outside of the range. @@ -631,14 +635,14 @@ QDeclarativeItem *QDeclarativePathView::highlightItem() Note that this is the correct way to influence where the current item ends up when the view moves. For example, if you want the currently selected item to be in the middle of the path, then set the - highlight range to be 0.5,0.5 and highlightRangeMode to StrictlyEnforceRange. + highlight range to be 0.5,0.5 and highlightRangeMode to PathView.StrictlyEnforceRange. Then, when the path scrolls, the currently selected item will be the item at that position. This also applies to when the currently selected item changes - it will scroll to within the preferred highlight range. Furthermore, the behaviour of the current item index will occur whether or not a highlight exists. - The default value is \e StrictlyEnforceRange. + The default value is \e PathView.StrictlyEnforceRange. Note that a valid range requires preferredHighlightEnd to be greater than or equal to preferredHighlightBegin. @@ -786,12 +790,17 @@ void QDeclarativePathView::setInteractive(bool interactive) } /*! - \qmlproperty component PathView::delegate + \qmlproperty Component PathView::delegate The delegate provides a template defining each item instantiated by the view. The index is exposed as an accessible \c index property. Properties of the model are also available depending upon the type of \l {qmlmodels}{Data Model}. + The number of elements in the delegate has a direct effect on the + flicking performance of the view when pathItemCount is specified. If at all possible, place functionality + that is not needed for the normal display of the delegate in a \l Loader which + can load additional elements when needed. + Note that the PathView will layout the items based on the size of the root item in the delegate. @@ -961,7 +970,12 @@ void QDeclarativePathView::mouseReleaseEvent(QGraphicsSceneMouseEvent *) else dist = qRound(dist - d->offset) + d->offset; // Calculate accel required to stop on item boundary - accel = v2 / (2.0f * qAbs(dist)); + if (dist <= 0.) { + dist = 0.; + accel = 0.; + } else { + accel = v2 / (2.0f * qAbs(dist)); + } } d->moveOffset.setValue(d->offset); d->tl.accel(d->moveOffset, velocity, accel, dist); @@ -1046,7 +1060,11 @@ void QDeclarativePathView::componentComplete() Q_D(QDeclarativePathView); QDeclarativeItem::componentComplete(); d->createHighlight(); - d->regenerate(); + // It is possible that a refill has already happended to to Path + // bindings being handled in the componentComplete(). If so + // don't do it again. + if (d->items.count() == 0) + d->regenerate(); d->updateHighlight(); } diff --git a/src/declarative/graphicsitems/qdeclarativepositioners.cpp b/src/declarative/graphicsitems/qdeclarativepositioners.cpp index 21c33e2..93bff3e 100644 --- a/src/declarative/graphicsitems/qdeclarativepositioners.cpp +++ b/src/declarative/graphicsitems/qdeclarativepositioners.cpp @@ -46,6 +46,7 @@ #include <qdeclarativestate_p.h> #include <qdeclarativestategroup_p.h> #include <qdeclarativestateoperations_p.h> +#include <qdeclarativeinfo.h> #include <QtCore/qmath.h> #include <QDebug> @@ -75,7 +76,6 @@ void QDeclarativeBasePositionerPrivate::unwatchChanges(QDeclarativeItem* other) /*! \internal \class QDeclarativeBasePositioner - \ingroup group_layouts \brief The QDeclarativeBasePositioner class provides a base for QDeclarativeGraphics layouts. To create a QDeclarativeGraphics Positioner, simply subclass QDeclarativeBasePositioner and implement @@ -165,6 +165,7 @@ void QDeclarativeBasePositioner::componentComplete() QDeclarativeItem::componentComplete(); positionedItems.reserve(d->QGraphicsItemPrivate::children.count()); prePositioning(); + reportConflictingAnchors(); } QVariant QDeclarativeBasePositioner::itemChange(GraphicsItemChange change, @@ -329,7 +330,6 @@ Column { \qml Column { spacing: 2 - remove: ... add: ... move: ... ... @@ -377,7 +377,7 @@ Column { move: Transition { NumberAnimation { properties: "y" - easing.type: "OutBounce" + easing.type: Easing.OutBounce } } } @@ -403,7 +403,6 @@ Column { \internal \class QDeclarativeColumn \brief The QDeclarativeColumn class lines up items vertically. - \ingroup group_positioners */ QDeclarativeColumn::QDeclarativeColumn(QDeclarativeItem *parent) : QDeclarativeBasePositioner(Vertical, parent) @@ -436,6 +435,29 @@ void QDeclarativeColumn::doPositioning(QSizeF *contentSize) contentSize->setHeight(voffset - spacing()); } +void QDeclarativeColumn::reportConflictingAnchors() +{ + bool childsWithConflictingAnchors(false); + for (int ii = 0; ii < positionedItems.count(); ++ii) { + const PositionedItem &child = positionedItems.at(ii); + if (child.item) { + QDeclarativeAnchors *anchors = QDeclarativeItemPrivate::get(child.item)->_anchors; + if (anchors) { + QDeclarativeAnchors::Anchors usedAnchors = anchors->usedAnchors(); + if (usedAnchors & QDeclarativeAnchors::TopAnchor || + usedAnchors & QDeclarativeAnchors::BottomAnchor || + usedAnchors & QDeclarativeAnchors::VCenterAnchor) { + childsWithConflictingAnchors = true; + break; + } + } + } + } + if (childsWithConflictingAnchors) { + qmlInfo(this) << "Cannot specify top, bottom or verticalCenter anchors for items inside Column"; + } +} + /*! \qmlclass Row QDeclarativeRow \since 4.7 @@ -523,7 +545,6 @@ Row { \internal \class QDeclarativeRow \brief The QDeclarativeRow class lines up items horizontally. - \ingroup group_positioners */ QDeclarativeRow::QDeclarativeRow(QDeclarativeItem *parent) : QDeclarativeBasePositioner(Horizontal, parent) @@ -551,6 +572,28 @@ void QDeclarativeRow::doPositioning(QSizeF *contentSize) contentSize->setWidth(hoffset - spacing()); } +void QDeclarativeRow::reportConflictingAnchors() +{ + bool childsWithConflictingAnchors(false); + for (int ii = 0; ii < positionedItems.count(); ++ii) { + const PositionedItem &child = positionedItems.at(ii); + if (child.item) { + QDeclarativeAnchors *anchors = QDeclarativeItemPrivate::get(child.item)->_anchors; + if (anchors) { + QDeclarativeAnchors::Anchors usedAnchors = anchors->usedAnchors(); + if (usedAnchors & QDeclarativeAnchors::LeftAnchor || + usedAnchors & QDeclarativeAnchors::RightAnchor || + usedAnchors & QDeclarativeAnchors::HCenterAnchor) { + childsWithConflictingAnchors = true; + break; + } + } + } + } + if (childsWithConflictingAnchors) { + qmlInfo(this) << "Cannot specify left, right or horizontalCenter anchors for items inside Row"; + } +} /*! \qmlclass Grid QDeclarativeGrid @@ -652,8 +695,6 @@ Grid { \internal \class QDeclarativeGrid \brief The QDeclarativeGrid class lays out items in a grid. - \ingroup group_layouts - */ QDeclarativeGrid::QDeclarativeGrid(QDeclarativeItem *parent) : QDeclarativeBasePositioner(Both, parent), m_rows(-1), m_columns(-1), m_flow(LeftToRight) @@ -697,14 +738,14 @@ void QDeclarativeGrid::setRows(const int rows) } /*! - \qmlproperty enumeration Flow::flow + \qmlproperty enumeration Grid::flow This property holds the flow of the layout. - Possible values are \c LeftToRight (default) and \c TopToBottom. + Possible values are \c Grid.LeftToRight (default) and \c Grid.TopToBottom. - If \a flow is \c LeftToRight, the items are positioned next to + If \a flow is \c Grid.LeftToRight, the items are positioned next to to each other from left to right, then wrapped to the next line. - If \a flow is \c TopToBottom, the items are positioned next to each + If \a flow is \c Grid.TopToBottom, the items are positioned next to each other from top to bottom, then wrapped to the next column. */ QDeclarativeGrid::Flow QDeclarativeGrid::flow() const @@ -823,6 +864,23 @@ void QDeclarativeGrid::doPositioning(QSizeF *contentSize) } } +void QDeclarativeGrid::reportConflictingAnchors() +{ + bool childsWithConflictingAnchors(false); + for (int ii = 0; ii < positionedItems.count(); ++ii) { + const PositionedItem &child = positionedItems.at(ii); + if (child.item) { + QDeclarativeAnchors *anchors = QDeclarativeItemPrivate::get(child.item)->_anchors; + if (anchors && anchors->usedAnchors()) { + childsWithConflictingAnchors = true; + break; + } + } + } + if (childsWithConflictingAnchors) { + qmlInfo(this) << "Cannot specify anchors for items inside Grid"; + } +} /*! \qmlclass Flow QDeclarativeFlow @@ -894,12 +952,12 @@ QDeclarativeFlow::QDeclarativeFlow(QDeclarativeItem *parent) \qmlproperty enumeration Flow::flow This property holds the flow of the layout. - Possible values are \c LeftToRight (default) and \c TopToBottom. + Possible values are \c Flow.LeftToRight (default) and \c Flow.TopToBottom. - If \a flow is \c LeftToRight, the items are positioned next to + If \a flow is \c Flow.LeftToRight, the items are positioned next to to each other from left to right until the width of the Flow is exceeded, then wrapped to the next line. - If \a flow is \c TopToBottom, the items are positioned next to each + If \a flow is \c Flow.TopToBottom, the items are positioned next to each other from top to bottom until the height of the Flow is exceeded, then wrapped to the next column. */ @@ -966,5 +1024,22 @@ void QDeclarativeFlow::doPositioning(QSizeF *contentSize) } } +void QDeclarativeFlow::reportConflictingAnchors() +{ + bool childsWithConflictingAnchors(false); + for (int ii = 0; ii < positionedItems.count(); ++ii) { + const PositionedItem &child = positionedItems.at(ii); + if (child.item) { + QDeclarativeAnchors *anchors = QDeclarativeItemPrivate::get(child.item)->_anchors; + if (anchors && anchors->usedAnchors()) { + childsWithConflictingAnchors = true; + break; + } + } + } + if (childsWithConflictingAnchors) { + qmlInfo(this) << "Cannot specify anchors for items inside Flow"; + } +} QT_END_NAMESPACE diff --git a/src/declarative/graphicsitems/qdeclarativepositioners_p.h b/src/declarative/graphicsitems/qdeclarativepositioners_p.h index b5fc979..787dcd3 100644 --- a/src/declarative/graphicsitems/qdeclarativepositioners_p.h +++ b/src/declarative/graphicsitems/qdeclarativepositioners_p.h @@ -94,6 +94,7 @@ protected Q_SLOTS: protected: virtual void doPositioning(QSizeF *contentSize)=0; + virtual void reportConflictingAnchors()=0; struct PositionedItem { PositionedItem(QDeclarativeItem *i) : item(i), isNew(false), isVisible(true) {} bool operator==(const PositionedItem &other) const { return other.item == item; } @@ -118,6 +119,7 @@ public: QDeclarativeColumn(QDeclarativeItem *parent=0); protected: virtual void doPositioning(QSizeF *contentSize); + virtual void reportConflictingAnchors(); private: Q_DISABLE_COPY(QDeclarativeColumn) }; @@ -129,6 +131,7 @@ public: QDeclarativeRow(QDeclarativeItem *parent=0); protected: virtual void doPositioning(QSizeF *contentSize); + virtual void reportConflictingAnchors(); private: Q_DISABLE_COPY(QDeclarativeRow) }; @@ -161,6 +164,7 @@ Q_SIGNALS: protected: virtual void doPositioning(QSizeF *contentSize); + virtual void reportConflictingAnchors(); private: int m_rows; @@ -187,7 +191,7 @@ Q_SIGNALS: protected: virtual void doPositioning(QSizeF *contentSize); - + virtual void reportConflictingAnchors(); protected: QDeclarativeFlow(QDeclarativeFlowPrivate &dd, QDeclarativeItem *parent); private: diff --git a/src/declarative/graphicsitems/qdeclarativerectangle.cpp b/src/declarative/graphicsitems/qdeclarativerectangle.cpp index 0328f91..ccabbde 100644 --- a/src/declarative/graphicsitems/qdeclarativerectangle.cpp +++ b/src/declarative/graphicsitems/qdeclarativerectangle.cpp @@ -43,6 +43,7 @@ #include "private/qdeclarativerectangle_p_p.h" #include <QPainter> +#include <QStringBuilder> #include <QtCore/qmath.h> QT_BEGIN_NAMESPACE @@ -155,8 +156,8 @@ void QDeclarativeGradient::doUpdate() \brief The Rectangle item allows you to add rectangles to a scene. \inherits Item - A Rectangle is painted having a solid fill (color) and an optional border. - You can also create rounded rectangles using the radius property. + A Rectangle is painted using a solid fill (color) and an optional border. + You can also create rounded rectangles using the \l radius property. \qml Rectangle { @@ -223,14 +224,22 @@ QDeclarativePen *QDeclarativeRectangle::border() \o \image declarative-rect_gradient.png \o \qml - Rectangle { y: 0; width: 80; height: 80; color: "lightsteelblue" } - Rectangle { y: 100; width: 80; height: 80 + Rectangle { + y: 0; width: 80; height: 80 + color: "lightsteelblue" + } + + Rectangle { + y: 100; width: 80; height: 80 gradient: Gradient { GradientStop { position: 0.0; color: "lightsteelblue" } GradientStop { position: 1.0; color: "blue" } } } - Rectangle { rotation: 90; y: 200; width: 80; height: 80 + + Rectangle { + y: 200; width: 80; height: 80 + rotation: 90 gradient: Gradient { GradientStop { position: 0.0; color: "lightsteelblue" } GradientStop { position: 1.0; color: "blue" } @@ -334,21 +343,29 @@ void QDeclarativeRectangle::generateRoundedRect() if (d->rectImage.isNull()) { const int pw = d->pen && d->pen->isValid() ? d->pen->width() : 0; const int radius = qCeil(d->radius); //ensure odd numbered width/height so we get 1-pixel center - d->rectImage = QPixmap(radius*2 + 3 + pw*2, radius*2 + 3 + pw*2); - d->rectImage.fill(Qt::transparent); - QPainter p(&(d->rectImage)); - p.setRenderHint(QPainter::Antialiasing); - if (d->pen && d->pen->isValid()) { - QPen pn(QColor(d->pen->color()), d->pen->width()); - p.setPen(pn); - } else { - p.setPen(Qt::NoPen); + + QString key = QLatin1String("q_") % QString::number(pw) % d->color.name() % QString::number(d->color.alpha(), 16) % QLatin1Char('_') % QString::number(radius); + if (d->pen && d->pen->isValid()) + key += d->pen->color().name() % QString::number(d->pen->color().alpha(), 16); + + if (!QPixmapCache::find(key, &d->rectImage)) { + d->rectImage = QPixmap(radius*2 + 3 + pw*2, radius*2 + 3 + pw*2); + d->rectImage.fill(Qt::transparent); + QPainter p(&(d->rectImage)); + p.setRenderHint(QPainter::Antialiasing); + if (d->pen && d->pen->isValid()) { + QPen pn(QColor(d->pen->color()), d->pen->width()); + p.setPen(pn); + } else { + p.setPen(Qt::NoPen); + } + p.setBrush(d->color); + if (pw%2) + p.drawRoundedRect(QRectF(qreal(pw)/2+1, qreal(pw)/2+1, d->rectImage.width()-(pw+1), d->rectImage.height()-(pw+1)), d->radius, d->radius); + else + p.drawRoundedRect(QRectF(qreal(pw)/2, qreal(pw)/2, d->rectImage.width()-pw, d->rectImage.height()-pw), d->radius, d->radius); + QPixmapCache::insert(key, d->rectImage); } - p.setBrush(d->color); - if (pw%2) - p.drawRoundedRect(QRectF(qreal(pw)/2+1, qreal(pw)/2+1, d->rectImage.width()-(pw+1), d->rectImage.height()-(pw+1)), d->radius, d->radius); - else - p.drawRoundedRect(QRectF(qreal(pw)/2, qreal(pw)/2, d->rectImage.width()-pw, d->rectImage.height()-pw), d->radius, d->radius); } } @@ -357,22 +374,30 @@ void QDeclarativeRectangle::generateBorderedRect() Q_D(QDeclarativeRectangle); if (d->rectImage.isNull()) { const int pw = d->pen && d->pen->isValid() ? d->pen->width() : 0; - d->rectImage = QPixmap(pw*2 + 3, pw*2 + 3); - d->rectImage.fill(Qt::transparent); - QPainter p(&(d->rectImage)); - p.setRenderHint(QPainter::Antialiasing); - if (d->pen && d->pen->isValid()) { - QPen pn(QColor(d->pen->color()), d->pen->width()); - pn.setJoinStyle(Qt::MiterJoin); - p.setPen(pn); - } else { - p.setPen(Qt::NoPen); + + QString key = QLatin1String("q_") % QString::number(pw) % d->color.name() % QString::number(d->color.alpha(), 16); + if (d->pen && d->pen->isValid()) + key += d->pen->color().name() % QString::number(d->pen->color().alpha(), 16); + + if (!QPixmapCache::find(key, &d->rectImage)) { + d->rectImage = QPixmap(pw*2 + 3, pw*2 + 3); + d->rectImage.fill(Qt::transparent); + QPainter p(&(d->rectImage)); + p.setRenderHint(QPainter::Antialiasing); + if (d->pen && d->pen->isValid()) { + QPen pn(QColor(d->pen->color()), d->pen->width()); + pn.setJoinStyle(Qt::MiterJoin); + p.setPen(pn); + } else { + p.setPen(Qt::NoPen); + } + p.setBrush(d->color); + if (pw%2) + p.drawRect(QRectF(qreal(pw)/2+1, qreal(pw)/2+1, d->rectImage.width()-(pw+1), d->rectImage.height()-(pw+1))); + else + p.drawRect(QRectF(qreal(pw)/2, qreal(pw)/2, d->rectImage.width()-pw, d->rectImage.height()-pw)); + QPixmapCache::insert(key, d->rectImage); } - p.setBrush(d->color); - if (pw%2) - p.drawRect(QRectF(qreal(pw)/2+1, qreal(pw)/2+1, d->rectImage.width()-(pw+1), d->rectImage.height()-(pw+1))); - else - p.drawRect(QRectF(qreal(pw)/2, qreal(pw)/2, d->rectImage.width()-pw, d->rectImage.height()-pw)); } } diff --git a/src/declarative/graphicsitems/qdeclarativerepeater.cpp b/src/declarative/graphicsitems/qdeclarativerepeater.cpp index d49bb02..ca0b8c6 100644 --- a/src/declarative/graphicsitems/qdeclarativerepeater.cpp +++ b/src/declarative/graphicsitems/qdeclarativerepeater.cpp @@ -67,7 +67,7 @@ QDeclarativeRepeaterPrivate::~QDeclarativeRepeaterPrivate() \brief The Repeater item allows you to repeat an Item-based component using a model. - The Repeater item is used when you want to create a large number of + The Repeater item is used to create a large number of similar items. For each entry in the model, an item is instantiated in a context seeded with data from the model. If the repeater will be instantiating a large number of instances, it may be more efficient to diff --git a/src/declarative/graphicsitems/qdeclarativetext.cpp b/src/declarative/graphicsitems/qdeclarativetext.cpp index 2b8da8e..4e7e0fd 100644 --- a/src/declarative/graphicsitems/qdeclarativetext.cpp +++ b/src/declarative/graphicsitems/qdeclarativetext.cpp @@ -116,7 +116,7 @@ QSet<QUrl> QTextDocumentWithImageResources::errors; \brief The Text item allows you to add formatted text to a scene. \inherits Item - It can display both plain and rich text. For example: + A Text item can display both plain and rich text. For example: \qml Text { text: "Hello World!"; font.family: "Helvetica"; font.pointSize: 24; color: "red" } @@ -132,8 +132,8 @@ QSet<QUrl> QTextDocumentWithImageResources::errors; The \c elide property can alternatively be used to fit a single line of plain text to a set width. - Note that the \l{Supported HTML Subset} is limited, and that if IMG tags - load remote images, the text reloads (see resourcesLoading). + Note that the \l{Supported HTML Subset} is limited. Also, if the text contains + HTML img tags that load remote images, the text is reloaded. Text provides read-only text. For editable text, see \l TextEdit. */ @@ -142,7 +142,6 @@ QSet<QUrl> QTextDocumentWithImageResources::errors; \internal \class QDeclarativeText \qmlclass Text - \ingroup group_coreitems \brief The QDeclarativeText class provides a formatted text item that you can add to a QDeclarativeView. @@ -191,7 +190,7 @@ QDeclarativeTextPrivate::~QDeclarativeTextPrivate() /*! \qmlproperty bool Text::font.bold - Sets the font's weight to bold. + Sets whether the font weight is bold. */ /*! @@ -201,11 +200,11 @@ QDeclarativeTextPrivate::~QDeclarativeTextPrivate() The weight can be one of: \list - \o Light - \o Normal - the default - \o DemiBold - \o Bold - \o Black + \o Font.Light + \o Font.Normal - the default + \o Font.DemiBold + \o Font.Bold + \o Font.Black \endlist \qml @@ -216,25 +215,25 @@ QDeclarativeTextPrivate::~QDeclarativeTextPrivate() /*! \qmlproperty bool Text::font.italic - Sets the style of the text to italic. + Sets whether the font has an italic style. */ /*! \qmlproperty bool Text::font.underline - Set the style of the text to underline. + Sets whether the text is underlined. */ /*! \qmlproperty bool Text::font.outline - Set the style of the text to outline. + Sets whether the font has an outline style. */ /*! \qmlproperty bool Text::font.strikeout - Set the style of the text to strikeout. + Sets whether the font has a strikeout style. */ /*! @@ -278,11 +277,11 @@ QDeclarativeTextPrivate::~QDeclarativeTextPrivate() Sets the capitalization for the text. \list - \o MixedCase - This is the normal text rendering option where no capitalization change is applied. - \o AllUppercase - This alters the text to be rendered in all uppercase type. - \o AllLowercase - This alters the text to be rendered in all lowercase type. - \o SmallCaps - This alters the text to be rendered in small-caps type. - \o Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character. + \o Font.MixedCase - This is the normal text rendering option where no capitalization change is applied. + \o Font.AllUppercase - This alters the text to be rendered in all uppercase type. + \o Font.AllLowercase - This alters the text to be rendered in all lowercase type. + \o Font.SmallCaps - This alters the text to be rendered in small-caps type. + \o Font.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character. \endlist \qml @@ -381,10 +380,10 @@ QColor QDeclarativeText::color() const Supported text styles are: \list - \o Normal - the default - \o Outline - \o Raised - \o Sunken + \o Text.Normal - the default + \o Text.Outline + \o Text.Raised + \o Text.Sunken \endlist \qml @@ -452,9 +451,14 @@ QColor QDeclarativeText::styleColor() const Sets the horizontal and vertical alignment of the text within the Text items width and height. By default, the text is top-left aligned. - The valid values for \c horizontalAlignment are \c AlignLeft, \c AlignRight and - \c AlignHCenter. The valid values for \c verticalAlignment are \c AlignTop, \c AlignBottom - and \c AlignVCenter. + The valid values for \c horizontalAlignment are \c Text.AlignLeft, \c Text.AlignRight and + \c Text.AlignHCenter. The valid values for \c verticalAlignment are \c Text.AlignTop, \c Text.AlignBottom + and \c Text.AlignVCenter. + + Note that for a single line of text, the size of the text is the area of the text. In this common case, + all alignments are equivalent. If you want the text to be, say, centered in it parent, then you will + need to either modify the Item::anchors, or set horizontalAlignment to Text.AlignHCenter and bind the width to + that of the parent. */ QDeclarativeText::HAlignment QDeclarativeText::hAlign() const { @@ -495,16 +499,16 @@ void QDeclarativeText::setVAlign(VAlignment align) wrap if an explicit width has been set. wrapMode can be one of: \list - \o NoWrap - no wrapping will be performed. - \o WordWrap - wrapping is done on word boundaries. If the text cannot be + \o Text.NoWrap - no wrapping will be performed. + \o Text.WordWrap - wrapping is done on word boundaries. If the text cannot be word-wrapped to the specified width it will be partially drawn outside of the item's bounds. If this is undesirable then enable clipping on the item (Item::clip). - \o WrapAnywhere - Text can be wrapped at any point on a line, even if it occurs in the middle of a word. - \o WrapAtWordBoundaryOrAnywhere - If possible, wrapping occurs at a word boundary; otherwise it + \o Text.WrapAnywhere - Text can be wrapped at any point on a line, even if it occurs in the middle of a word. + \o Text.WrapAtWordBoundaryOrAnywhere - If possible, wrapping occurs at a word boundary; otherwise it will occur at the appropriate point on the line, even in the middle of a word. \endlist - The default is NoWrap. + The default is Text.NoWrap. */ QDeclarativeText::WrapMode QDeclarativeText::wrapMode() const { @@ -531,13 +535,20 @@ void QDeclarativeText::setWrapMode(WrapMode mode) The way the text property should be displayed. - Supported text formats are \c AutoText, \c PlainText, \c RichText and \c StyledText + Supported text formats are: + + \list + \o Text.AutoText + \o Text.PlainText + \o Text.RichText + \o Text.StyledText + \endlist - The default is AutoText. If the text format is AutoText the text element + The default is Text.AutoText. If the text format is Text.AutoText the text element will automatically determine whether the text should be treated as rich text. This determination is made using Qt::mightBeRichText(). - StyledText is an optimized format supporting some basic text + Text.StyledText is an optimized format supporting some basic text styling markup, in the style of html 3.2: \code @@ -548,7 +559,7 @@ void QDeclarativeText::setWrapMode(WrapMode mode) > < & \endcode - \c StyledText parser is strict, requiring tags to be correctly nested. + \c Text.StyledText parser is strict, requiring tags to be correctly nested. \table \row @@ -616,13 +627,13 @@ void QDeclarativeText::setTextFormat(TextFormat format) Eliding can be: \list - \o ElideNone - the default - \o ElideLeft - \o ElideMiddle - \o ElideRight + \o Text.ElideNone - the default + \o Text.ElideLeft + \o Text.ElideMiddle + \o Text.ElideRight \endlist - If the text is a multi-length string, and the mode is not \c ElideNone, + If the text is a multi-length string, and the mode is not \c Text.ElideNone, the first string that fits will be used, otherwise the last will be elided. Multi-length strings are ordered from longest to shortest, separated by the @@ -1069,8 +1080,9 @@ void QDeclarativeText::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWid /*! \qmlproperty bool Text::smooth - Set this property if you want the text to be smoothly scaled or - transformed. Smooth filtering gives better visual quality, but is slower. If + This property holds whether the text is smoothly scaled or transformed. + + Smooth filtering gives better visual quality, but is slower. If the item is displayed at its natural size, this property has no visual or performance effect. diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp index 25eaef6..6d86e58 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp @@ -46,6 +46,8 @@ #include <private/qdeclarativeglobal_p.h> #include <qdeclarativeinfo.h> +#include <QtCore/qmath.h> + #include <QTextLayout> #include <QTextLine> #include <QTextDocument> @@ -85,7 +87,6 @@ TextEdit { \internal \class QDeclarativeTextEdit \qmlclass TextEdit - \ingroup group_coreitems \brief The QDeclarativeTextEdit class provides an editable formatted text item that you can add to a QDeclarativeView. @@ -129,7 +130,7 @@ QString QDeclarativeTextEdit::text() const /*! \qmlproperty bool TextEdit::font.bold - Sets the font's weight to bold. + Sets whether the font weight is bold. */ /*! @@ -139,11 +140,11 @@ QString QDeclarativeTextEdit::text() const The weight can be one of: \list - \o Light - \o Normal - the default - \o DemiBold - \o Bold - \o Black + \o Font.Light + \o Font.Normal - the default + \o Font.DemiBold + \o Font.Bold + \o Font.Black \endlist \qml @@ -154,25 +155,25 @@ QString QDeclarativeTextEdit::text() const /*! \qmlproperty bool TextEdit::font.italic - Sets the style of the text to italic. + Sets whether the font has an italic style. */ /*! \qmlproperty bool TextEdit::font.underline - Set the style of the text to underline. + Sets whether the text is underlined. */ /*! \qmlproperty bool TextEdit::font.outline - Set the style of the text to outline. + Sets whether the font has an outline style. */ /*! \qmlproperty bool TextEdit::font.strikeout - Set the style of the text to strikeout. + Sets whether the font has a strikeout style. */ /*! @@ -216,11 +217,11 @@ QString QDeclarativeTextEdit::text() const Sets the capitalization for the text. \list - \o MixedCase - This is the normal text rendering option where no capitalization change is applied. - \o AllUppercase - This alters the text to be rendered in all uppercase type. - \o AllLowercase - This alters the text to be rendered in all lowercase type. - \o SmallCaps - This alters the text to be rendered in small-caps type. - \o Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character. + \o Font.MixedCase - This is the normal text rendering option where no capitalization change is applied. + \o Font.AllUppercase - This alters the text to be rendered in all uppercase type. + \o Font.AllLowercase - This alters the text to be rendered in all lowercase type. + \o Font.SmallCaps - This alters the text to be rendered in small-caps type. + \o Font.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character. \endlist \qml @@ -255,9 +256,14 @@ void QDeclarativeTextEdit::setText(const QString &text) The way the text property should be displayed. - Supported text formats are \c AutoText, \c PlainText and \c RichText. + \list + \o TextEdit.AutoText + \o TextEdit.PlainText + \o TextEdit.RichText + \o TextEdit.StyledText + \endlist - The default is AutoText. If the text format is AutoText the text edit + The default is TextEdit.AutoText. If the text format is TextEdit.AutoText the text edit will automatically determine whether the text should be treated as rich text. This determination is made using Qt::mightBeRichText(). @@ -424,9 +430,9 @@ void QDeclarativeTextEdit::setSelectedTextColor(const QColor &color) Sets the horizontal and vertical alignment of the text within the TextEdit items width and height. By default, the text is top-left aligned. - The valid values for \c horizontalAlignment are \c AlignLeft, \c AlignRight and - \c AlignHCenter. The valid values for \c verticalAlignment are \c AlignTop, \c AlignBottom - and \c AlignVCenter. + The valid values for \c horizontalAlignment are \c TextEdit.AlignLeft, \c TextEdit.AlignRight and + \c TextEdit.AlignHCenter. The valid values for \c verticalAlignment are \c TextEdit.AlignTop, \c TextEdit.AlignBottom + and \c TextEdit.AlignVCenter. */ QDeclarativeTextEdit::HAlignment QDeclarativeTextEdit::hAlign() const { @@ -469,14 +475,14 @@ void QDeclarativeTextEdit::setVAlign(QDeclarativeTextEdit::VAlignment alignment) The text will only wrap if an explicit width has been set. \list - \o NoWrap - no wrapping will be performed. - \o WordWrap - wrapping is done on word boundaries. - \o WrapAnywhere - Text can be wrapped at any point on a line, even if it occurs in the middle of a word. - \o WrapAtWordBoundaryOrAnywhere - If possible, wrapping occurs at a word boundary; otherwise it + \o TextEdit.NoWrap - no wrapping will be performed. + \o TextEdit.WordWrap - wrapping is done on word boundaries. + \o TextEdit.WrapAnywhere - Text can be wrapped at any point on a line, even if it occurs in the middle of a word. + \o TextEdit.WrapAtWordBoundaryOrAnywhere - If possible, wrapping occurs at a word boundary; otherwise it will occur at the appropriate point on the line, even in the middle of a word. \endlist - The default is NoWrap. + The default is TextEdit.NoWrap. */ QDeclarativeTextEdit::WrapMode QDeclarativeTextEdit::wrapMode() const { @@ -724,7 +730,7 @@ void QDeclarativeTextEdit::setPersistentSelection(bool on) } /* - \qmlproperty number TextEdit::textMargin + \qmlproperty real TextEdit::textMargin The margin, in pixels, around the text in the TextEdit. */ @@ -991,8 +997,9 @@ void QDeclarativeTextEdit::updateImgCache(const QRectF &r) /*! \qmlproperty bool TextEdit::smooth - Set this property if you want the text to be smoothly scaled or - transformed. Smooth filtering gives better visual quality, but is slower. If + This property holds whether the text is smoothly scaled or transformed. + + Smooth filtering gives better visual quality, but is slower. If the item is displayed at its natural size, this property has no visual or performance effect. @@ -1102,7 +1109,7 @@ void QDeclarativeTextEdit::updateSize() setBaselineOffset(fm.ascent() + yoff + d->textMargin); //### need to comfirm cost of always setting these - int newWidth = (int)d->document->idealWidth(); + int newWidth = qCeil(d->document->idealWidth()); d->document->setTextWidth(newWidth); // ### QTextDoc> Alignment will not work unless textWidth is set. Does Text need this line as well? int cursorWidth = 1; if(d->cursor) diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index b618183..604f508 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -62,6 +62,9 @@ QT_BEGIN_NAMESPACE Input constraints include setting a QValidator, an input mask, or a maximum input length. + + On Mac OS X, the Up/Down key bindings for Home/End are explicitly disabled. + If you want such bindings (on any platform), you will need to construct them in QML. */ QDeclarativeTextInput::QDeclarativeTextInput(QDeclarativeItem* parent) : QDeclarativePaintedItem(*(new QDeclarativeTextInputPrivate), parent) @@ -108,7 +111,7 @@ void QDeclarativeTextInput::setText(const QString &s) /*! \qmlproperty bool TextInput::font.bold - Sets the font's weight to bold. + Sets whether the font weight is bold. */ /*! @@ -118,11 +121,11 @@ void QDeclarativeTextInput::setText(const QString &s) The weight can be one of: \list - \o Light - \o Normal - the default - \o DemiBold - \o Bold - \o Black + \o Font.Light + \o Font.Normal - the default + \o Font.DemiBold + \o Font.Bold + \o Font.Black \endlist \qml @@ -133,25 +136,25 @@ void QDeclarativeTextInput::setText(const QString &s) /*! \qmlproperty bool TextInput::font.italic - Sets the style of the text to italic. + Sets whether the font has an italic style. */ /*! \qmlproperty bool TextInput::font.underline - Set the style of the text to underline. + Sets whether the text is underlined. */ /*! \qmlproperty bool TextInput::font.outline - Set the style of the text to outline. + Sets whether the font has an outline style. */ /*! \qmlproperty bool TextInput::font.strikeout - Set the style of the text to strikeout. + Sets whether the font has a strikeout style. */ /*! @@ -195,11 +198,11 @@ void QDeclarativeTextInput::setText(const QString &s) Sets the capitalization for the text. \list - \o MixedCase - This is the normal text rendering option where no capitalization change is applied. - \o AllUppercase - This alters the text to be rendered in all uppercase type. - \o AllLowercase - This alters the text to be rendered in all lowercase type. - \o SmallCaps - This alters the text to be rendered in small-caps type. - \o Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character. + \o Font.MixedCase - This is the normal text rendering option where no capitalization change is applied. + \o Font.AllUppercase - This alters the text to be rendered in all uppercase type. + \o Font.AllLowercase - This alters the text to be rendered in all lowercase type. + \o Font.SmallCaps - This alters the text to be rendered in small-caps type. + \o Font.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character. \endlist \qml @@ -308,8 +311,8 @@ void QDeclarativeTextInput::setSelectedTextColor(const QColor &color) vertically. You can use anchors to align it however you want within another item. - The valid values for \c horizontalAlignment are \c AlignLeft, \c AlignRight and - \c AlignHCenter. + The valid values for \c horizontalAlignment are \c TextInput.AlignLeft, \c TextInput.AlignRight and + \c TextInput.AlignHCenter. */ QDeclarativeTextInput::HAlignment QDeclarativeTextInput::hAlign() const { @@ -600,9 +603,9 @@ void QDeclarativeTextInput::setAutoScroll(bool b) This property holds the notation of how a string can describe a number. The values for this property are DoubleValidator.StandardNotation or DoubleValidator.ScientificNotation. - If this property is set to ScientificNotation, the written number may have an exponent part(i.e. 1.5E-2). + If this property is set to DoubleValidator.ScientificNotation, the written number may have an exponent part(i.e. 1.5E-2). - By default, this property is set to ScientificNotation. + By default, this property is set to DoubleValidator.ScientificNotation. */ /*! @@ -706,14 +709,15 @@ bool QDeclarativeTextInput::hasAcceptableInput() const } /*! - \qmlproperty TextInput.EchoMode TextInput::echoMode + \qmlproperty enumeration TextInput::echoMode Specifies how the text should be displayed in the TextInput. - The default is Normal, which displays the text as it is. Other values - are Password, which displays asterixes instead of characters, NoEcho, - which displays nothing, and PasswordEchoOnEdit, which displays all but the - current character as asterixes. - + \list + \o TextInput.Normal - Displays the text as it is. (Default) + \o TextInput.Password - Displays asterixes instead of characters. + \o TextInput.NoEcho - Displays nothing. + \o TextInput.PasswordEchoOnEdit - Displays all but the current character as asterixes. + \endlist */ QDeclarativeTextInput::EchoMode QDeclarativeTextInput::echoMode() const { @@ -827,8 +831,8 @@ void QDeclarativeTextInput::moveCursor() d->cursorItem->setX(d->control->cursorToX() - d->hscroll); } -/* - \qmlmethod int xToPosition(int x) +/*! + \qmlmethod int TextInput::xToPosition(int x) This function returns the character position at x pixels from the left of the textInput. Position 0 is before the @@ -859,10 +863,12 @@ void QDeclarativeTextInputPrivate::focusChanged(bool hasFocus) void QDeclarativeTextInput::keyPressEvent(QKeyEvent* ev) { Q_D(QDeclarativeTextInput); - if(((d->control->cursor() == 0 && ev->key() == Qt::Key_Left) + if (((ev->key() == Qt::Key_Up || ev->key() == Qt::Key_Down) && ev->modifiers() == Qt::NoModifier) // Don't allow MacOSX up/down support, and we don't allow a completer. + || (((d->control->cursor() == 0 && ev->key() == Qt::Key_Left) || (d->control->cursor() == d->control->text().length() && ev->key() == Qt::Key_Right)) - && (d->lastSelectionStart == d->lastSelectionEnd)){ + && (d->lastSelectionStart == d->lastSelectionEnd))) + { //ignore when moving off the end //unless there is a selection, because then moving will do something (deselect) ev->ignore(); @@ -1044,8 +1050,9 @@ void QDeclarativeTextInput::selectAll() /*! \qmlproperty bool TextInput::smooth - Set this property if you want the text to be smoothly scaled or - transformed. Smooth filtering gives better visual quality, but is slower. If + This property holds whether the text is smoothly scaled or transformed. + + Smooth filtering gives better visual quality, but is slower. If the item is displayed at its natural size, this property has no visual or performance effect. @@ -1054,15 +1061,15 @@ void QDeclarativeTextInput::selectAll() filtering at the beginning of the animation and reenable it at the conclusion. */ -/* +/*! \qmlproperty string TextInput::passwordCharacter This is the character displayed when echoMode is set to Password or PasswordEchoOnEdit. By default it is an asterisk. - Attempting to set this to more than one character will set it to - the first character in the string. Attempting to set this to less - than one character will fail. + If this property is set to a string with more than one character, + the first character is used. If the string is empty, the value + is ignored and the property is not set. */ QString QDeclarativeTextInput::passwordCharacter() const { @@ -1079,15 +1086,15 @@ void QDeclarativeTextInput::setPasswordCharacter(const QString &str) d->control->setPasswordCharacter(str.constData()[0]); } -/* +/*! \qmlproperty string TextInput::displayText - This is the actual text displayed in the TextInput. When - echoMode is set to TextInput::Normal this will be exactly - the same as the TextInput::text property. When echoMode - is set to something else, this property will contain the text - the user sees, while the text property will contain the - entered text. + This is the text displayed in the TextInput. + + If \l echoMode is set to TextInput::Normal, this holds the + same value as the TextInput::text property. Otherwise, + this property holds the text visible to the user, while + the \l text property holds the actual entered text. */ QString QDeclarativeTextInput::displayText() const { @@ -1095,29 +1102,33 @@ QString QDeclarativeTextInput::displayText() const return d->control->displayText(); } -/* - \qmlmethod void moveCursorSelection(int pos) +/*! + \qmlmethod void TextInput::moveCursorSelection(int position) - This method allows you to move the cursor while modifying the selection accordingly. - To simply move the cursor, set the cursorPosition property. + Moves the cursor to \a position and updates the selection accordingly. + (To only move the cursor, set the \l cursorPosition property.) When this method is called it additionally sets either the selectionStart or the selectionEnd (whichever was at the previous cursor position) to the specified position. This allows you to easily extend and contract the selected text range. - Example: The sequence of calls + For example, take this sequence of calls: + + \code cursorPosition = 5 moveCursorSelection(9) moveCursorSelection(7) - would move the cursor to position 5, extend the selection end from 5 to 9 + \endcode + + This moves the cursor to position 5, extend the selection end from 5 to 9 and then retract the selection end from 9 to 7, leaving the text from position 5 to 7 selected (the 6th and 7th characters). */ -void QDeclarativeTextInput::moveCursorSelection(int pos) +void QDeclarativeTextInput::moveCursorSelection(int position) { Q_D(QDeclarativeTextInput); - d->control->moveCursor(pos, true); + d->control->moveCursor(position, true); } void QDeclarativeTextInputPrivate::init() diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp index 43cafe3..1038c83 100644 --- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp +++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp @@ -44,6 +44,7 @@ #include "qdeclarativeitem.h" #include <qdeclarativecontext.h> +#include <qdeclarativecontext_p.h> #include <qdeclarativeengine.h> #include <qdeclarativeexpression.h> #include <qdeclarativepackage_p.h> @@ -55,6 +56,7 @@ #include <qdeclarativeguard_p.h> #include <qdeclarativeglobal_p.h> +#include <qgraphicsscene.h> #include <qlistmodelinterface_p.h> #include <qhash.h> #include <qlist.h> @@ -436,8 +438,7 @@ int QDeclarativeVisualDataModelDataMetaObject::createProperty(const char *name, if ((!model->m_listModelInterface || !model->m_abstractItemModel) && model->m_listAccessor) { if (model->m_listAccessor->type() == QDeclarativeListAccessor::ListProperty) { model->ensureRoles(); - QObject *object = model->m_listAccessor->at(data->m_index).value<QObject*>(); - if (object && (object->property(name).isValid() || qstrcmp(name,"modelData")==0)) + if (qstrcmp(name,"modelData") == 0) return QDeclarativeOpenMetaObject::createProperty(name, type); } } @@ -759,7 +760,7 @@ void QDeclarativeVisualDataModel::setModel(const QVariant &model) } /*! - \qmlproperty component VisualDataModel::delegate + \qmlproperty Component VisualDataModel::delegate The delegate provides a template defining each item instantiated by a view. The index is exposed as an accessible \c index property. Properties of the @@ -963,13 +964,18 @@ QDeclarativeVisualDataModel::ReleaseFlags QDeclarativeVisualDataModel::release(Q } if (d->m_cache.releaseItem(obj)) { + // Remove any bindings to avoid warnings due to parent change. + QObjectPrivate *p = QObjectPrivate::get(obj); + Q_ASSERT(p->declarativeData); + QDeclarativeData *d = static_cast<QDeclarativeData*>(p->declarativeData); + if (d->ownContext && d->context) + d->context->clearExpressions(); + if (inPackage) { emit destroyingPackage(qobject_cast<QDeclarativePackage*>(obj)); } else { - if (item->hasFocus()) - item->clearFocus(); - item->setOpacity(0.0); - static_cast<QGraphicsItem*>(item)->setParentItem(0); + if (item->scene()) + item->scene()->removeItem(item); } stat |= Destroyed; obj->deleteLater(); @@ -1030,6 +1036,11 @@ QDeclarativeItem *QDeclarativeVisualDataModel::item(int index, const QByteArray if (!ccontext) ccontext = qmlContext(this); QDeclarativeContext *ctxt = new QDeclarativeContext(ccontext); QDeclarativeVisualDataModelData *data = new QDeclarativeVisualDataModelData(index, this); + if ((!d->m_listModelInterface || !d->m_abstractItemModel) && d->m_listAccessor + && d->m_listAccessor->type() == QDeclarativeListAccessor::ListProperty) { + ctxt->setContextObject(d->m_listAccessor->at(index).value<QObject*>()); + ctxt = new QDeclarativeContext(ctxt, ctxt); + } ctxt->setContextProperty(QLatin1String("model"), data); ctxt->setContextObject(data); d->m_completePending = false; diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp index d44e7fb..8043ea9 100644 --- a/src/declarative/qml/qdeclarativebinding.cpp +++ b/src/declarative/qml/qdeclarativebinding.cpp @@ -193,7 +193,18 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags) data->error.setColumn(-1); data->error.setDescription(QLatin1String("Unable to assign [undefined] to ") + QLatin1String(QMetaType::typeName(data->property.propertyType()))); - } else if (data->property.object() && + } else if (!scriptValue.isRegExp() && scriptValue.isFunction()) { + + QUrl url = QUrl(data->url); + int line = data->line; + if (url.isEmpty()) url = QUrl(QLatin1String("<Unknown File>")); + + data->error.setUrl(url); + data->error.setLine(line); + data->error.setColumn(-1); + data->error.setDescription(QLatin1String("Unable to assign a function to a property.")); + + } else if (data->property.object() && !QDeclarativePropertyPrivate::write(data->property, value, flags)) { QUrl url = QUrl(data->url); diff --git a/src/declarative/qml/qdeclarativecompiledbindings.cpp b/src/declarative/qml/qdeclarativecompiledbindings.cpp index 6596aba..05b7dc6 100644 --- a/src/declarative/qml/qdeclarativecompiledbindings.cpp +++ b/src/declarative/qml/qdeclarativecompiledbindings.cpp @@ -572,7 +572,7 @@ struct QDeclarativeBindingCompilerPrivate QDeclarativeParser::Object *component; QDeclarativeParser::Property *destination; QHash<QString, QDeclarativeParser::Object *> ids; - QDeclarativeEnginePrivate::Imports imports; + QDeclarativeImports imports; QDeclarativeEnginePrivate *engine; QString contextName() const { return QLatin1String("$$$SCOPE_") + QString::number((intptr_t)context, 16); } @@ -1795,8 +1795,8 @@ bool QDeclarativeBindingCompilerPrivate::parseName(AST::Node *node, Result &type if (nameParts.at(ii + 1).at(0).isUpper()) return false; - QDeclarativeEnginePrivate::ImportedNamespace *ns = 0; - if (!engine->resolveType(imports, name.toUtf8(), &attachType, 0, 0, 0, &ns)) + QDeclarativeImportedNamespace *ns = 0; + if (!engine->importDatabase.resolveType(imports, name.toUtf8(), &attachType, 0, 0, 0, &ns)) return false; if (ns || !attachType || !attachType->attachedPropertiesType()) return false; diff --git a/src/declarative/qml/qdeclarativecompiledbindings_p.h b/src/declarative/qml/qdeclarativecompiledbindings_p.h index d5c6a02..a9772cc 100644 --- a/src/declarative/qml/qdeclarativecompiledbindings_p.h +++ b/src/declarative/qml/qdeclarativecompiledbindings_p.h @@ -77,7 +77,7 @@ public: QDeclarativeParser::Property *property; QDeclarativeParser::Variant expression; QHash<QString, QDeclarativeParser::Object *> ids; - QDeclarativeEnginePrivate::Imports imports; + QDeclarativeImports imports; }; // -1 on failure, otherwise the binding index to use diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 1727687..6d420a7 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -607,6 +607,7 @@ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine, Q_ASSERT(root); this->engine = engine; + this->enginePrivate = QDeclarativeEnginePrivate::get(engine); this->unit = unit; this->unitRoot = root; compileTree(root); @@ -624,6 +625,7 @@ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine, savedCompileStates.clear(); output = 0; this->engine = 0; + this->enginePrivate = 0; this->unit = 0; this->unitRoot = 0; @@ -688,14 +690,12 @@ void QDeclarativeCompiler::compileTree(Object *tree) def.type = QDeclarativeInstruction::SetDefault; output->bytecode << def; - output->imports = unit->imports; - output->importCache = new QDeclarativeTypeNameCache(engine); for (int ii = 0; ii < importedScriptIndexes.count(); ++ii) output->importCache->add(importedScriptIndexes.at(ii), ii); - output->imports.cache(output->importCache, engine); + unit->imports.cache(output->importCache, engine); Q_ASSERT(tree->metatype); @@ -706,7 +706,7 @@ void QDeclarativeCompiler::compileTree(Object *tree) output->root = &output->rootData; } if (!tree->metadata.isEmpty()) - QDeclarativeEnginePrivate::get(engine)->registerCompositeType(output); + enginePrivate->registerCompositeType(output); } static bool ValuePtrLessThan(const Value *t1, const Value *t2) @@ -938,19 +938,28 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj) meta.storeMeta.propertyCache = output->propertyCaches.count(); // ### Surely the creation of this property cache could be more efficient QDeclarativePropertyCache *propertyCache = 0; - if (tr.component && QDeclarativeComponentPrivate::get(tr.component)->cc->rootPropertyCache) { + if (tr.component) propertyCache = QDeclarativeComponentPrivate::get(tr.component)->cc->rootPropertyCache->copy(); - } else { - propertyCache = QDeclarativePropertyCache::create(engine, obj->metaObject()->superClass()); - } + else + propertyCache = enginePrivate->cache(obj->metaObject()->superClass())->copy(); + propertyCache->append(engine, obj->metaObject(), QDeclarativePropertyCache::Data::NoFlags, QDeclarativePropertyCache::Data::IsVMEFunction); + if (obj == unitRoot) { propertyCache->addref(); output->rootPropertyCache = propertyCache; } + output->propertyCaches << propertyCache; output->bytecode << meta; + } else if (obj == unitRoot) { + if (tr.component) + output->rootPropertyCache = QDeclarativeComponentPrivate::get(tr.component)->cc->rootPropertyCache; + else + output->rootPropertyCache = enginePrivate->cache(obj->metaObject()); + + output->rootPropertyCache->addref(); } // Set the object id @@ -1359,9 +1368,9 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop, } QDeclarativeType *type = 0; - QDeclarativeEnginePrivate::ImportedNamespace *typeNamespace = 0; - QDeclarativeEnginePrivate::get(engine)->resolveType(unit->imports, prop->name, - &type, 0, 0, 0, &typeNamespace); + QDeclarativeImportedNamespace *typeNamespace = 0; + enginePrivate->importDatabase.resolveType(unit->imports, prop->name, + &type, 0, 0, 0, &typeNamespace); if (typeNamespace) { // ### We might need to indicate that this property is a namespace @@ -1436,7 +1445,7 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop, COMPILE_CHECK(buildGroupedProperty(prop, obj, ctxt)); - } else if (QDeclarativeEnginePrivate::get(engine)->isList(prop->type)) { + } else if (enginePrivate->isList(prop->type)) { COMPILE_CHECK(buildListProperty(prop, obj, ctxt)); @@ -1453,11 +1462,10 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop, return true; } -bool -QDeclarativeCompiler::buildPropertyInNamespace(QDeclarativeEnginePrivate::ImportedNamespace *ns, - QDeclarativeParser::Property *nsProp, - QDeclarativeParser::Object *obj, - const BindingContext &ctxt) +bool QDeclarativeCompiler::buildPropertyInNamespace(QDeclarativeImportedNamespace *ns, + QDeclarativeParser::Property *nsProp, + QDeclarativeParser::Object *obj, + const BindingContext &ctxt) { if (!nsProp->value) COMPILE_EXCEPTION(nsProp, tr("Invalid use of namespace")); @@ -1470,8 +1478,7 @@ QDeclarativeCompiler::buildPropertyInNamespace(QDeclarativeEnginePrivate::Import // Setup attached property data QDeclarativeType *type = 0; - QDeclarativeEnginePrivate::get(engine)->resolveTypeInNamespace(ns, prop->name, - &type, 0, 0, 0); + enginePrivate->importDatabase.resolveTypeInNamespace(ns, prop->name, &type, 0, 0, 0); if (!type || !type->attachedPropertiesType()) COMPILE_EXCEPTION(prop, tr("Non-existent attached object")); @@ -1492,7 +1499,7 @@ QDeclarativeCompiler::buildPropertyInNamespace(QDeclarativeEnginePrivate::Import void QDeclarativeCompiler::genValueProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj) { - if (QDeclarativeEnginePrivate::get(engine)->isList(prop->type)) { + if (enginePrivate->isList(prop->type)) { genListProperty(prop, obj); } else { genPropertyAssignment(prop, obj); @@ -1502,7 +1509,7 @@ void QDeclarativeCompiler::genValueProperty(QDeclarativeParser::Property *prop, void QDeclarativeCompiler::genListProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj) { - int listType = QDeclarativeEnginePrivate::get(engine)->listType(prop->type); + int listType = enginePrivate->listType(prop->type); QDeclarativeInstruction fetch; fetch.type = QDeclarativeInstruction::FetchQList; @@ -1756,8 +1763,7 @@ bool QDeclarativeCompiler::buildGroupedProperty(QDeclarativeParser::Property *pr } else { // Load the nested property's meta type - prop->value->metatype = - QDeclarativeEnginePrivate::get(engine)->metaObjectForType(prop->type); + prop->value->metatype = enginePrivate->metaObjectForType(prop->type); if (!prop->value->metatype) COMPILE_EXCEPTION(prop, tr("Invalid grouped property access")); @@ -1836,13 +1842,13 @@ bool QDeclarativeCompiler::buildListProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj, const BindingContext &ctxt) { - Q_ASSERT(QDeclarativeEnginePrivate::get(engine)->isList(prop->type)); + Q_ASSERT(enginePrivate->isList(prop->type)); int t = prop->type; obj->addValueProperty(prop); - int listType = QDeclarativeEnginePrivate::get(engine)->listType(t); + int listType = enginePrivate->listType(t); bool listTypeIsInterface = QDeclarativeMetaType::isInterface(listType); bool assignedBinding = false; @@ -1957,8 +1963,7 @@ bool QDeclarativeCompiler::buildPropertyObjectAssignment(QDeclarativeParser::Pro // We want to raw metaObject here as the raw metaobject is the // actual property type before we applied any extensions that might // effect the properties on the type, but don't effect assignability - const QMetaObject *propertyMetaObject = - QDeclarativeEnginePrivate::get(engine)->rawMetaObjectForType(prop->type); + const QMetaObject *propertyMetaObject = enginePrivate->rawMetaObjectForType(prop->type); // Will be true if the assgned type inherits propertyMetaObject bool isAssignable = false; @@ -2100,8 +2105,8 @@ bool QDeclarativeCompiler::testQualifiedEnumAssignment(const QMetaProperty &prop QString typeName = parts.at(0); QDeclarativeType *type = 0; - QDeclarativeEnginePrivate::get(engine)->resolveType(unit->imports, typeName.toUtf8(), - &type, 0, 0, 0, 0); + enginePrivate->importDatabase.resolveType(unit->imports, typeName.toUtf8(), + &type, 0, 0, 0, 0); if (!type || obj->typeName != type->qmlTypeName()) return true; @@ -2128,7 +2133,7 @@ int QDeclarativeCompiler::evaluateEnum(const QByteArray& script) const int dot = script.indexOf('.'); if (dot > 0) { QDeclarativeType *type = 0; - QDeclarativeEnginePrivate::get(engine)->resolveType(unit->imports, script.left(dot), &type, 0, 0, 0, 0); + enginePrivate->importDatabase.resolveType(unit->imports, script.left(dot), &type, 0, 0, 0, 0); if (!type) return -1; const QMetaObject *mo = type->metaObject(); @@ -2282,13 +2287,12 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn QByteArray customTypeName; QDeclarativeType *qmltype = 0; QUrl url; - QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(engine); - if (!priv->resolveType(unit->imports, p.customType, &qmltype, - &url, 0, 0, 0)) + if (!enginePrivate->importDatabase.resolveType(unit->imports, p.customType, &qmltype, + &url, 0, 0, 0)) COMPILE_EXCEPTION(&p, tr("Invalid property type")); if (!qmltype) { - QDeclarativeCompositeTypeData *tdata = priv->typeManager.get(url); + QDeclarativeCompositeTypeData *tdata = enginePrivate->typeManager.get(url); Q_ASSERT(tdata); Q_ASSERT(tdata->status == QDeclarativeCompositeTypeData::Complete); @@ -2460,7 +2464,7 @@ bool QDeclarativeCompiler::checkValidId(QDeclarativeParser::Value *v, const QStr } - if (QDeclarativeEnginePrivate::get(engine)->globalClass->illegalNames().contains(val)) + if (enginePrivate->globalClass->illegalNames().contains(val)) COMPILE_EXCEPTION(v, tr( "ID illegally masks global JavaScript property")); return true; @@ -2653,8 +2657,8 @@ int QDeclarativeCompiler::genValueTypeData(QDeclarativeParser::Property *valueTy { QByteArray data = QDeclarativePropertyPrivate::saveValueType(prop->parent->metaObject(), prop->index, - QDeclarativeEnginePrivate::get(engine)->valueTypes[prop->type]->metaObject(), - valueTypeProp->index); + enginePrivate->valueTypes[prop->type]->metaObject(), + valueTypeProp->index); // valueTypeProp->index, valueTypeProp->type); return output->indexForByteArray(data); @@ -2690,7 +2694,7 @@ bool QDeclarativeCompiler::completeComponentBuild() expr.expression = binding.expression; expr.imports = unit->imports; - int index = bindingCompiler.compile(expr, QDeclarativeEnginePrivate::get(engine)); + int index = bindingCompiler.compile(expr, enginePrivate); if (index != -1) { binding.dataType = BindingReference::Experimental; binding.compiledIndex = index; @@ -2798,7 +2802,7 @@ void QDeclarativeCompiler::dumpStats() bool QDeclarativeCompiler::canCoerce(int to, QDeclarativeParser::Object *from) { const QMetaObject *toMo = - QDeclarativeEnginePrivate::get(engine)->rawMetaObjectForType(to); + enginePrivate->rawMetaObjectForType(to); const QMetaObject *fromMo = from->metaObject(); while (fromMo) { diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h index fefab7a..908c703 100644 --- a/src/declarative/qml/qdeclarativecompiler_p.h +++ b/src/declarative/qml/qdeclarativecompiler_p.h @@ -84,7 +84,6 @@ public: QString name; QUrl url; - QDeclarativeEnginePrivate::Imports imports; QDeclarativeTypeNameCache *importCache; struct TypeReference @@ -192,7 +191,7 @@ private: const BindingContext &); bool buildProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj, const BindingContext &); - bool buildPropertyInNamespace(QDeclarativeEnginePrivate::ImportedNamespace *ns, + bool buildPropertyInNamespace(QDeclarativeImportedNamespace *ns, QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj, const BindingContext &); @@ -336,6 +335,7 @@ private: QList<QDeclarativeError> exceptions; QDeclarativeCompiledData *output; QDeclarativeEngine *engine; + QDeclarativeEnginePrivate *enginePrivate; QDeclarativeParser::Object *unitRoot; QDeclarativeCompositeTypeData *unit; }; diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index d8bbb70..afdaee8 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -59,11 +59,11 @@ #include <QFileInfo> #include <QtCore/qdebug.h> #include <QApplication> +#include <QGraphicsObject> QT_BEGIN_NAMESPACE class QByteArray; -int statusId = qRegisterMetaType<QDeclarativeComponent::Status>("QDeclarativeComponent::Status"); /*! \class QDeclarativeComponent @@ -242,10 +242,10 @@ QDeclarativeComponent::~QDeclarativeComponent() \qmlproperty enumeration Component::status This property holds the status of component loading. It can be one of: \list - \o Null - no data is available for the component - \o Ready - the component has been loaded, and can be used to create instances. - \o Loading - the component is currently being loaded - \o Error - an error occurred while loading the component. + \o Component.Null - no data is available for the component + \o Component.Ready - the component has been loaded, and can be used to create instances. + \o Component.Loading - the component is currently being loaded + \o Component.Error - an error occurred while loading the component. Calling errorsString() will provide a human-readable description of any errors. \endlist */ @@ -269,19 +269,7 @@ QDeclarativeComponent::Status QDeclarativeComponent::status() const } /*! - \qmlproperty bool Component::isNull - - Is true if the component is in the Null state, false otherwise. - - Equivalent to status == Component.Null. -*/ - -/*! - \property QDeclarativeComponent::isNull - - Is true if the component is in the Null state, false otherwise. - - Equivalent to status() == QDeclarativeComponent::Null. + Returns true if status() == QDeclarativeComponent::Null. */ bool QDeclarativeComponent::isNull() const { @@ -289,19 +277,7 @@ bool QDeclarativeComponent::isNull() const } /*! - \qmlproperty bool Component::isReady - - Is true if the component is in the Ready state, false otherwise. - - Equivalent to status == Component.Ready. -*/ - -/*! - \property QDeclarativeComponent::isReady - - Is true if the component is in the Ready state, false otherwise. - - Equivalent to status() == QDeclarativeComponent::Ready. + Returns true if status() == QDeclarativeComponent::Ready. */ bool QDeclarativeComponent::isReady() const { @@ -309,21 +285,7 @@ bool QDeclarativeComponent::isReady() const } /*! - \qmlproperty bool Component::isError - - Is true if the component is in the Error state, false otherwise. - - Equivalent to status == Component.Error. - - Calling errorsString() will provide a human-readable description of any errors. -*/ - -/*! - \property QDeclarativeComponent::isError - - Is true if the component is in the Error state, false otherwise. - - Equivalent to status() == QDeclarativeComponent::Error. + Returns true if status() == QDeclarativeComponent::Error. */ bool QDeclarativeComponent::isError() const { @@ -331,19 +293,7 @@ bool QDeclarativeComponent::isError() const } /*! - \qmlproperty bool Component::isLoading - - Is true if the component is in the Loading state, false otherwise. - - Equivalent to status == Component::Loading. -*/ - -/*! - \property QDeclarativeComponent::isLoading - - Is true if the component is in the Loading state, false otherwise. - - Equivalent to status() == QDeclarativeComponent::Loading. + Returns true if status() == QDeclarativeComponent::Loading. */ bool QDeclarativeComponent::isLoading() const { @@ -421,7 +371,7 @@ QDeclarativeComponent::QDeclarativeComponent(QDeclarativeEngine *engine, const Q { Q_D(QDeclarativeComponent); d->engine = engine; - loadUrl(QUrl::fromLocalFile(fileName)); + loadUrl(d->engine->baseUrl().resolved(QUrl::fromLocalFile(fileName))); } /*! @@ -598,14 +548,21 @@ QDeclarativeComponent::QDeclarativeComponent(QDeclarativeComponentPrivate &dd, Q \qmlmethod object Component::createObject() Returns an object instance from this component, or null if object creation fails. - The object will be created in the same context as the component was created in. + The object will be created in the same context as the one in which the component + was created. + + Note that if the returned object is to be displayed, its \c parent must be set to + an existing item in a scene, or else the object will not be visible. */ /*! \internal A version of create which returns a scriptObject, for use in script + + Sets graphics object parent because forgetting to do this is a frequent + and serious problem. */ -QScriptValue QDeclarativeComponent::createObject() +QScriptValue QDeclarativeComponent::createObject(QObject* parent) { Q_D(QDeclarativeComponent); QDeclarativeContext* ctxt = creationContext(); @@ -614,6 +571,20 @@ QScriptValue QDeclarativeComponent::createObject() QObject* ret = create(ctxt); if (!ret) return QScriptValue(QScriptValue::NullValue); + + QGraphicsObject* gobj = qobject_cast<QGraphicsObject*>(ret); + bool needParent = (gobj != 0); + if(parent){ + ret->setParent(parent); + QGraphicsObject* gparent = qobject_cast<QGraphicsObject*>(parent); + if(gparent){ + gobj->setParentItem(gparent); + needParent = false; + } + } + if(needParent) + qWarning("QDeclarativeComponent: Created graphical object was not placed in the graphics scene."); + QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(d->engine); QDeclarativeData::get(ret, true)->setImplicitDestructible(); return priv->objectClass->newQObject(ret, QMetaType::QObjectStar); @@ -754,6 +725,7 @@ QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *ctxt, QDe state->bindValues = enginePriv->bindValues; state->parserStatus = enginePriv->parserStatus; + state->finalizedParserStatus = enginePriv->finalizedParserStatus; state->componentAttached = enginePriv->componentAttached; if (state->componentAttached) state->componentAttached->prev = &state->componentAttached; @@ -761,6 +733,7 @@ QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *ctxt, QDe enginePriv->componentAttached = 0; enginePriv->bindValues.clear(); enginePriv->parserStatus.clear(); + enginePriv->finalizedParserStatus.clear(); state->completePending = true; enginePriv->inProgressCreations++; } @@ -785,6 +758,7 @@ void QDeclarativeComponentPrivate::beginDeferred(QDeclarativeEnginePrivate *engi state->bindValues = enginePriv->bindValues; state->parserStatus = enginePriv->parserStatus; + state->finalizedParserStatus = enginePriv->finalizedParserStatus; state->componentAttached = enginePriv->componentAttached; if (state->componentAttached) state->componentAttached->prev = &state->componentAttached; @@ -792,6 +766,7 @@ void QDeclarativeComponentPrivate::beginDeferred(QDeclarativeEnginePrivate *engi enginePriv->componentAttached = 0; enginePriv->bindValues.clear(); enginePriv->parserStatus.clear(); + enginePriv->finalizedParserStatus.clear(); state->completePending = true; enginePriv->inProgressCreations++; } @@ -826,6 +801,16 @@ void QDeclarativeComponentPrivate::complete(QDeclarativeEnginePrivate *enginePri QDeclarativeEnginePrivate::clear(ps); } + for (int ii = 0; ii < state->finalizedParserStatus.count(); ++ii) { + QPair<QDeclarativeGuard<QObject>, int> status = state->finalizedParserStatus.at(ii); + QObject *obj = status.first; + if (obj) { + void *args[] = { 0 }; + QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod, + status.second, args); + } + } + while (state->componentAttached) { QDeclarativeComponentAttached *a = state->componentAttached; a->rem(); @@ -838,6 +823,7 @@ void QDeclarativeComponentPrivate::complete(QDeclarativeEnginePrivate *enginePri state->bindValues.clear(); state->parserStatus.clear(); + state->finalizedParserStatus.clear(); state->completePending = false; enginePriv->inProgressCreations--; diff --git a/src/declarative/qml/qdeclarativecomponent.h b/src/declarative/qml/qdeclarativecomponent.h index f3cfe3c..688e233 100644 --- a/src/declarative/qml/qdeclarativecomponent.h +++ b/src/declarative/qml/qdeclarativecomponent.h @@ -64,10 +64,7 @@ class Q_DECLARATIVE_EXPORT QDeclarativeComponent : public QObject { Q_OBJECT Q_DECLARE_PRIVATE(QDeclarativeComponent) - Q_PROPERTY(bool isNull READ isNull NOTIFY statusChanged) - Q_PROPERTY(bool isReady READ isReady NOTIFY statusChanged) - Q_PROPERTY(bool isError READ isError NOTIFY statusChanged) - Q_PROPERTY(bool isLoading READ isLoading NOTIFY statusChanged) + Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged) Q_PROPERTY(Status status READ status NOTIFY statusChanged) Q_PROPERTY(QUrl url READ url CONSTANT) @@ -112,7 +109,7 @@ Q_SIGNALS: protected: QDeclarativeComponent(QDeclarativeComponentPrivate &dd, QObject* parent); - Q_INVOKABLE QScriptValue createObject(); + Q_INVOKABLE QScriptValue createObject(QObject* parent); private: QDeclarativeComponent(QDeclarativeEngine *, QDeclarativeCompiledData *, int, int, QObject *parent); diff --git a/src/declarative/qml/qdeclarativecomponent_p.h b/src/declarative/qml/qdeclarativecomponent_p.h index 8b95945..2a7d633 100644 --- a/src/declarative/qml/qdeclarativecomponent_p.h +++ b/src/declarative/qml/qdeclarativecomponent_p.h @@ -102,6 +102,7 @@ public: ConstructionState() : componentAttached(0), completePending(false) {} QList<QDeclarativeEnginePrivate::SimpleList<QDeclarativeAbstractBinding> > bindValues; QList<QDeclarativeEnginePrivate::SimpleList<QDeclarativeParserStatus> > parserStatus; + QList<QPair<QDeclarativeGuard<QObject>, int> > finalizedParserStatus; QDeclarativeComponentAttached *componentAttached; QList<QDeclarativeError> errors; bool completePending; diff --git a/src/declarative/qml/qdeclarativecompositetypedata_p.h b/src/declarative/qml/qdeclarativecompositetypedata_p.h index 47cb3b3..a0e4cc2 100644 --- a/src/declarative/qml/qdeclarativecompositetypedata_p.h +++ b/src/declarative/qml/qdeclarativecompositetypedata_p.h @@ -83,7 +83,7 @@ public: QList<QDeclarativeError> errors; - QDeclarativeEnginePrivate::Imports imports; + QDeclarativeImports imports; QList<QDeclarativeCompositeTypeData *> dependants; diff --git a/src/declarative/qml/qdeclarativecompositetypemanager.cpp b/src/declarative/qml/qdeclarativecompositetypemanager.cpp index 625356c..b43b4d0 100644 --- a/src/declarative/qml/qdeclarativecompositetypemanager.cpp +++ b/src/declarative/qml/qdeclarativecompositetypemanager.cpp @@ -530,16 +530,15 @@ void QDeclarativeCompositeTypeManager::checkComplete(QDeclarativeCompositeTypeDa 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. - */ + // 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"))))) { @@ -549,14 +548,9 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData qmldircomponentsnetwork = parser.components(); } - QDeclarativeEnginePrivate::get(engine)-> - addToImport(&unit->imports, - qmldircomponentsnetwork, - QLatin1String("."), - QString(), - -1, -1, - QDeclarativeScriptParser::Import::File, - 0); // error ignored (just means no fallback) + importDatabase.addToImport(&unit->imports, qmldircomponentsnetwork, QLatin1String("."), + QString(), -1, -1, QDeclarativeScriptParser::Import::File, + 0); // error ignored (just means no fallback) } @@ -593,9 +587,8 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData } QString errorString; - if (!QDeclarativeEnginePrivate::get(engine)-> - addToImport(&unit->imports, qmldircomponentsnetwork, imp.uri, imp.qualifier, vmaj, vmin, imp.type, &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); @@ -621,11 +614,10 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData QUrl url; int majorVersion; int minorVersion; - QDeclarativeEnginePrivate::ImportedNamespace *typeNamespace = 0; + QDeclarativeImportedNamespace *typeNamespace = 0; QString errorString; - if (!QDeclarativeEnginePrivate::get(engine)->resolveType(unit->imports, typeName, &ref.type, &url, &majorVersion, &minorVersion, &typeNamespace, &errorString) - || typeNamespace) - { + 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 {}) diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index ae4223e..b61b8cb 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -528,13 +528,8 @@ void QDeclarativeContextData::invalidate() parent = 0; } -void QDeclarativeContextData::destroy() +void QDeclarativeContextData::clearExpressions() { - if (linkedContext) - linkedContext->destroy(); - - if (engine) invalidate(); - QDeclarativeAbstractExpression *expression = expressions; while (expression) { QDeclarativeAbstractExpression *nextExpression = expression->m_nextExpression; @@ -546,6 +541,16 @@ void QDeclarativeContextData::destroy() expression = nextExpression; } expressions = 0; +} + +void QDeclarativeContextData::destroy() +{ + if (linkedContext) + linkedContext->destroy(); + + if (engine) invalidate(); + + clearExpressions(); while (contextObjects) { QDeclarativeData *co = contextObjects; diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h index c7fb099..6b6cd0a 100644 --- a/src/declarative/qml/qdeclarativecontext_p.h +++ b/src/declarative/qml/qdeclarativecontext_p.h @@ -113,6 +113,7 @@ class QDeclarativeContextData public: QDeclarativeContextData(); QDeclarativeContextData(QDeclarativeContext *); + void clearExpressions(); void destroy(); void invalidate(); diff --git a/src/declarative/qml/qdeclarativedata_p.h b/src/declarative/qml/qdeclarativedata_p.h index 4a56536..e916273 100644 --- a/src/declarative/qml/qdeclarativedata_p.h +++ b/src/declarative/qml/qdeclarativedata_p.h @@ -152,11 +152,11 @@ public: template<class T> void QDeclarativeGuard<T>::addGuard() { - if (QObjectPrivate::get(o)->wasDeleted) { - if (prev) remGuard(); + Q_ASSERT(!prev); + + if (QObjectPrivate::get(o)->wasDeleted) return; - } - + QDeclarativeData *data = QDeclarativeData::get(o, true); next = data->guards; if (next) reinterpret_cast<QDeclarativeGuard<T> *>(next)->prev = &next; @@ -167,6 +167,8 @@ void QDeclarativeGuard<T>::addGuard() template<class T> void QDeclarativeGuard<T>::remGuard() { + Q_ASSERT(prev); + if (next) reinterpret_cast<QDeclarativeGuard<T> *>(next)->prev = prev; *prev = next; next = 0; diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 1387432..9f5cafe 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -82,6 +82,7 @@ #include <QStack> #include <QMap> #include <QPluginLoader> +#include <QtGui/qfontdatabase.h> #include <QtCore/qlibraryinfo.h> #include <QtCore/qthreadstorage.h> #include <QtCore/qthread.h> @@ -111,9 +112,6 @@ Q_DECLARE_METATYPE(QDeclarativeProperty) QT_BEGIN_NAMESPACE -DEFINE_BOOL_CONFIG_OPTION(qmlImportTrace, QML_IMPORT_TRACE) -DEFINE_BOOL_CONFIG_OPTION(qmlCheckTypes, QML_CHECK_TYPES) - /*! \qmlclass QtObject QObject \since 4.7 @@ -158,7 +156,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), uniqueId(1) + typeManager(e), importDatabase(e), uniqueId(1) { if (!qt_QmlQtModule_registered) { qt_QmlQtModule_registered = true; @@ -168,27 +166,6 @@ QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e) QDeclarativeValueTypeFactory::registerValueTypes(); } globalClass = new QDeclarativeGlobalScriptClass(&scriptEngine); - - // env import paths - QByteArray envImportPath = qgetenv("QML_IMPORT_PATH"); - if (!envImportPath.isEmpty()) { -#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) - QLatin1Char pathSep(';'); -#else - QLatin1Char pathSep(':'); -#endif - foreach (const QString &path, QString::fromLatin1(envImportPath).split(pathSep, QString::SkipEmptyParts)) { - QString canonicalPath = QDir(path).canonicalPath(); - if (!canonicalPath.isEmpty() && !fileImportPath.contains(canonicalPath)) - fileImportPath.append(canonicalPath); - } - } - QString builtinPath = QLibraryInfo::location(QLibraryInfo::ImportsPath); - if (!builtinPath.isEmpty()) - fileImportPath += builtinPath; - - filePluginPath += QLatin1String("."); - } QUrl QDeclarativeScriptEngine::resolvedUrl(QScriptContext *context, const QUrl& url) @@ -249,6 +226,7 @@ QDeclarativeScriptEngine::QDeclarativeScriptEngine(QDeclarativeEnginePrivate *pr //misc methods qtObject.setProperty(QLatin1String("openUrlExternally"),newFunction(QDeclarativeEnginePrivate::desktopOpenUrl, 1)); + qtObject.setProperty(QLatin1String("fontFamilies"),newFunction(QDeclarativeEnginePrivate::fontFamilies, 0)); qtObject.setProperty(QLatin1String("md5"),newFunction(QDeclarativeEnginePrivate::md5, 1)); qtObject.setProperty(QLatin1String("btoa"),newFunction(QDeclarativeEnginePrivate::btoa, 1)); qtObject.setProperty(QLatin1String("atob"),newFunction(QDeclarativeEnginePrivate::atob, 1)); @@ -345,17 +323,16 @@ void QDeclarativeEnginePrivate::clear(SimpleList<QDeclarativeParserStatus> &pss) } Q_GLOBAL_STATIC(QDeclarativeEngineDebugServer, qmlEngineDebugServer); -typedef QMap<QString, QString> StringStringMap; -Q_GLOBAL_STATIC(StringStringMap, qmlEnginePluginsWithRegisteredTypes); // stores the uri - void QDeclarativePrivate::qdeclarativeelement_destructor(QObject *o) { QObjectPrivate *p = QObjectPrivate::get(o); Q_ASSERT(p->declarativeData); QDeclarativeData *d = static_cast<QDeclarativeData*>(p->declarativeData); - if (d->ownContext) + if (d->ownContext && d->context) { d->context->destroy(); + d->context = 0; + } } void QDeclarativeData::destroyed(QAbstractDeclarativeData *d, QObject *o) @@ -374,6 +351,7 @@ void QDeclarativeEnginePrivate::init() qRegisterMetaType<QVariant>("QVariant"); qRegisterMetaType<QDeclarativeScriptString>("QDeclarativeScriptString"); qRegisterMetaType<QScriptValue>("QScriptValue"); + qRegisterMetaType<QDeclarativeComponent::Status>("QDeclarativeComponent::Status"); QDeclarativeData::init(); @@ -456,7 +434,11 @@ QDeclarativeEngine::~QDeclarativeEngine() } /*! \fn void QDeclarativeEngine::quit() - This signal is emitted when the QDeclarativeEngine quits. + This signal is emitted when the QDeclarativeEngine quits. + */ + +/*! \fn void QDeclarativeEngine::warnings(const QList<QDeclarativeError> &warnings) + This signal is emitted when \a warnings messages are generated by QML. */ /*! @@ -892,14 +874,10 @@ void QDeclarativeData::destroyed(QObject *object) if (ownContext && context) context->destroy(); - QDeclarativeGuard<QObject> *guard = guards; - while (guard) { - QDeclarativeGuard<QObject> *g = guard; - guard = guard->next; - g->o = 0; - g->prev = 0; - g->next = 0; - g->objectDestroyed(object); + while (guards) { + QDeclarativeGuard<QObject> *guard = guards; + *guard = (QObject *)0; + guard->objectDestroyed(object); } if (scriptValue) @@ -986,7 +964,7 @@ QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, QS Q_ASSERT(context); if(ctxt->argumentCount() != 1) { - return ctxt->throwError("Qt.createComponent(): Invalid arguments"); + return ctxt->throwError(QLatin1String("Qt.createComponent(): Invalid arguments")); }else{ QString arg = ctxt->argument(0).toString(); if (arg.isEmpty()) @@ -1006,7 +984,7 @@ QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QS QDeclarativeEngine* activeEngine = activeEnginePriv->q_func(); if(ctxt->argumentCount() < 2 || ctxt->argumentCount() > 3) - return ctxt->throwError("Qt.createQmlObject(): Invalid arguments"); + return ctxt->throwError(QLatin1String("Qt.createQmlObject(): Invalid arguments")); QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt); Q_ASSERT(context); @@ -1026,7 +1004,7 @@ QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QS QObject *parentArg = activeEnginePriv->objectClass->toQObject(ctxt->argument(1)); if(!parentArg) - return ctxt->throwError("Qt.createQmlObject(): Missing parent object"); + return ctxt->throwError(QLatin1String("Qt.createQmlObject(): Missing parent object")); QDeclarativeComponent component(activeEngine); component.setData(qml.toUtf8(), url); @@ -1051,9 +1029,12 @@ QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QS } if (!component.isReady()) - return ctxt->throwError("Qt.createQmlObject(): Component is not ready"); + return ctxt->throwError(QLatin1String("Qt.createQmlObject(): Component is not ready")); - QObject *obj = component.create(context->asQDeclarativeContext()); + QObject *obj = component.beginCreate(context->asQDeclarativeContext()); + if(obj) + QDeclarativeData::get(obj, true)->setImplicitDestructible(); + component.completeCreate(); if(component.isError()) { QList<QDeclarativeError> errors = component.errors(); @@ -1097,18 +1078,18 @@ QScriptValue QDeclarativeEnginePrivate::isQtObject(QScriptContext *ctxt, QScript QScriptValue QDeclarativeEnginePrivate::vector(QScriptContext *ctxt, QScriptEngine *engine) { if(ctxt->argumentCount() != 3) - return ctxt->throwError("Qt.vector(): Invalid arguments"); + return ctxt->throwError(QLatin1String("Qt.vector(): Invalid arguments")); qsreal x = ctxt->argument(0).toNumber(); qsreal y = ctxt->argument(1).toNumber(); qsreal z = ctxt->argument(2).toNumber(); - return engine->newVariant(qVariantFromValue(QVector3D(x, y, z))); + return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(qVariantFromValue(QVector3D(x, y, z))); } QScriptValue QDeclarativeEnginePrivate::formatDate(QScriptContext*ctxt, QScriptEngine*engine) { int argCount = ctxt->argumentCount(); if(argCount == 0 || argCount > 2) - return ctxt->throwError("Qt.formatDate(): Invalid arguments"); + return ctxt->throwError(QLatin1String("Qt.formatDate(): Invalid arguments")); QDate date = ctxt->argument(0).toDateTime().date(); Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate; @@ -1119,7 +1100,7 @@ QScriptValue QDeclarativeEnginePrivate::formatDate(QScriptContext*ctxt, QScriptE } else if (ctxt->argument(1).isNumber()) { enumFormat = Qt::DateFormat(ctxt->argument(1).toUInt32()); } else { - return ctxt->throwError("Qt.formatDate(): Invalid date format"); + return ctxt->throwError(QLatin1String("Qt.formatDate(): Invalid date format")); } } return engine->newVariant(qVariantFromValue(date.toString(enumFormat))); @@ -1129,7 +1110,7 @@ QScriptValue QDeclarativeEnginePrivate::formatTime(QScriptContext*ctxt, QScriptE { int argCount = ctxt->argumentCount(); if(argCount == 0 || argCount > 2) - return ctxt->throwError("Qt.formatTime(): Invalid arguments"); + return ctxt->throwError(QLatin1String("Qt.formatTime(): Invalid arguments")); QTime date = ctxt->argument(0).toDateTime().time(); Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate; @@ -1140,7 +1121,7 @@ QScriptValue QDeclarativeEnginePrivate::formatTime(QScriptContext*ctxt, QScriptE } else if (ctxt->argument(1).isNumber()) { enumFormat = Qt::DateFormat(ctxt->argument(1).toUInt32()); } else { - return ctxt->throwError("Qt.formatTime(): Invalid time format"); + return ctxt->throwError(QLatin1String("Qt.formatTime(): Invalid time format")); } } return engine->newVariant(qVariantFromValue(date.toString(enumFormat))); @@ -1150,7 +1131,7 @@ QScriptValue QDeclarativeEnginePrivate::formatDateTime(QScriptContext*ctxt, QScr { int argCount = ctxt->argumentCount(); if(argCount == 0 || argCount > 2) - return ctxt->throwError("Qt.formatDateTime(): Invalid arguments"); + return ctxt->throwError(QLatin1String("Qt.formatDateTime(): Invalid arguments")); QDateTime date = ctxt->argument(0).toDateTime(); Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate; @@ -1161,7 +1142,7 @@ QScriptValue QDeclarativeEnginePrivate::formatDateTime(QScriptContext*ctxt, QScr } else if (ctxt->argument(1).isNumber()) { enumFormat = Qt::DateFormat(ctxt->argument(1).toUInt32()); } else { - return ctxt->throwError("Qt.formatDateTime(): Invalid datetime format"); + return ctxt->throwError(QLatin1String("Qt.formatDateTime(): Invalid datetime format")); } } return engine->newVariant(qVariantFromValue(date.toString(enumFormat))); @@ -1171,7 +1152,7 @@ QScriptValue QDeclarativeEnginePrivate::rgba(QScriptContext *ctxt, QScriptEngine { int argCount = ctxt->argumentCount(); if(argCount < 3 || argCount > 4) - return ctxt->throwError("Qt.rgba(): Invalid arguments"); + return ctxt->throwError(QLatin1String("Qt.rgba(): Invalid arguments")); qsreal r = ctxt->argument(0).toNumber(); qsreal g = ctxt->argument(1).toNumber(); qsreal b = ctxt->argument(2).toNumber(); @@ -1193,7 +1174,7 @@ QScriptValue QDeclarativeEnginePrivate::hsla(QScriptContext *ctxt, QScriptEngine { int argCount = ctxt->argumentCount(); if(argCount < 3 || argCount > 4) - return ctxt->throwError("Qt.hsla(): Invalid arguments"); + return ctxt->throwError(QLatin1String("Qt.hsla(): Invalid arguments")); qsreal h = ctxt->argument(0).toNumber(); qsreal s = ctxt->argument(1).toNumber(); qsreal l = ctxt->argument(2).toNumber(); @@ -1214,7 +1195,7 @@ QScriptValue QDeclarativeEnginePrivate::hsla(QScriptContext *ctxt, QScriptEngine QScriptValue QDeclarativeEnginePrivate::rect(QScriptContext *ctxt, QScriptEngine *engine) { if(ctxt->argumentCount() != 4) - return ctxt->throwError("Qt.rect(): Invalid arguments"); + return ctxt->throwError(QLatin1String("Qt.rect(): Invalid arguments")); qsreal x = ctxt->argument(0).toNumber(); qsreal y = ctxt->argument(1).toNumber(); @@ -1224,31 +1205,31 @@ QScriptValue QDeclarativeEnginePrivate::rect(QScriptContext *ctxt, QScriptEngine if (w < 0 || h < 0) return engine->nullValue(); - return qScriptValueFromValue(engine, qVariantFromValue(QRectF(x, y, w, h))); + return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(qVariantFromValue(QRectF(x, y, w, h))); } QScriptValue QDeclarativeEnginePrivate::point(QScriptContext *ctxt, QScriptEngine *engine) { if(ctxt->argumentCount() != 2) - return ctxt->throwError("Qt.point(): Invalid arguments"); + return ctxt->throwError(QLatin1String("Qt.point(): Invalid arguments")); qsreal x = ctxt->argument(0).toNumber(); qsreal y = ctxt->argument(1).toNumber(); - return qScriptValueFromValue(engine, qVariantFromValue(QPointF(x, y))); + return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(qVariantFromValue(QPointF(x, y))); } QScriptValue QDeclarativeEnginePrivate::size(QScriptContext *ctxt, QScriptEngine *engine) { if(ctxt->argumentCount() != 2) - return ctxt->throwError("Qt.size(): Invalid arguments"); + return ctxt->throwError(QLatin1String("Qt.size(): Invalid arguments")); qsreal w = ctxt->argument(0).toNumber(); qsreal h = ctxt->argument(1).toNumber(); - return qScriptValueFromValue(engine, qVariantFromValue(QSizeF(w, h))); + return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(qVariantFromValue(QSizeF(w, h))); } QScriptValue QDeclarativeEnginePrivate::lighter(QScriptContext *ctxt, QScriptEngine *engine) { - if(ctxt->argumentCount() != 1) - return ctxt->throwError("Qt.lighter(): Invalid arguments"); + if(ctxt->argumentCount() != 1 && ctxt->argumentCount() != 2) + return ctxt->throwError(QLatin1String("Qt.lighter(): Invalid arguments")); QVariant v = ctxt->argument(0).toVariant(); QColor color; if (v.userType() == QVariant::Color) @@ -1260,14 +1241,17 @@ QScriptValue QDeclarativeEnginePrivate::lighter(QScriptContext *ctxt, QScriptEng return engine->nullValue(); } else return engine->nullValue(); - color = color.lighter(); + qsreal factor = 1.5; + if (ctxt->argumentCount() == 2) + factor = ctxt->argument(1).toNumber(); + color = color.lighter(int(qRound(factor*100.))); return qScriptValueFromValue(engine, qVariantFromValue(color)); } QScriptValue QDeclarativeEnginePrivate::darker(QScriptContext *ctxt, QScriptEngine *engine) { - if(ctxt->argumentCount() != 1) - return ctxt->throwError("Qt.darker(): Invalid arguments"); + if(ctxt->argumentCount() != 1 && ctxt->argumentCount() != 2) + return ctxt->throwError(QLatin1String("Qt.darker(): Invalid arguments")); QVariant v = ctxt->argument(0).toVariant(); QColor color; if (v.userType() == QVariant::Color) @@ -1279,7 +1263,10 @@ QScriptValue QDeclarativeEnginePrivate::darker(QScriptContext *ctxt, QScriptEngi return engine->nullValue(); } else return engine->nullValue(); - color = color.darker(); + qsreal factor = 2.0; + if (ctxt->argumentCount() == 2) + factor = ctxt->argument(1).toNumber(); + color = color.darker(int(qRound(factor*100.))); return qScriptValueFromValue(engine, qVariantFromValue(color)); } @@ -1294,10 +1281,20 @@ QScriptValue QDeclarativeEnginePrivate::desktopOpenUrl(QScriptContext *ctxt, QSc return QScriptValue(e, ret); } +QScriptValue QDeclarativeEnginePrivate::fontFamilies(QScriptContext *ctxt, QScriptEngine *e) +{ + if(ctxt->argumentCount() != 0) + return ctxt->throwError(QLatin1String("Qt.fontFamilies(): Invalid arguments")); + + QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(e); + QFontDatabase database; + return p->scriptValueFromVariant(database.families()); +} + QScriptValue QDeclarativeEnginePrivate::md5(QScriptContext *ctxt, QScriptEngine *) { if (ctxt->argumentCount() != 1) - return ctxt->throwError("Qt.md5(): Invalid arguments"); + return ctxt->throwError(QLatin1String("Qt.md5(): Invalid arguments")); QByteArray data = ctxt->argument(0).toString().toUtf8(); QByteArray result = QCryptographicHash::hash(data, QCryptographicHash::Md5); @@ -1308,7 +1305,7 @@ QScriptValue QDeclarativeEnginePrivate::md5(QScriptContext *ctxt, QScriptEngine QScriptValue QDeclarativeEnginePrivate::btoa(QScriptContext *ctxt, QScriptEngine *) { if (ctxt->argumentCount() != 1) - return ctxt->throwError("Qt.btoa(): Invalid arguments"); + return ctxt->throwError(QLatin1String("Qt.btoa(): Invalid arguments")); QByteArray data = ctxt->argument(0).toString().toUtf8(); @@ -1318,7 +1315,7 @@ QScriptValue QDeclarativeEnginePrivate::btoa(QScriptContext *ctxt, QScriptEngine QScriptValue QDeclarativeEnginePrivate::atob(QScriptContext *ctxt, QScriptEngine *) { if (ctxt->argumentCount() != 1) - return ctxt->throwError("Qt.atob(): Invalid arguments"); + return ctxt->throwError(QLatin1String("Qt.atob(): Invalid arguments")); QByteArray data = ctxt->argument(0).toString().toUtf8(); @@ -1419,7 +1416,7 @@ QScriptValue QDeclarativeEnginePrivate::quit(QScriptContext * /*ctxt*/, QScriptE QScriptValue QDeclarativeEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine *engine) { if(ctxt->argumentCount() != 2) - return ctxt->throwError("Qt.tint(): Invalid arguments"); + return ctxt->throwError(QLatin1String("Qt.tint(): Invalid arguments")); //get color QVariant v = ctxt->argument(0).toVariant(); QColor color; @@ -1522,516 +1519,6 @@ QVariant QDeclarativeEnginePrivate::scriptValueToVariant(const QScriptValue &val return val.toVariant(); } -// XXX this beyonds in QUrl::toLocalFile() -// WARNING, there is a copy of this function in qdeclarativecompositetypemanager.cpp -static QString toLocalFileOrQrc(const QUrl& url) -{ - if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0) { - if (url.authority().isEmpty()) - return QLatin1Char(':') + url.path(); - return QString(); - } - return url.toLocalFile(); -} - -///////////////////////////////////////////////////////////// -struct QDeclarativeEnginePrivate::ImportedNamespace { - QStringList uris; - QStringList urls; - QList<int> majversions; - QList<int> minversions; - QList<bool> isLibrary; - QList<QDeclarativeDirComponents> qmlDirComponents; - - - bool find_helper(int i, const QByteArray& type, int *vmajor, int *vminor, - QDeclarativeType** type_return, QUrl* url_return, - QUrl *base = 0, bool *typeRecursionDetected = 0) - { - int vmaj = majversions.at(i); - int vmin = minversions.at(i); - - QByteArray qt = uris.at(i).toUtf8(); - qt += '/'; - qt += type; - - QDeclarativeType *t = QDeclarativeMetaType::qmlType(qt,vmaj,vmin); - if (t) { - if (vmajor) *vmajor = vmaj; - if (vminor) *vminor = vmin; - if (type_return) - *type_return = t; - return true; - } - - QUrl url = QUrl(urls.at(i) + QLatin1Char('/') + QString::fromUtf8(type) + QLatin1String(".qml")); - QDeclarativeDirComponents qmldircomponents = qmlDirComponents.at(i); - - bool typeWasDeclaredInQmldir = false; - if (!qmldircomponents.isEmpty()) { - const QString typeName = QString::fromUtf8(type); - foreach (const QDeclarativeDirParser::Component &c, qmldircomponents) { - if (c.typeName == typeName) { - typeWasDeclaredInQmldir = true; - - // importing version -1 means import ALL versions - if ((vmaj == -1) || (c.majorVersion < vmaj || (c.majorVersion == vmaj && vmin >= c.minorVersion))) { - QUrl candidate = url.resolved(QUrl(c.fileName)); - if (c.internal && base) { - if (base->resolved(QUrl(c.fileName)) != candidate) - continue; // failed attempt to access an internal type - } - if (base && *base == candidate) { - if (typeRecursionDetected) - *typeRecursionDetected = true; - continue; // no recursion - } - if (url_return) - *url_return = candidate; - return true; - } - } - } - } - - if (!typeWasDeclaredInQmldir && !isLibrary.at(i)) { - // XXX search non-files too! (eg. zip files, see QT-524) - QFileInfo f(toLocalFileOrQrc(url)); - if (f.exists()) { - if (base && *base == url) { // no recursion - if (typeRecursionDetected) - *typeRecursionDetected = true; - } else { - if (url_return) - *url_return = url; - return true; - } - } - } - return false; - } - - bool find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, - QUrl* url_return, QUrl *base = 0, QString *errorString = 0) - { - bool typeRecursionDetected = false; - for (int i=0; i<urls.count(); ++i) { - if (find_helper(i, type, vmajor, vminor, type_return, url_return, base, &typeRecursionDetected)) { - if (qmlCheckTypes()) { - // check for type clashes - for (int j = i+1; j<urls.count(); ++j) { - if (find_helper(j, type, vmajor, vminor, 0, 0, base)) { - if (errorString) { - QString u1 = urls.at(i); - QString u2 = urls.at(j); - if (base) { - QString b = base->toString(); - int slash = b.lastIndexOf(QLatin1Char('/')); - if (slash >= 0) { - b = b.left(slash+1); - QString l = b.left(slash); - if (u1.startsWith(b)) - u1 = u1.mid(b.count()); - else if (u1 == l) - u1 = QDeclarativeEngine::tr("local directory"); - if (u2.startsWith(b)) - u2 = u2.mid(b.count()); - else if (u2 == l) - u2 = QDeclarativeEngine::tr("local directory"); - } - } - - if (u1 != u2) - *errorString - = QDeclarativeEngine::tr("is ambiguous. Found in %1 and in %2") - .arg(u1).arg(u2); - else - *errorString - = QDeclarativeEngine::tr("is ambiguous. Found in %1 in version %2.%3 and %4.%5") - .arg(u1) - .arg(majversions.at(i)).arg(minversions.at(i)) - .arg(majversions.at(j)).arg(minversions.at(j)); - } - return false; - } - } - } - return true; - } - } - if (errorString) { - if (typeRecursionDetected) - *errorString = QDeclarativeEngine::tr("is instantiated recursively"); - else - *errorString = QDeclarativeEngine::tr("is not a type"); - } - return false; - } -}; - -static bool greaterThan(const QString &s1, const QString &s2) -{ - return s1 > s2; -} - -class QDeclarativeImportsPrivate { -public: - QDeclarativeImportsPrivate() : ref(1) - { - } - - ~QDeclarativeImportsPrivate() - { - foreach (QDeclarativeEnginePrivate::ImportedNamespace* s, set.values()) - delete s; - } - - QSet<QString> qmlDirFilesForWhichPluginsHaveBeenLoaded; - - bool importExtension(const QString &absoluteFilePath, const QString &uri, QDeclarativeEngine *engine, QDeclarativeDirComponents* components, QString *errorString) { - QFile file(absoluteFilePath); - QString filecontent; - if (file.open(QFile::ReadOnly)) { - filecontent = QString::fromUtf8(file.readAll()); - if (qmlImportTrace()) - qDebug() << "QDeclarativeEngine::add: loaded" << absoluteFilePath; - } else { - if (errorString) - *errorString = QDeclarativeEngine::tr("module \"%1\" definition \"%2\" not readable").arg(uri).arg(absoluteFilePath); - return false; - } - QDir dir = QFileInfo(file).dir(); - - QDeclarativeDirParser qmldirParser; - qmldirParser.setSource(filecontent); - qmldirParser.parse(); - - if (! qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(absoluteFilePath)) { - qmlDirFilesForWhichPluginsHaveBeenLoaded.insert(absoluteFilePath); - - - foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser.plugins()) { - - QString resolvedFilePath = - QDeclarativeEnginePrivate::get(engine) - ->resolvePlugin(dir, plugin.path, - plugin.name); - - if (!resolvedFilePath.isEmpty()) { - if (!engine->importPlugin(resolvedFilePath, uri, errorString)) { - if (errorString) - *errorString = QDeclarativeEngine::tr("plugin cannot be loaded for module \"%1\": %2").arg(uri).arg(*errorString); - return false; - } - } else { - if (errorString) - *errorString = QDeclarativeEngine::tr("module \"%1\" plugin \"%2\" not found").arg(uri).arg(plugin.name); - return false; - } - } - } - - if (components) - *components = qmldirParser.components(); - - return true; - } - - QString resolvedUri(const QString &dir_arg, QDeclarativeEngine *engine) - { - QString dir = dir_arg; - if (dir.endsWith(QLatin1Char('/')) || dir.endsWith(QLatin1Char('\\'))) - dir.chop(1); - - QStringList paths = QDeclarativeEnginePrivate::get(engine)->fileImportPath; - qSort(paths.begin(), paths.end(), greaterThan); // Ensure subdirs preceed their parents. - - QString stableRelativePath = dir; - foreach( QString path, paths) { - if (dir.startsWith(path)) { - stableRelativePath = dir.mid(path.length()+1); - break; - } - } - stableRelativePath.replace(QLatin1Char('/'), QLatin1Char('.')); - stableRelativePath.replace(QLatin1Char('\\'), QLatin1Char('.')); - return stableRelativePath; - } - - - - - bool add(const QUrl& base, const QDeclarativeDirComponents &qmldircomponentsnetwork, const QString& uri_arg, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, QDeclarativeEngine *engine, QString *errorString) - { - QDeclarativeDirComponents qmldircomponents = qmldircomponentsnetwork; - QString uri = uri_arg; - QDeclarativeEnginePrivate::ImportedNamespace *s; - if (prefix.isEmpty()) { - s = &unqualifiedset; - } else { - s = set.value(prefix); - if (!s) - set.insert(prefix,(s=new QDeclarativeEnginePrivate::ImportedNamespace)); - } - - - - QString url = uri; - if (importType == QDeclarativeScriptParser::Import::Library) { - url.replace(QLatin1Char('.'), QLatin1Char('/')); - bool found = false; - QString dir; - - - foreach (const QString &p, - QDeclarativeEnginePrivate::get(engine)->fileImportPath) { - dir = p+QLatin1Char('/')+url; - - QFileInfo fi(dir+QLatin1String("/qmldir")); - const QString absoluteFilePath = fi.absoluteFilePath(); - - if (fi.isFile()) { - found = true; - - url = QUrl::fromLocalFile(fi.absolutePath()).toString(); - uri = resolvedUri(dir, engine); - if (!importExtension(absoluteFilePath, uri, engine, &qmldircomponents, errorString)) - return false; - break; - } - } - - if (!found) { - found = QDeclarativeMetaType::isModule(uri.toUtf8(), vmaj, vmin); - if (!found) { - if (errorString) { - bool anyversion = QDeclarativeMetaType::isModule(uri.toUtf8(), -1, -1); - if (anyversion) - *errorString = QDeclarativeEngine::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin); - else - *errorString = QDeclarativeEngine::tr("module \"%1\" is not installed").arg(uri_arg); - } - return false; - } - } - } else { - - if (importType == QDeclarativeScriptParser::Import::File && qmldircomponents.isEmpty()) { - QUrl importUrl = base.resolved(QUrl(uri + QLatin1String("/qmldir"))); - QString localFileOrQrc = toLocalFileOrQrc(importUrl); - if (!localFileOrQrc.isEmpty()) { - QString dir = toLocalFileOrQrc(base.resolved(QUrl(uri))); - if (dir.isEmpty() || !QDir().exists(dir)) { - if (errorString) - *errorString = QDeclarativeEngine::tr("\"%1\": no such directory").arg(uri_arg); - return false; // local import dirs must exist - } - uri = resolvedUri(toLocalFileOrQrc(base.resolved(QUrl(uri))), engine); - if (uri.endsWith(QLatin1Char('/'))) - uri.chop(1); - if (QFile::exists(localFileOrQrc)) { - if (!importExtension(localFileOrQrc,uri,engine,&qmldircomponents,errorString)) - return false; - } - } else { - if (prefix.isEmpty()) { - // directory must at least exist for valid import - QString localFileOrQrc = toLocalFileOrQrc(base.resolved(QUrl(uri))); - if (localFileOrQrc.isEmpty() || !QDir().exists(localFileOrQrc)) { - if (errorString) { - if (localFileOrQrc.isEmpty()) - *errorString = QDeclarativeEngine::tr("import \"%1\" has no qmldir and no namespace").arg(uri); - else - *errorString = QDeclarativeEngine::tr("\"%1\": no such directory").arg(uri); - } - return false; - } - } - } - } - - url = base.resolved(QUrl(url)).toString(); - if (url.endsWith(QLatin1Char('/'))) - url.chop(1); - } - - if (vmaj > -1 && vmin > -1 && !qmldircomponents.isEmpty()) { - QList<QDeclarativeDirParser::Component>::ConstIterator it = qmldircomponents.begin(); - for (; it != qmldircomponents.end(); ++it) { - if (it->majorVersion > vmaj || (it->majorVersion == vmaj && it->minorVersion >= vmin)) - break; - } - if (it == qmldircomponents.end()) { - *errorString = QDeclarativeEngine::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin); - return false; - } - } - - s->uris.prepend(uri); - s->urls.prepend(url); - s->majversions.prepend(vmaj); - s->minversions.prepend(vmin); - s->isLibrary.prepend(importType == QDeclarativeScriptParser::Import::Library); - s->qmlDirComponents.prepend(qmldircomponents); - return true; - } - - bool find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, - QUrl* url_return, QString *errorString) - { - QDeclarativeEnginePrivate::ImportedNamespace *s = 0; - int slash = type.indexOf('/'); - if (slash >= 0) { - QString namespaceName = QString::fromUtf8(type.left(slash)); - s = set.value(namespaceName); - if (!s) { - if (errorString) - *errorString = QDeclarativeEngine::tr("- %1 is not a namespace").arg(namespaceName); - return false; - } - int nslash = type.indexOf('/',slash+1); - if (nslash > 0) { - if (errorString) - *errorString = QDeclarativeEngine::tr("- nested namespaces not allowed"); - return false; - } - } else { - s = &unqualifiedset; - } - QByteArray unqualifiedtype = slash < 0 ? type : type.mid(slash+1); // common-case opt (QString::mid works fine, but slower) - if (s) { - if (s->find(unqualifiedtype,vmajor,vminor,type_return,url_return, &base, errorString)) - return true; - if (s->urls.count() == 1 && !s->isLibrary[0] && url_return && s != &unqualifiedset) { - // qualified, and only 1 url - *url_return = QUrl(s->urls[0]+QLatin1Char('/')).resolved(QUrl(QString::fromUtf8(unqualifiedtype) + QLatin1String(".qml"))); - return true; - } - } - - return false; - } - - QDeclarativeEnginePrivate::ImportedNamespace *findNamespace(const QString& type) - { - return set.value(type); - } - - QUrl base; - int ref; - -private: - friend struct QDeclarativeEnginePrivate::Imports; - QDeclarativeEnginePrivate::ImportedNamespace unqualifiedset; - QHash<QString,QDeclarativeEnginePrivate::ImportedNamespace* > set; -}; - -QDeclarativeEnginePrivate::Imports::Imports(const Imports ©) : - d(copy.d) -{ - ++d->ref; -} - -QDeclarativeEnginePrivate::Imports &QDeclarativeEnginePrivate::Imports::operator =(const Imports ©) -{ - ++copy.d->ref; - if (--d->ref == 0) - delete d; - d = copy.d; - return *this; -} - -QDeclarativeEnginePrivate::Imports::Imports() : - d(new QDeclarativeImportsPrivate) -{ -} - -QDeclarativeEnginePrivate::Imports::~Imports() -{ - if (--d->ref == 0) - delete d; -} - -static QDeclarativeTypeNameCache *cacheForNamespace(QDeclarativeEngine *engine, const QDeclarativeEnginePrivate::ImportedNamespace &set, QDeclarativeTypeNameCache *cache) -{ - if (!cache) - cache = new QDeclarativeTypeNameCache(engine); - - QList<QDeclarativeType *> types = QDeclarativeMetaType::qmlTypes(); - - for (int ii = 0; ii < set.uris.count(); ++ii) { - QByteArray base = set.uris.at(ii).toUtf8() + '/'; - int major = set.majversions.at(ii); - int minor = set.minversions.at(ii); - - foreach (QDeclarativeType *type, types) { - if (type->qmlTypeName().startsWith(base) && - type->qmlTypeName().lastIndexOf('/') == (base.length() - 1) && - type->availableInVersion(major,minor)) - { - QString name = QString::fromUtf8(type->qmlTypeName().mid(base.length())); - - cache->add(name, type); - } - } - } - - return cache; -} - -void QDeclarativeEnginePrivate::Imports::cache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *engine) const -{ - const QDeclarativeEnginePrivate::ImportedNamespace &set = d->unqualifiedset; - - for (QHash<QString,QDeclarativeEnginePrivate::ImportedNamespace* >::ConstIterator iter = d->set.begin(); - iter != d->set.end(); ++iter) { - - QDeclarativeTypeNameCache::Data *d = cache->data(iter.key()); - if (d) { - if (!d->typeNamespace) - cacheForNamespace(engine, *(*iter), d->typeNamespace); - } else { - QDeclarativeTypeNameCache *nc = cacheForNamespace(engine, *(*iter), 0); - cache->add(iter.key(), nc); - nc->release(); - } - } - - cacheForNamespace(engine, set, cache); -} - -/* -QStringList QDeclarativeEnginePrivate::Imports::unqualifiedSet() const -{ - QStringList rv; - - const QDeclarativeEnginePrivate::ImportedNamespace &set = d->unqualifiedset; - - for (int ii = 0; ii < set.urls.count(); ++ii) { - if (set.isBuiltin.at(ii)) - rv << set.urls.at(ii); - } - - return rv; -} -*/ - -/*! - Sets the base URL to be used for all relative file imports added. -*/ -void QDeclarativeEnginePrivate::Imports::setBaseUrl(const QUrl& url) -{ - d->base = url; -} - -/*! - Returns the base URL to be used for all relative file imports added. -*/ -QUrl QDeclarativeEnginePrivate::Imports::baseUrl() const -{ - return d->base; -} - /*! Adds \a path as a directory where the engine searches for installed modules in a URL-based directory structure. @@ -2042,19 +1529,10 @@ QUrl QDeclarativeEnginePrivate::Imports::baseUrl() const */ void QDeclarativeEngine::addImportPath(const QString& path) { - if (qmlImportTrace()) - qDebug() << "QDeclarativeEngine::addImportPath" << path; Q_D(QDeclarativeEngine); - QUrl url = QUrl(path); - if (url.isRelative() || url.scheme() == QString::fromLocal8Bit("file")) { - QDir dir = QDir(path); - d->fileImportPath.prepend(dir.canonicalPath()); - } else { - d->fileImportPath.prepend(path); - } + d->importDatabase.addImportPath(path); } - /*! Returns the list of directories where the engine searches for installed modules in a URL-based directory structure. @@ -2073,11 +1551,11 @@ void QDeclarativeEngine::addImportPath(const QString& path) QStringList QDeclarativeEngine::importPathList() const { Q_D(const QDeclarativeEngine); - return d->fileImportPath; + return d->importDatabase.importPathList(); } /*! - Sets the list of directories where the engine searches for + Sets \a paths as the list of directories where the engine searches for installed modules in a URL-based directory structure. By default, the list contains the paths specified in the \c QML_IMPORT_PATH environment @@ -2088,7 +1566,7 @@ QStringList QDeclarativeEngine::importPathList() const void QDeclarativeEngine::setImportPathList(const QStringList &paths) { Q_D(QDeclarativeEngine); - d->fileImportPath = paths; + d->importDatabase.setImportPathList(paths); } @@ -2105,16 +1583,8 @@ void QDeclarativeEngine::setImportPathList(const QStringList &paths) */ void QDeclarativeEngine::addPluginPath(const QString& path) { - if (qmlImportTrace()) - qDebug() << "QDeclarativeEngine::addPluginPath" << path; Q_D(QDeclarativeEngine); - QUrl url = QUrl(path); - if (url.isRelative() || url.scheme() == QString::fromLocal8Bit("file")) { - QDir dir = QDir(path); - d->filePluginPath.prepend(dir.canonicalPath()); - } else { - d->filePluginPath.prepend(path); - } + d->importDatabase.addPluginPath(path); } @@ -2130,7 +1600,7 @@ void QDeclarativeEngine::addPluginPath(const QString& path) QStringList QDeclarativeEngine::pluginPathList() const { Q_D(const QDeclarativeEngine); - return d->filePluginPath; + return d->importDatabase.pluginPathList(); } /*! @@ -2146,7 +1616,7 @@ QStringList QDeclarativeEngine::pluginPathList() const void QDeclarativeEngine::setPluginPathList(const QStringList &paths) { Q_D(QDeclarativeEngine); - d->filePluginPath = paths; + d->importDatabase.setPluginPathList(paths); } @@ -2160,55 +1630,8 @@ void QDeclarativeEngine::setPluginPathList(const QStringList &paths) */ bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QString *errorString) { - if (qmlImportTrace()) - qDebug() << "QDeclarativeEngine::importPlugin" << uri << "from" << filePath; - QFileInfo fileInfo(filePath); - const QString absoluteFilePath = fileInfo.absoluteFilePath(); - - QDeclarativeEnginePrivate *d = QDeclarativeEnginePrivate::get(this); - bool engineInitialized = d->initializedPlugins.contains(absoluteFilePath); - bool typesRegistered = qmlEnginePluginsWithRegisteredTypes()->contains(absoluteFilePath); - - if (typesRegistered) { - Q_ASSERT_X(qmlEnginePluginsWithRegisteredTypes()->value(absoluteFilePath) == uri, - "QDeclarativeEngine::importExtension", - "Internal error: Plugin imported previously with different uri"); - } - - if (!engineInitialized || !typesRegistered) { - QPluginLoader loader(absoluteFilePath); - - if (!loader.load()) { - if (errorString) - *errorString = loader.errorString(); - return false; - } - - if (QDeclarativeExtensionInterface *iface = qobject_cast<QDeclarativeExtensionInterface *>(loader.instance())) { - - const QByteArray bytes = uri.toUtf8(); - const char *moduleId = bytes.constData(); - if (!typesRegistered) { - - // ### this code should probably be protected with a mutex. - qmlEnginePluginsWithRegisteredTypes()->insert(absoluteFilePath, uri); - iface->registerTypes(moduleId); - } - if (!engineInitialized) { - // things on the engine (eg. adding new global objects) have to be done for every engine. - - // protect against double initialization - d->initializedPlugins.insert(absoluteFilePath); - iface->initializeEngine(this, moduleId); - } - } else { - if (errorString) - *errorString = loader.errorString(); - return false; - } - } - - return true; + Q_D(QDeclarativeEngine); + return d->importDatabase.importPlugin(filePath, uri, errorString); } /*! @@ -2240,208 +1663,6 @@ QString QDeclarativeEngine::offlineStoragePath() const return d->scriptEngine.offlineStoragePath; } -/*! - \internal - - Returns the result of the merge of \a baseName with \a path, \a suffixes, and \a prefix. - The \a prefix must contain the dot. - - \a qmldirPath is the location of the qmldir file. - */ -QString QDeclarativeEnginePrivate::resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath, const QString &baseName, - const QStringList &suffixes, - const QString &prefix) -{ - QStringList searchPaths = filePluginPath; - bool qmldirPluginPathIsRelative = QDir::isRelativePath(qmldirPluginPath); - if (!qmldirPluginPathIsRelative) - searchPaths.prepend(qmldirPluginPath); - - foreach (const QString &pluginPath, searchPaths) { - - QString resolvedPath; - - if (pluginPath == QLatin1String(".")) { - if (qmldirPluginPathIsRelative) - resolvedPath = qmldirPath.absoluteFilePath(qmldirPluginPath); - else - resolvedPath = qmldirPath.absolutePath(); - } else { - resolvedPath = pluginPath; - } - - // hack for resources, should probably go away - if (resolvedPath.startsWith(QLatin1Char(':'))) - resolvedPath = QCoreApplication::applicationDirPath(); - - QDir dir(resolvedPath); - foreach (const QString &suffix, suffixes) { - QString pluginFileName = prefix; - - pluginFileName += baseName; - pluginFileName += suffix; - - QFileInfo fileInfo(dir, pluginFileName); - - if (fileInfo.exists()) - return fileInfo.absoluteFilePath(); - } - } - - if (qmlImportTrace()) - qDebug() << "QDeclarativeEngine::resolvePlugin: Could not resolve plugin" << baseName << "in" << qmldirPath.absolutePath(); - return QString(); -} - -/*! - \internal - - Returns the result of the merge of \a baseName with \a dir and the platform suffix. - - \table - \header \i Platform \i Valid suffixes - \row \i Windows \i \c .dll - \row \i Unix/Linux \i \c .so - \row \i AIX \i \c .a - \row \i HP-UX \i \c .sl, \c .so (HP-UXi) - \row \i Mac OS X \i \c .dylib, \c .bundle, \c .so - \row \i Symbian \i \c .dll - \endtable - - Version number on unix are ignored. -*/ -QString QDeclarativeEnginePrivate::resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath, const QString &baseName) -{ -#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) - return resolvePlugin(qmldirPath, qmldirPluginPath, baseName, - QStringList() -# ifdef QT_DEBUG - << QLatin1String("d.dll") // try a qmake-style debug build first -# endif - << QLatin1String(".dll")); -#elif defined(Q_OS_SYMBIAN) - return resolvePlugin(qmldirPath, qmldirPluginPath, baseName, - QStringList() - << QLatin1String(".dll") - << QLatin1String(".qtplugin")); -#else - -# if defined(Q_OS_DARWIN) - - return resolvePlugin(qmldirPath, qmldirPluginPath, baseName, - QStringList() -# ifdef QT_DEBUG - << QLatin1String("_debug.dylib") // try a qmake-style debug build first - << QLatin1String(".dylib") -# else - << QLatin1String(".dylib") - << QLatin1String("_debug.dylib") // try a qmake-style debug build after -# endif - << QLatin1String(".so") - << QLatin1String(".bundle"), - QLatin1String("lib")); -# else // Generic Unix - QStringList validSuffixList; - -# if defined(Q_OS_HPUX) -/* - See "HP-UX Linker and Libraries User's Guide", section "Link-time Differences between PA-RISC and IPF": - "In PA-RISC (PA-32 and PA-64) shared libraries are suffixed with .sl. In IPF (32-bit and 64-bit), - the shared libraries are suffixed with .so. For compatibility, the IPF linker also supports the .sl suffix." - */ - validSuffixList << QLatin1String(".sl"); -# if defined __ia64 - validSuffixList << QLatin1String(".so"); -# endif -# elif defined(Q_OS_AIX) - validSuffixList << QLatin1String(".a") << QLatin1String(".so"); -# elif defined(Q_OS_UNIX) - validSuffixList << QLatin1String(".so"); -# endif - - // Examples of valid library names: - // libfoo.so - - return resolvePlugin(qmldirPath, qmldirPluginPath, baseName, validSuffixList, QLatin1String("lib")); -# endif - -#endif -} - -/*! - \internal - - Adds information to \a imports such that subsequent calls to resolveType() - will resolve types qualified by \a prefix by considering types found at the given \a uri. - - The uri is either a directory (if importType is FileImport), or a URI resolved using paths - added via addImportPath() (if importType is LibraryImport). - - The \a prefix may be empty, in which case the import location is considered for - unqualified types. - - The base URL must already have been set with Import::setBaseUrl(). -*/ -bool QDeclarativeEnginePrivate::addToImport(Imports* imports, const QDeclarativeDirComponents &qmldircomponentsnetwork, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, QString *errorString) const -{ - QDeclarativeEngine *engine = QDeclarativeEnginePrivate::get(const_cast<QDeclarativeEnginePrivate *>(this)); - if (qmlImportTrace()) - qDebug().nospace() << "QDeclarativeEngine::addToImport " << imports << " " << uri << " " << vmaj << '.' << vmin << " " << (importType==QDeclarativeScriptParser::Import::Library? "Library" : "File") << " as " << prefix; - bool ok = imports->d->add(imports->d->base,qmldircomponentsnetwork, uri,prefix,vmaj,vmin,importType, engine, errorString); - return ok; -} - -/*! - \internal - - Using the given \a imports, the given (namespace qualified) \a type is resolved to either - an ImportedNamespace 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 QDeclarativeEnginePrivate::resolveType(const Imports& imports, const QByteArray& type, QDeclarativeType** type_return, QUrl* url_return, int *vmaj, int *vmin, ImportedNamespace** ns_return, QString *errorString) const -{ - ImportedNamespace* 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() << "QDeclarativeEngine::resolveType" << type << '=' << (*type_return)->typeName() << *url_return; - if (type_return && *type_return) - qDebug() << "QDeclarativeEngine::resolveType" << type << '=' << (*type_return)->typeName(); - if (url_return && !url_return->isEmpty()) - qDebug() << "QDeclarativeEngine::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. -*/ -void QDeclarativeEnginePrivate::resolveTypeInNamespace(ImportedNamespace* ns, const QByteArray& type, QDeclarativeType** type_return, QUrl* url_return, int *vmaj, int *vmin ) const -{ - ns->find(type,vmaj,vmin,type_return,url_return); -} - static void voidptr_destructor(void *v) { void **ptr = (void **)v; diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h index 743275e..531ac97 100644 --- a/src/declarative/qml/qdeclarativeengine_p.h +++ b/src/declarative/qml/qdeclarativeengine_p.h @@ -57,6 +57,7 @@ #include "private/qdeclarativeclassfactory_p.h" #include "private/qdeclarativecompositetypemanager_p.h" +#include "private/qdeclarativeimport_p.h" #include "private/qpodvector_p.h" #include "qdeclarative.h" #include "private/qdeclarativevaluetype_p.h" @@ -164,7 +165,6 @@ public: bool outputWarningsToStdErr; - struct ImportedNamespace; QDeclarativeContextScriptClass *contextClass; QDeclarativeContextData *sharedContext; QObject *sharedScope; @@ -217,8 +217,13 @@ public: QList<SimpleList<QDeclarativeAbstractBinding> > bindValues; QList<SimpleList<QDeclarativeParserStatus> > parserStatus; + QList<QPair<QDeclarativeGuard<QObject>,int> > finalizedParserStatus; QDeclarativeComponentAttached *componentAttached; + void registerFinalizedParserStatusObject(QObject *obj, int index) { + finalizedParserStatus.append(qMakePair(QDeclarativeGuard<QObject>(obj), index)); + } + bool inBeginCreate; QNetworkAccessManager *createNetworkAccessManager(QObject *parent) const; @@ -232,8 +237,8 @@ public: mutable QMutex mutex; QDeclarativeCompositeTypeManager typeManager; - QStringList fileImportPath; - QStringList filePluginPath; + QDeclarativeImportDatabase importDatabase; + QString offlineStoragePath; mutable quint32 uniqueId; @@ -244,58 +249,8 @@ public: QDeclarativeValueTypeFactory valueTypes; QHash<const QMetaObject *, QDeclarativePropertyCache *> propertyCache; - QDeclarativePropertyCache *cache(QObject *obj) { - Q_Q(QDeclarativeEngine); - if (!obj || QObjectPrivate::get(obj)->metaObject || - QObjectPrivate::get(obj)->wasDeleted) return 0; - const QMetaObject *mo = obj->metaObject(); - QDeclarativePropertyCache *rv = propertyCache.value(mo); - if (!rv) { - rv = QDeclarativePropertyCache::create(q, mo); - propertyCache.insert(mo, rv); - } - return rv; - } - - // ### This whole class is embarrassing - struct Imports { - Imports(); - ~Imports(); - Imports(const Imports ©); - Imports &operator =(const Imports ©); - - void setBaseUrl(const QUrl& url); - QUrl baseUrl() const; - - void cache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *) const; - - private: - friend class QDeclarativeEnginePrivate; - QDeclarativeImportsPrivate *d; - }; - - - QSet<QString> initializedPlugins; - - QString resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath, const QString &baseName, - const QStringList &suffixes, - const QString &prefix = QString()); - QString resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath, const QString &baseName); - - - bool addToImport(Imports*, const QDeclarativeDirComponents &qmldircomponentsnetwork, - const QString& uri, const QString& prefix, int vmaj, int vmin, - QDeclarativeScriptParser::Import::Type importType, - QString *errorString) const; - bool resolveType(const Imports&, const QByteArray& type, - QDeclarativeType** type_return, QUrl* url_return, - int *version_major, int *version_minor, - ImportedNamespace** ns_return, - QString *errorString = 0) const; - void resolveTypeInNamespace(ImportedNamespace*, const QByteArray& type, - QDeclarativeType** type_return, QUrl* url_return, - int *version_major, int *version_minor ) const; - + inline QDeclarativePropertyCache *cache(QObject *obj); + inline QDeclarativePropertyCache *cache(const QMetaObject *); void registerCompositeType(QDeclarativeCompiledData *); @@ -339,6 +294,7 @@ public: static QScriptValue tint(QScriptContext*, QScriptEngine*); static QScriptValue desktopOpenUrl(QScriptContext*, QScriptEngine*); + static QScriptValue fontFamilies(QScriptContext*, QScriptEngine*); static QScriptValue md5(QScriptContext*, QScriptEngine*); static QScriptValue btoa(QScriptContext*, QScriptEngine*); static QScriptValue atob(QScriptContext*, QScriptEngine*); @@ -361,6 +317,48 @@ public: static void defineModule(); }; +/*! +Returns a QDeclarativePropertyCache for \a obj if one is available. + +If \a obj is null, being deleted or contains a dynamic meta object 0 +is returned. +*/ +QDeclarativePropertyCache *QDeclarativeEnginePrivate::cache(QObject *obj) +{ + Q_Q(QDeclarativeEngine); + if (!obj || QObjectPrivate::get(obj)->metaObject || QObjectPrivate::get(obj)->wasDeleted) + return 0; + + const QMetaObject *mo = obj->metaObject(); + QDeclarativePropertyCache *rv = propertyCache.value(mo); + if (!rv) { + rv = new QDeclarativePropertyCache(q, mo); + propertyCache.insert(mo, rv); + } + return rv; +} + +/*! +Returns a QDeclarativePropertyCache for \a metaObject. + +As the cache is persisted for the life of the engine, \a metaObject must be +a static "compile time" meta-object, or a meta-object that is otherwise known to +exist for the lifetime of the QDeclarativeEngine. +*/ +QDeclarativePropertyCache *QDeclarativeEnginePrivate::cache(const QMetaObject *metaObject) +{ + Q_Q(QDeclarativeEngine); + Q_ASSERT(metaObject); + + QDeclarativePropertyCache *rv = propertyCache.value(metaObject); + if (!rv) { + rv = new QDeclarativePropertyCache(q, metaObject); + propertyCache.insert(metaObject, rv); + } + + return rv; +} + QT_END_NAMESPACE #endif // QDECLARATIVEENGINE_P_H diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp index f561a7e..5ceb918 100644 --- a/src/declarative/qml/qdeclarativeexpression.cpp +++ b/src/declarative/qml/qdeclarativeexpression.cpp @@ -57,10 +57,12 @@ QT_BEGIN_NAMESPACE bool QDeclarativeDelayedError::addError(QDeclarativeEnginePrivate *e) { - if (!e || prevError) return false; + if (!e) return false; if (e->inProgressCreations == 0) return false; // Not in construction + if (prevError) return true; // Already in error chain + prevError = &e->erroredBindings; nextError = e->erroredBindings; e->erroredBindings = this; diff --git a/src/declarative/qml/qdeclarativeglobalscriptclass.cpp b/src/declarative/qml/qdeclarativeglobalscriptclass.cpp index fc802b4..6e107fb 100644 --- a/src/declarative/qml/qdeclarativeglobalscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeglobalscriptclass.cpp @@ -53,19 +53,29 @@ QT_BEGIN_NAMESPACE QDeclarativeGlobalScriptClass::QDeclarativeGlobalScriptClass(QScriptEngine *engine) : QScriptClass(engine) { + QString eval = QLatin1String("eval"); + QScriptValue globalObject = engine->globalObject(); + m_globalObject = engine->newObject(); + QScriptValue newGlobalObject = engine->newObject(); QScriptValueIterator iter(globalObject); + while (iter.hasNext()) { iter.next(); - m_globalObject.setProperty(iter.scriptName(), iter.value()); - m_illegalNames.insert(iter.name()); + + QString name = iter.name(); + + if (name != eval) + m_globalObject.setProperty(iter.scriptName(), iter.value()); + newGlobalObject.setProperty(iter.scriptName(), iter.value()); + + m_illegalNames.insert(name); } - QScriptValue v = engine->newObject(); - v.setScriptClass(this); - engine->setGlobalObject(v); + newGlobalObject.setScriptClass(this); + engine->setGlobalObject(newGlobalObject); } QScriptClass::QueryFlags diff --git a/src/declarative/qml/qdeclarativeimport.cpp b/src/declarative/qml/qdeclarativeimport.cpp new file mode 100644 index 0000000..576e048 --- /dev/null +++ b/src/declarative/qml/qdeclarativeimport.cpp @@ -0,0 +1,925 @@ +/**************************************************************************** +** +** 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 "qdeclarativeimport_p.h" + +#include <QtCore/qdebug.h> +#include <QtCore/qdir.h> +#include <QtCore/qfileinfo.h> +#include <QtCore/qpluginloader.h> +#include <QtCore/qlibraryinfo.h> +#include <QtDeclarative/qdeclarativeextensioninterface.h> +#include <private/qdeclarativeglobal_p.h> +#include <private/qdeclarativetypenamecache_p.h> + +QT_BEGIN_NAMESPACE + +DEFINE_BOOL_CONFIG_OPTION(qmlImportTrace, QML_IMPORT_TRACE) +DEFINE_BOOL_CONFIG_OPTION(qmlCheckTypes, QML_CHECK_TYPES) + +static QString toLocalFileOrQrc(const QUrl& url) +{ + if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0) { + if (url.authority().isEmpty()) + return QLatin1Char(':') + url.path(); + return QString(); + } + return url.toLocalFile(); +} + +static bool greaterThan(const QString &s1, const QString &s2) +{ + return s1 > s2; +} + +typedef QMap<QString, QString> StringStringMap; +Q_GLOBAL_STATIC(StringStringMap, qmlEnginePluginsWithRegisteredTypes); // stores the uri + +class QDeclarativeImportedNamespace +{ +public: + QStringList uris; + QStringList urls; + QList<int> majversions; + QList<int> minversions; + QList<bool> isLibrary; + QList<QDeclarativeDirComponents> qmlDirComponents; + + + bool find_helper(int i, const QByteArray& type, int *vmajor, int *vminor, + QDeclarativeType** type_return, QUrl* url_return, + QUrl *base = 0, bool *typeRecursionDetected = 0); + bool find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, + QUrl* url_return, QUrl *base = 0, QString *errorString = 0); +}; + +class QDeclarativeImportsPrivate { +public: + QDeclarativeImportsPrivate(); + ~QDeclarativeImportsPrivate(); + + bool importExtension(const QString &absoluteFilePath, const QString &uri, + QDeclarativeImportDatabase *database, QDeclarativeDirComponents* components, + QString *errorString); + + QString resolvedUri(const QString &dir_arg, QDeclarativeImportDatabase *database); + bool add(const QDeclarativeDirComponents &qmldircomponentsnetwork, + const QString& uri_arg, const QString& prefix, + int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, + QDeclarativeImportDatabase *database, QString *errorString); + bool find(const QByteArray& type, int *vmajor, int *vminor, + QDeclarativeType** type_return, QUrl* url_return, QString *errorString); + + QDeclarativeImportedNamespace *findNamespace(const QString& type); + + QUrl base; + int ref; + + QSet<QString> qmlDirFilesForWhichPluginsHaveBeenLoaded; + QDeclarativeImportedNamespace unqualifiedset; + QHash<QString,QDeclarativeImportedNamespace* > set; +}; + +QDeclarativeImports::QDeclarativeImports(const QDeclarativeImports ©) +: d(copy.d) +{ + ++d->ref; +} + +QDeclarativeImports & +QDeclarativeImports::operator =(const QDeclarativeImports ©) +{ + ++copy.d->ref; + if (--d->ref == 0) + delete d; + d = copy.d; + return *this; +} + +QDeclarativeImports::QDeclarativeImports() +: d(new QDeclarativeImportsPrivate) +{ +} + +QDeclarativeImports::~QDeclarativeImports() +{ + if (--d->ref == 0) + delete d; +} + +/*! + Sets the base URL to be used for all relative file imports added. +*/ +void QDeclarativeImports::setBaseUrl(const QUrl& url) +{ + d->base = url; +} + +/*! + Returns the base URL to be used for all relative file imports added. +*/ +QUrl QDeclarativeImports::baseUrl() const +{ + return d->base; +} + +static QDeclarativeTypeNameCache * +cacheForNamespace(QDeclarativeEngine *engine, const QDeclarativeImportedNamespace &set, + QDeclarativeTypeNameCache *cache) +{ + if (!cache) + cache = new QDeclarativeTypeNameCache(engine); + + QList<QDeclarativeType *> types = QDeclarativeMetaType::qmlTypes(); + + for (int ii = 0; ii < set.uris.count(); ++ii) { + QByteArray base = set.uris.at(ii).toUtf8() + '/'; + int major = set.majversions.at(ii); + int minor = set.minversions.at(ii); + + foreach (QDeclarativeType *type, types) { + if (type->qmlTypeName().startsWith(base) && + type->qmlTypeName().lastIndexOf('/') == (base.length() - 1) && + type->availableInVersion(major,minor)) + { + QString name = QString::fromUtf8(type->qmlTypeName().mid(base.length())); + + cache->add(name, type); + } + } + } + + return cache; +} + +void QDeclarativeImports::cache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *engine) const +{ + const QDeclarativeImportedNamespace &set = d->unqualifiedset; + + for (QHash<QString,QDeclarativeImportedNamespace* >::ConstIterator iter = d->set.begin(); + iter != d->set.end(); ++iter) { + + QDeclarativeTypeNameCache::Data *d = cache->data(iter.key()); + if (d) { + if (!d->typeNamespace) + cacheForNamespace(engine, *(*iter), d->typeNamespace); + } else { + QDeclarativeTypeNameCache *nc = cacheForNamespace(engine, *(*iter), 0); + cache->add(iter.key(), nc); + nc->release(); + } + } + + cacheForNamespace(engine, set, cache); +} +bool QDeclarativeImportedNamespace::find_helper(int i, const QByteArray& type, int *vmajor, int *vminor, + QDeclarativeType** type_return, QUrl* url_return, + QUrl *base, bool *typeRecursionDetected) +{ + int vmaj = majversions.at(i); + int vmin = minversions.at(i); + + QByteArray qt = uris.at(i).toUtf8(); + qt += '/'; + qt += type; + + QDeclarativeType *t = QDeclarativeMetaType::qmlType(qt,vmaj,vmin); + if (t) { + if (vmajor) *vmajor = vmaj; + if (vminor) *vminor = vmin; + if (type_return) + *type_return = t; + return true; + } + + QUrl url = QUrl(urls.at(i) + QLatin1Char('/') + QString::fromUtf8(type) + QLatin1String(".qml")); + QDeclarativeDirComponents qmldircomponents = qmlDirComponents.at(i); + + bool typeWasDeclaredInQmldir = false; + if (!qmldircomponents.isEmpty()) { + const QString typeName = QString::fromUtf8(type); + foreach (const QDeclarativeDirParser::Component &c, qmldircomponents) { + if (c.typeName == typeName) { + typeWasDeclaredInQmldir = true; + + // importing version -1 means import ALL versions + if ((vmaj == -1) || (c.majorVersion < vmaj || (c.majorVersion == vmaj && vmin >= c.minorVersion))) { + QUrl candidate = url.resolved(QUrl(c.fileName)); + if (c.internal && base) { + if (base->resolved(QUrl(c.fileName)) != candidate) + continue; // failed attempt to access an internal type + } + if (base && *base == candidate) { + if (typeRecursionDetected) + *typeRecursionDetected = true; + continue; // no recursion + } + if (url_return) + *url_return = candidate; + return true; + } + } + } + } + + if (!typeWasDeclaredInQmldir && !isLibrary.at(i)) { + // XXX search non-files too! (eg. zip files, see QT-524) + QFileInfo f(toLocalFileOrQrc(url)); + if (f.exists()) { + if (base && *base == url) { // no recursion + if (typeRecursionDetected) + *typeRecursionDetected = true; + } else { + if (url_return) + *url_return = url; + return true; + } + } + } + return false; +} + +QDeclarativeImportsPrivate::QDeclarativeImportsPrivate() +: ref(1) +{ +} + +QDeclarativeImportsPrivate::~QDeclarativeImportsPrivate() +{ + foreach (QDeclarativeImportedNamespace* s, set.values()) + delete s; +} + +bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath, const QString &uri, + 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; + } else { + if (errorString) + *errorString = QDeclarativeImportDatabase::tr("module \"%1\" definition \"%2\" not readable").arg(uri).arg(absoluteFilePath); + return false; + } + QDir dir = QFileInfo(file).dir(); + + QDeclarativeDirParser qmldirParser; + qmldirParser.setSource(filecontent); + qmldirParser.parse(); + + if (! qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(absoluteFilePath)) { + qmlDirFilesForWhichPluginsHaveBeenLoaded.insert(absoluteFilePath); + + + foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser.plugins()) { + + QString resolvedFilePath = database->resolvePlugin(dir, plugin.path, plugin.name); + + if (!resolvedFilePath.isEmpty()) { + if (!database->importPlugin(resolvedFilePath, uri, errorString)) { + if (errorString) + *errorString = QDeclarativeImportDatabase::tr("plugin cannot be loaded for module \"%1\": %2").arg(uri).arg(*errorString); + return false; + } + } else { + if (errorString) + *errorString = QDeclarativeImportDatabase::tr("module \"%1\" plugin \"%2\" not found").arg(uri).arg(plugin.name); + return false; + } + } + } + + if (components) + *components = qmldirParser.components(); + + return true; +} + +QString QDeclarativeImportsPrivate::resolvedUri(const QString &dir_arg, QDeclarativeImportDatabase *database) +{ + QString dir = dir_arg; + if (dir.endsWith(QLatin1Char('/')) || dir.endsWith(QLatin1Char('\\'))) + dir.chop(1); + + QStringList paths = database->fileImportPath; + qSort(paths.begin(), paths.end(), greaterThan); // Ensure subdirs preceed their parents. + + QString stableRelativePath = dir; + foreach( QString path, paths) { + if (dir.startsWith(path)) { + stableRelativePath = dir.mid(path.length()+1); + break; + } + } + stableRelativePath.replace(QLatin1Char('/'), QLatin1Char('.')); + stableRelativePath.replace(QLatin1Char('\\'), QLatin1Char('.')); + return stableRelativePath; +} + +bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomponentsnetwork, + const QString& uri_arg, const QString& prefix, int vmaj, int vmin, + QDeclarativeScriptParser::Import::Type importType, + QDeclarativeImportDatabase *database, QString *errorString) +{ + QDeclarativeDirComponents qmldircomponents = qmldircomponentsnetwork; + QString uri = uri_arg; + QDeclarativeImportedNamespace *s; + if (prefix.isEmpty()) { + s = &unqualifiedset; + } else { + s = set.value(prefix); + if (!s) + set.insert(prefix,(s=new QDeclarativeImportedNamespace)); + } + + QString url = uri; + if (importType == QDeclarativeScriptParser::Import::Library) { + url.replace(QLatin1Char('.'), QLatin1Char('/')); + bool found = false; + QString dir; + + + foreach (const QString &p, database->fileImportPath) { + dir = p+QLatin1Char('/')+url; + + QFileInfo fi(dir+QLatin1String("/qmldir")); + const QString absoluteFilePath = fi.absoluteFilePath(); + + if (fi.isFile()) { + found = true; + + url = QUrl::fromLocalFile(fi.absolutePath()).toString(); + uri = resolvedUri(dir, database); + if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, errorString)) + return false; + break; + } + } + + if (!found) { + found = QDeclarativeMetaType::isModule(uri.toUtf8(), vmaj, vmin); + if (!found) { + if (errorString) { + bool anyversion = QDeclarativeMetaType::isModule(uri.toUtf8(), -1, -1); + if (anyversion) + *errorString = QDeclarativeImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin); + else + *errorString = QDeclarativeImportDatabase::tr("module \"%1\" is not installed").arg(uri_arg); + } + return false; + } + } + } else { + + if (importType == QDeclarativeScriptParser::Import::File && qmldircomponents.isEmpty()) { + QUrl importUrl = base.resolved(QUrl(uri + QLatin1String("/qmldir"))); + QString localFileOrQrc = toLocalFileOrQrc(importUrl); + if (!localFileOrQrc.isEmpty()) { + QString dir = toLocalFileOrQrc(base.resolved(QUrl(uri))); + if (dir.isEmpty() || !QDir().exists(dir)) { + if (errorString) + *errorString = QDeclarativeImportDatabase::tr("\"%1\": no such directory").arg(uri_arg); + return false; // local import dirs must exist + } + uri = resolvedUri(toLocalFileOrQrc(base.resolved(QUrl(uri))), database); + if (uri.endsWith(QLatin1Char('/'))) + uri.chop(1); + if (QFile::exists(localFileOrQrc)) { + if (!importExtension(localFileOrQrc,uri,database,&qmldircomponents,errorString)) + return false; + } + } else { + if (prefix.isEmpty()) { + // directory must at least exist for valid import + QString localFileOrQrc = toLocalFileOrQrc(base.resolved(QUrl(uri))); + if (localFileOrQrc.isEmpty() || !QDir().exists(localFileOrQrc)) { + if (errorString) { + if (localFileOrQrc.isEmpty()) + *errorString = QDeclarativeImportDatabase::tr("import \"%1\" has no qmldir and no namespace").arg(uri); + else + *errorString = QDeclarativeImportDatabase::tr("\"%1\": no such directory").arg(uri); + } + return false; + } + } + } + } + + url = base.resolved(QUrl(url)).toString(); + if (url.endsWith(QLatin1Char('/'))) + url.chop(1); + } + + if (vmaj > -1 && vmin > -1 && !qmldircomponents.isEmpty()) { + QList<QDeclarativeDirParser::Component>::ConstIterator it = qmldircomponents.begin(); + for (; it != qmldircomponents.end(); ++it) { + if (it->majorVersion > vmaj || (it->majorVersion == vmaj && it->minorVersion >= vmin)) + break; + } + if (it == qmldircomponents.end()) { + *errorString = QDeclarativeImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin); + return false; + } + } + + s->uris.prepend(uri); + s->urls.prepend(url); + s->majversions.prepend(vmaj); + s->minversions.prepend(vmin); + s->isLibrary.prepend(importType == QDeclarativeScriptParser::Import::Library); + s->qmlDirComponents.prepend(qmldircomponents); + return true; +} + +bool QDeclarativeImportsPrivate::find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, + QUrl* url_return, QString *errorString) +{ + QDeclarativeImportedNamespace *s = 0; + int slash = type.indexOf('/'); + if (slash >= 0) { + QString namespaceName = QString::fromUtf8(type.left(slash)); + s = set.value(namespaceName); + if (!s) { + if (errorString) + *errorString = QDeclarativeImportDatabase::tr("- %1 is not a namespace").arg(namespaceName); + return false; + } + int nslash = type.indexOf('/',slash+1); + if (nslash > 0) { + if (errorString) + *errorString = QDeclarativeImportDatabase::tr("- nested namespaces not allowed"); + return false; + } + } else { + s = &unqualifiedset; + } + QByteArray unqualifiedtype = slash < 0 ? type : type.mid(slash+1); // common-case opt (QString::mid works fine, but slower) + if (s) { + if (s->find(unqualifiedtype,vmajor,vminor,type_return,url_return, &base, errorString)) + return true; + if (s->urls.count() == 1 && !s->isLibrary[0] && url_return && s != &unqualifiedset) { + // qualified, and only 1 url + *url_return = QUrl(s->urls[0]+QLatin1Char('/')).resolved(QUrl(QString::fromUtf8(unqualifiedtype) + QLatin1String(".qml"))); + return true; + } + } + + return false; +} + +QDeclarativeImportedNamespace *QDeclarativeImportsPrivate::findNamespace(const QString& type) +{ + return set.value(type); +} + +bool QDeclarativeImportedNamespace::find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, + QUrl* url_return, QUrl *base, QString *errorString) +{ + bool typeRecursionDetected = false; + for (int i=0; i<urls.count(); ++i) { + if (find_helper(i, type, vmajor, vminor, type_return, url_return, base, &typeRecursionDetected)) { + if (qmlCheckTypes()) { + // check for type clashes + for (int j = i+1; j<urls.count(); ++j) { + if (find_helper(j, type, vmajor, vminor, 0, 0, base)) { + if (errorString) { + QString u1 = urls.at(i); + QString u2 = urls.at(j); + if (base) { + QString b = base->toString(); + int slash = b.lastIndexOf(QLatin1Char('/')); + if (slash >= 0) { + b = b.left(slash+1); + QString l = b.left(slash); + if (u1.startsWith(b)) + u1 = u1.mid(b.count()); + else if (u1 == l) + u1 = QDeclarativeImportDatabase::tr("local directory"); + if (u2.startsWith(b)) + u2 = u2.mid(b.count()); + else if (u2 == l) + u2 = QDeclarativeImportDatabase::tr("local directory"); + } + } + + if (u1 != u2) + *errorString + = QDeclarativeImportDatabase::tr("is ambiguous. Found in %1 and in %2") + .arg(u1).arg(u2); + else + *errorString + = QDeclarativeImportDatabase::tr("is ambiguous. Found in %1 in version %2.%3 and %4.%5") + .arg(u1) + .arg(majversions.at(i)).arg(minversions.at(i)) + .arg(majversions.at(j)).arg(minversions.at(j)); + } + return false; + } + } + } + return true; + } + } + if (errorString) { + if (typeRecursionDetected) + *errorString = QDeclarativeImportDatabase::tr("is instantiated recursively"); + else + *errorString = QDeclarativeImportDatabase::tr("is not a type"); + } + return false; +} + +QDeclarativeImportDatabase::QDeclarativeImportDatabase(QDeclarativeEngine *e) +: engine(e) +{ + filePluginPath << QLatin1String("."); + + QString builtinPath = QLibraryInfo::location(QLibraryInfo::ImportsPath); + if (!builtinPath.isEmpty()) + addImportPath(builtinPath); + + // env import paths + QByteArray envImportPath = qgetenv("QML_IMPORT_PATH"); + if (!envImportPath.isEmpty()) { +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + QLatin1Char pathSep(';'); +#else + QLatin1Char pathSep(':'); +#endif + QStringList paths = QString::fromLatin1(envImportPath).split(pathSep, QString::SkipEmptyParts); + for (int ii = paths.count() - 1; ii >= 0; --ii) + addImportPath(paths.at(ii)); + } +} + +QDeclarativeImportDatabase::~QDeclarativeImportDatabase() +{ +} + +/*! + \internal + + Adds information to \a imports such that subsequent calls to resolveType() + will resolve types qualified by \a prefix by considering types found at the given \a uri. + + The uri is either a directory (if importType is FileImport), or a URI resolved using paths + added via addImportPath() (if importType is LibraryImport). + + The \a prefix may be empty, in which case the import location is considered for + unqualified types. + + 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) +{ + if (qmlImportTrace()) + qDebug().nospace() << "QDeclarativeImportDatabase::addToImport " << imports << " " << 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. +*/ +void QDeclarativeImportDatabase::resolveTypeInNamespace(QDeclarativeImportedNamespace* ns, const QByteArray& type, + QDeclarativeType** type_return, QUrl* url_return, + int *vmaj, int *vmin) const +{ + ns->find(type,vmaj,vmin,type_return,url_return); +} + +/*! + \internal + + Returns the result of the merge of \a baseName with \a path, \a suffixes, and \a prefix. + The \a prefix must contain the dot. + + \a qmldirPath is the location of the qmldir file. + */ +QString QDeclarativeImportDatabase::resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath, + const QString &baseName, const QStringList &suffixes, + const QString &prefix) +{ + QStringList searchPaths = filePluginPath; + bool qmldirPluginPathIsRelative = QDir::isRelativePath(qmldirPluginPath); + if (!qmldirPluginPathIsRelative) + searchPaths.prepend(qmldirPluginPath); + + foreach (const QString &pluginPath, searchPaths) { + + QString resolvedPath; + + if (pluginPath == QLatin1String(".")) { + if (qmldirPluginPathIsRelative) + resolvedPath = qmldirPath.absoluteFilePath(qmldirPluginPath); + else + resolvedPath = qmldirPath.absolutePath(); + } else { + resolvedPath = pluginPath; + } + + // hack for resources, should probably go away + if (resolvedPath.startsWith(QLatin1Char(':'))) + resolvedPath = QCoreApplication::applicationDirPath(); + + QDir dir(resolvedPath); + foreach (const QString &suffix, suffixes) { + QString pluginFileName = prefix; + + pluginFileName += baseName; + pluginFileName += suffix; + + QFileInfo fileInfo(dir, pluginFileName); + + if (fileInfo.exists()) + return fileInfo.absoluteFilePath(); + } + } + + if (qmlImportTrace()) + qDebug() << "QDeclarativeImportDatabase::resolvePlugin: Could not resolve plugin" << baseName + << "in" << qmldirPath.absolutePath(); + + return QString(); +} + +/*! + \internal + + Returns the result of the merge of \a baseName with \a dir and the platform suffix. + + \table + \header \i Platform \i Valid suffixes + \row \i Windows \i \c .dll + \row \i Unix/Linux \i \c .so + \row \i AIX \i \c .a + \row \i HP-UX \i \c .sl, \c .so (HP-UXi) + \row \i Mac OS X \i \c .dylib, \c .bundle, \c .so + \row \i Symbian \i \c .dll + \endtable + + Version number on unix are ignored. +*/ +QString QDeclarativeImportDatabase::resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath, + const QString &baseName) +{ +#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) + return resolvePlugin(qmldirPath, qmldirPluginPath, baseName, + QStringList() +# ifdef QT_DEBUG + << QLatin1String("d.dll") // try a qmake-style debug build first +# endif + << QLatin1String(".dll")); +#elif defined(Q_OS_SYMBIAN) + return resolvePlugin(qmldirPath, qmldirPluginPath, baseName, + QStringList() + << QLatin1String(".dll") + << QLatin1String(".qtplugin")); +#else + +# if defined(Q_OS_DARWIN) + + return resolvePlugin(qmldirPath, qmldirPluginPath, baseName, + QStringList() +# ifdef QT_DEBUG + << QLatin1String("_debug.dylib") // try a qmake-style debug build first + << QLatin1String(".dylib") +# else + << QLatin1String(".dylib") + << QLatin1String("_debug.dylib") // try a qmake-style debug build after +# endif + << QLatin1String(".so") + << QLatin1String(".bundle"), + QLatin1String("lib")); +# else // Generic Unix + QStringList validSuffixList; + +# if defined(Q_OS_HPUX) +/* + See "HP-UX Linker and Libraries User's Guide", section "Link-time Differences between PA-RISC and IPF": + "In PA-RISC (PA-32 and PA-64) shared libraries are suffixed with .sl. In IPF (32-bit and 64-bit), + the shared libraries are suffixed with .so. For compatibility, the IPF linker also supports the .sl suffix." + */ + validSuffixList << QLatin1String(".sl"); +# if defined __ia64 + validSuffixList << QLatin1String(".so"); +# endif +# elif defined(Q_OS_AIX) + validSuffixList << QLatin1String(".a") << QLatin1String(".so"); +# elif defined(Q_OS_UNIX) + validSuffixList << QLatin1String(".so"); +# endif + + // Examples of valid library names: + // libfoo.so + + return resolvePlugin(qmldirPath, qmldirPluginPath, baseName, validSuffixList, QLatin1String("lib")); +# endif + +#endif +} + +QStringList QDeclarativeImportDatabase::pluginPathList() const +{ + return filePluginPath; +} + +void QDeclarativeImportDatabase::setPluginPathList(const QStringList &paths) +{ + filePluginPath = paths; +} + +void QDeclarativeImportDatabase::addPluginPath(const QString& path) +{ + if (qmlImportTrace()) + qDebug() << "QDeclarativeImportDatabase::addPluginPath" << path; + + QUrl url = QUrl(path); + if (url.isRelative() || url.scheme() == QString::fromLocal8Bit("file")) { + QDir dir = QDir(path); + filePluginPath.prepend(dir.canonicalPath()); + } else { + filePluginPath.prepend(path); + } +} + +void QDeclarativeImportDatabase::addImportPath(const QString& path) +{ + if (qmlImportTrace()) + qDebug() << "QDeclarativeImportDatabase::addImportPath" << path; + + QUrl url = QUrl(path); + QString cPath; + + if (url.isRelative() || url.scheme() == QString::fromLocal8Bit("file")) { + QDir dir = QDir(path); + cPath = dir.canonicalPath(); + } else { + cPath = path; + } + + if (!fileImportPath.contains(cPath)) + fileImportPath.prepend(cPath); +} + +QStringList QDeclarativeImportDatabase::importPathList() const +{ + return fileImportPath; +} + +void QDeclarativeImportDatabase::setImportPathList(const QStringList &paths) +{ + fileImportPath = paths; +} + + +bool QDeclarativeImportDatabase::importPlugin(const QString &filePath, const QString &uri, QString *errorString) +{ + if (qmlImportTrace()) + qDebug() << "QDeclarativeImportDatabase::importPlugin" << uri << "from" << filePath; + + QFileInfo fileInfo(filePath); + const QString absoluteFilePath = fileInfo.absoluteFilePath(); + + bool engineInitialized = initializedPlugins.contains(absoluteFilePath); + bool typesRegistered = qmlEnginePluginsWithRegisteredTypes()->contains(absoluteFilePath); + + if (typesRegistered) { + Q_ASSERT_X(qmlEnginePluginsWithRegisteredTypes()->value(absoluteFilePath) == uri, + "QDeclarativeImportDatabase::importExtension", + "Internal error: Plugin imported previously with different uri"); + } + + if (!engineInitialized || !typesRegistered) { + QPluginLoader loader(absoluteFilePath); + + if (!loader.load()) { + if (errorString) + *errorString = loader.errorString(); + return false; + } + + if (QDeclarativeExtensionInterface *iface = qobject_cast<QDeclarativeExtensionInterface *>(loader.instance())) { + + const QByteArray bytes = uri.toUtf8(); + const char *moduleId = bytes.constData(); + if (!typesRegistered) { + + // ### this code should probably be protected with a mutex. + qmlEnginePluginsWithRegisteredTypes()->insert(absoluteFilePath, uri); + iface->registerTypes(moduleId); + } + if (!engineInitialized) { + // things on the engine (eg. adding new global objects) have to be done for every engine. + + // protect against double initialization + initializedPlugins.insert(absoluteFilePath); + iface->initializeEngine(engine, moduleId); + } + } else { + if (errorString) + *errorString = loader.errorString(); + return false; + } + } + + return true; +} + + +QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativeimport_p.h b/src/declarative/qml/qdeclarativeimport_p.h new file mode 100644 index 0000000..62b0517 --- /dev/null +++ b/src/declarative/qml/qdeclarativeimport_p.h @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** 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 QDECLARATIVEIMPORT_P_H +#define QDECLARATIVEIMPORT_P_H + +#include <QtCore/qurl.h> +#include <QtCore/qcoreapplication.h> +#include <QtCore/qset.h> +#include <private/qdeclarativedirparser_p.h> +#include <private/qdeclarativescriptparser_p.h> +#include <private/qdeclarativemetatype_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. +// + +QT_BEGIN_NAMESPACE + +class QDeclarativeTypeNameCache; +class QDeclarativeEngine; +class QDir; + +class QDeclarativeImportedNamespace; +class QDeclarativeImportsPrivate; +class QDeclarativeImports +{ +public: + QDeclarativeImports(); + QDeclarativeImports(const QDeclarativeImports &); + ~QDeclarativeImports(); + QDeclarativeImports &operator=(const QDeclarativeImports &); + + void setBaseUrl(const QUrl &url); + QUrl baseUrl() const; + + void cache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *) const; +private: + friend class QDeclarativeImportDatabase; + QDeclarativeImportsPrivate *d; +}; + +class QDeclarativeImportDatabase +{ + Q_DECLARE_TR_FUNCTIONS(QDeclarativeImportDatabase) +public: + QDeclarativeImportDatabase(QDeclarativeEngine *); + ~QDeclarativeImportDatabase(); + + bool importPlugin(const QString &filePath, const QString &uri, QString *errorString); + + QStringList importPathList() const; + void setImportPathList(const QStringList &paths); + void addImportPath(const QString& dir); + + QStringList pluginPathList() const; + 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; + void 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, + const QString &baseName, const QStringList &suffixes, + const QString &prefix = QString()); + QString resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath, + const QString &baseName); + + + QStringList filePluginPath; + QStringList fileImportPath; + + QSet<QString> initializedPlugins; + QDeclarativeEngine *engine; +}; + +QT_END_NAMESPACE + +#endif // QDECLARATIVEIMPORT_P_H + diff --git a/src/declarative/qml/qdeclarativeinfo.cpp b/src/declarative/qml/qdeclarativeinfo.cpp index ffed14e..c980a2a 100644 --- a/src/declarative/qml/qdeclarativeinfo.cpp +++ b/src/declarative/qml/qdeclarativeinfo.cpp @@ -78,8 +78,9 @@ QT_BEGIN_NAMESPACE \endcode */ -struct QDeclarativeInfoPrivate +class QDeclarativeInfoPrivate { +public: QDeclarativeInfoPrivate() : ref (1), object(0) {} int ref; diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index bb5c8b7..8b64e0e 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -104,7 +104,8 @@ QScriptValue QDeclarativeObjectScriptClass::newQObject(QObject *object, int type QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); if (!object) - return newObject(scriptEngine, this, new ObjectData(object, type)); + return scriptEngine->nullValue(); +// return newObject(scriptEngine, this, new ObjectData(object, type)); if (QObjectPrivate::get(object)->wasDeleted) return scriptEngine->undefinedValue(); @@ -265,7 +266,7 @@ QDeclarativeObjectScriptClass::property(QObject *obj, const Identifier &name) void *args[] = { &rv, 0 }; QMetaObject::metacall(obj, QMetaObject::ReadProperty, lastData->coreIndex, args); return Value(scriptEngine, rv); - } else if (lastData->propType == QMetaType::Int) { + } else if (lastData->propType == QMetaType::Int || lastData->flags & QDeclarativePropertyCache::Data::IsEnumType) { int rv = 0; void *args[] = { &rv, 0 }; QMetaObject::metacall(obj, QMetaObject::ReadProperty, lastData->coreIndex, args); @@ -368,6 +369,9 @@ void QDeclarativeObjectScriptClass::setProperty(QObject *obj, QString error = QLatin1String("Cannot assign [undefined] to ") + QLatin1String(QMetaType::typeName(lastData->propType)); context->throwError(error); + } else if (!value.isRegExp() && value.isFunction()) { + QString error = QLatin1String("Cannot assign a function to a property."); + context->throwError(error); } else { QVariant v; if (lastData->flags & QDeclarativePropertyCache::Data::IsQList) @@ -441,7 +445,7 @@ QScriptValue QDeclarativeObjectScriptClass::destroy(QScriptContext *context, QSc QDeclarativeData *ddata = QDeclarativeData::get(data->object, false); if (!ddata || ddata->indestructible) - return engine->currentContext()->throwError(QLatin1String("Invalid attempt to destroy() an indestructible object")); + return engine->currentContext()->throwError(QLatin1String("Invalid attempt to destroy() an indestructible object")); QObject *obj = data->object; int delay = 0; @@ -772,7 +776,8 @@ QScriptDeclarativeClass::Value MetaCallArgument::toValue(QDeclarativeEngine *e) return QScriptDeclarativeClass::Value(engine, *((QString *)&data)); } else if (type == QMetaType::QObjectStar) { QObject *object = *((QObject **)&data); - QDeclarativeData::get(object, true)->setImplicitDestructible(); + if (object) + QDeclarativeData::get(object, true)->setImplicitDestructible(); QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(e); return QScriptDeclarativeClass::Value(engine, priv->objectClass->newQObject(object)); } else if (type == qMetaTypeId<QList<QObject *> >()) { diff --git a/src/declarative/qml/qdeclarativeparser_p.h b/src/declarative/qml/qdeclarativeparser_p.h index 0870cfb..25777f5 100644 --- a/src/declarative/qml/qdeclarativeparser_p.h +++ b/src/declarative/qml/qdeclarativeparser_p.h @@ -188,9 +188,6 @@ namespace QDeclarativeParser QList<int> lineNumbers; QList<Pragmas> pragmas; }; -#if 0 - QList<ScriptBlock> scripts; -#endif // The bytes to cast instances by to get to the QDeclarativeParserStatus // interface. -1 indicates the type doesn't support this interface. diff --git a/src/declarative/qml/qdeclarativeparserstatus.cpp b/src/declarative/qml/qdeclarativeparserstatus.cpp index 978bfb4..4c4e429 100644 --- a/src/declarative/qml/qdeclarativeparserstatus.cpp +++ b/src/declarative/qml/qdeclarativeparserstatus.cpp @@ -91,19 +91,17 @@ QDeclarativeParserStatus::~QDeclarativeParserStatus() } /*! + \fn void QDeclarativeParserStatus::classBegin() + Invoked after class creation, but before any properties have been set. */ -void QDeclarativeParserStatus::classBegin() -{ -} /*! + \fn void QDeclarativeParserStatus::componentComplete() + Invoked after the root component that caused this instantiation has completed construction. At this point all static values and binding values have been assigned to the class. */ -void QDeclarativeParserStatus::componentComplete() -{ -} QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativeparserstatus.h b/src/declarative/qml/qdeclarativeparserstatus.h index 34528c1..60d423e 100644 --- a/src/declarative/qml/qdeclarativeparserstatus.h +++ b/src/declarative/qml/qdeclarativeparserstatus.h @@ -56,8 +56,8 @@ public: QDeclarativeParserStatus(); virtual ~QDeclarativeParserStatus(); - virtual void classBegin(); - virtual void componentComplete(); + virtual void classBegin()=0; + virtual void componentComplete()=0; private: friend class QDeclarativeVME; diff --git a/src/declarative/qml/qdeclarativepropertycache.cpp b/src/declarative/qml/qdeclarativepropertycache.cpp index 26bddde..839d79f 100644 --- a/src/declarative/qml/qdeclarativepropertycache.cpp +++ b/src/declarative/qml/qdeclarativepropertycache.cpp @@ -106,9 +106,25 @@ void QDeclarativePropertyCache::Data::load(const QMetaMethod &m) } +/*! +Creates a new empty QDeclarativePropertyCache. +*/ QDeclarativePropertyCache::QDeclarativePropertyCache(QDeclarativeEngine *e) : QDeclarativeCleanup(e), engine(e) { + Q_ASSERT(engine); +} + +/*! +Creates a new QDeclarativePropertyCache of \a metaObject. +*/ +QDeclarativePropertyCache::QDeclarativePropertyCache(QDeclarativeEngine *e, const QMetaObject *metaObject) +: QDeclarativeCleanup(e), engine(e) +{ + Q_ASSERT(engine); + Q_ASSERT(metaObject); + + update(engine, metaObject); } QDeclarativePropertyCache::~QDeclarativePropertyCache() @@ -135,7 +151,7 @@ void QDeclarativePropertyCache::clear() } QDeclarativePropertyCache::Data QDeclarativePropertyCache::create(const QMetaObject *metaObject, - const QString &property) + const QString &property) { Q_ASSERT(metaObject); @@ -245,17 +261,6 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb } } -// ### Optimize - check engine for the parent meta object etc. -QDeclarativePropertyCache *QDeclarativePropertyCache::create(QDeclarativeEngine *engine, const QMetaObject *metaObject) -{ - Q_ASSERT(engine); - Q_ASSERT(metaObject); - - QDeclarativePropertyCache *cache = new QDeclarativePropertyCache(engine); - cache->update(engine, metaObject); - return cache; -} - void QDeclarativePropertyCache::update(QDeclarativeEngine *engine, const QMetaObject *metaObject) { Q_ASSERT(engine); diff --git a/src/declarative/qml/qdeclarativepropertycache_p.h b/src/declarative/qml/qdeclarativepropertycache_p.h index 6b64a96..b01e5cc 100644 --- a/src/declarative/qml/qdeclarativepropertycache_p.h +++ b/src/declarative/qml/qdeclarativepropertycache_p.h @@ -69,6 +69,7 @@ class QDeclarativePropertyCache : public QDeclarativeRefCount, public QDeclarati { public: QDeclarativePropertyCache(QDeclarativeEngine *); + QDeclarativePropertyCache(QDeclarativeEngine *, const QMetaObject *); virtual ~QDeclarativePropertyCache(); struct Data { diff --git a/src/declarative/qml/qdeclarativepropertyvaluesource.cpp b/src/declarative/qml/qdeclarativepropertyvaluesource.cpp index a0ed78f..039998f 100644 --- a/src/declarative/qml/qdeclarativepropertyvaluesource.cpp +++ b/src/declarative/qml/qdeclarativepropertyvaluesource.cpp @@ -60,6 +60,9 @@ QDeclarativePropertyValueSource::QDeclarativePropertyValueSource() { } +/*! + Destroys the value source. +*/ QDeclarativePropertyValueSource::~QDeclarativePropertyValueSource() { } diff --git a/src/declarative/qml/qdeclarativescriptparser.cpp b/src/declarative/qml/qdeclarativescriptparser.cpp index 8b96733..219d759 100644 --- a/src/declarative/qml/qdeclarativescriptparser.cpp +++ b/src/declarative/qml/qdeclarativescriptparser.cpp @@ -104,17 +104,13 @@ public: void operator()(const QString &code, AST::Node *node); protected: + Object *defineObjectBinding(AST::UiQualifiedId *propertyName, bool onAssignment, - AST::UiQualifiedId *objectTypeName, + const QString &objectType, + AST::SourceLocation typeLocation, LocationSpan location, AST::UiObjectInitializer *initializer = 0); - Object *defineObjectBinding_helper(AST::UiQualifiedId *propertyName, bool onAssignment, - const QString &objectType, - AST::SourceLocation typeLocation, - LocationSpan location, - AST::UiObjectInitializer *initializer = 0); - QDeclarativeParser::Variant getVariant(AST::ExpressionNode *expr); LocationSpan location(AST::SourceLocation start, AST::SourceLocation end); @@ -240,12 +236,12 @@ QString ProcessAST::asString(AST::UiQualifiedId *node) const } Object * -ProcessAST::defineObjectBinding_helper(AST::UiQualifiedId *propertyName, - bool onAssignment, - const QString &objectType, - AST::SourceLocation typeLocation, - LocationSpan location, - AST::UiObjectInitializer *initializer) +ProcessAST::defineObjectBinding(AST::UiQualifiedId *propertyName, + bool onAssignment, + const QString &objectType, + AST::SourceLocation typeLocation, + LocationSpan location, + AST::UiObjectInitializer *initializer) { int lastTypeDot = objectType.lastIndexOf(QLatin1Char('.')); bool isType = !objectType.isEmpty() && @@ -355,41 +351,6 @@ ProcessAST::defineObjectBinding_helper(AST::UiQualifiedId *propertyName, } } -Object *ProcessAST::defineObjectBinding(AST::UiQualifiedId *qualifiedId, bool onAssignment, - AST::UiQualifiedId *objectTypeName, - LocationSpan location, - AST::UiObjectInitializer *initializer) -{ - const QString objectType = asString(objectTypeName); - const AST::SourceLocation typeLocation = objectTypeName->identifierToken; - - if (objectType == QLatin1String("Script")) { - - AST::UiObjectMemberList *it = initializer->members; - for (; it; it = it->next) { - AST::UiScriptBinding *scriptBinding = AST::cast<AST::UiScriptBinding *>(it->member); - if (! scriptBinding) - continue; - - QString propertyName = asString(scriptBinding->qualifiedId); - if (propertyName == QLatin1String("source")) { - if (AST::ExpressionStatement *stmt = AST::cast<AST::ExpressionStatement *>(scriptBinding->statement)) { - QDeclarativeParser::Variant string = getVariant(stmt->expression); - if (string.isStringList()) { - QStringList urls = string.asStringList(); - // We need to add this as a resource - for (int ii = 0; ii < urls.count(); ++ii) - _parser->_refUrls << QUrl(urls.at(ii)); - } - } - } - } - - } - - return defineObjectBinding_helper(qualifiedId, onAssignment, objectType, typeLocation, location, initializer); -} - LocationSpan ProcessAST::location(AST::UiQualifiedId *id) { return location(id->identifierToken, id->identifierToken); @@ -664,10 +625,11 @@ bool ProcessAST::visit(AST::UiObjectDefinition *node) LocationSpan l = location(node->firstSourceLocation(), node->lastSourceLocation()); - defineObjectBinding(/*propertyName = */ 0, false, - node->qualifiedTypeNameId, - l, - node->initializer); + const QString objectType = asString(node->qualifiedTypeNameId); + const AST::SourceLocation typeLocation = node->qualifiedTypeNameId->identifierToken; + + defineObjectBinding(/*propertyName = */ 0, false, objectType, + typeLocation, l, node->initializer); return false; } @@ -679,10 +641,11 @@ bool ProcessAST::visit(AST::UiObjectBinding *node) LocationSpan l = location(node->qualifiedTypeNameId->identifierToken, node->initializer->rbraceToken); - defineObjectBinding(node->qualifiedId, node->hasOnToken, - node->qualifiedTypeNameId, - l, - node->initializer); + const QString objectType = asString(node->qualifiedTypeNameId); + const AST::SourceLocation typeLocation = node->qualifiedTypeNameId->identifierToken; + + defineObjectBinding(node->qualifiedId, node->hasOnToken, objectType, + typeLocation, l, node->initializer); return false; } diff --git a/src/declarative/qml/qdeclarativevaluetype.cpp b/src/declarative/qml/qdeclarativevaluetype.cpp index c6fe161..dbc25bb 100644 --- a/src/declarative/qml/qdeclarativevaluetype.cpp +++ b/src/declarative/qml/qdeclarativevaluetype.cpp @@ -116,8 +116,16 @@ QDeclarativeValueType *QDeclarativeValueTypeFactory::valueType(int t) return new QDeclarativeRectValueType; case QVariant::RectF: return new QDeclarativeRectFValueType; + case QVariant::Vector2D: + return new QDeclarativeVector2DValueType; case QVariant::Vector3D: return new QDeclarativeVector3DValueType; + case QVariant::Vector4D: + return new QDeclarativeVector4DValueType; + case QVariant::Quaternion: + return new QDeclarativeQuaternionValueType; + case QVariant::Matrix4x4: + return new QDeclarativeMatrix4x4ValueType; case QVariant::EasingCurve: return new QDeclarativeEasingValueType; case QVariant::Font: @@ -460,6 +468,54 @@ void QDeclarativeRectValueType::setHeight(int h) rect.setHeight(h); } +QDeclarativeVector2DValueType::QDeclarativeVector2DValueType(QObject *parent) +: QDeclarativeValueType(parent) +{ +} + +void QDeclarativeVector2DValueType::read(QObject *obj, int idx) +{ + void *a[] = { &vector, 0 }; + QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a); +} + +void QDeclarativeVector2DValueType::write(QObject *obj, int idx, QDeclarativePropertyPrivate::WriteFlags flags) +{ + int status = -1; + void *a[] = { &vector, 0, &status, &flags }; + QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a); +} + +QVariant QDeclarativeVector2DValueType::value() +{ + return QVariant(vector); +} + +void QDeclarativeVector2DValueType::setValue(QVariant value) +{ + vector = qvariant_cast<QVector2D>(value); +} + +qreal QDeclarativeVector2DValueType::x() const +{ + return vector.x(); +} + +qreal QDeclarativeVector2DValueType::y() const +{ + return vector.y(); +} + +void QDeclarativeVector2DValueType::setX(qreal x) +{ + vector.setX(x); +} + +void QDeclarativeVector2DValueType::setY(qreal y) +{ + vector.setY(y); +} + QDeclarativeVector3DValueType::QDeclarativeVector3DValueType(QObject *parent) : QDeclarativeValueType(parent) { @@ -518,6 +574,170 @@ void QDeclarativeVector3DValueType::setZ(qreal z) vector.setZ(z); } +QDeclarativeVector4DValueType::QDeclarativeVector4DValueType(QObject *parent) +: QDeclarativeValueType(parent) +{ +} + +void QDeclarativeVector4DValueType::read(QObject *obj, int idx) +{ + void *a[] = { &vector, 0 }; + QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a); +} + +void QDeclarativeVector4DValueType::write(QObject *obj, int idx, QDeclarativePropertyPrivate::WriteFlags flags) +{ + int status = -1; + void *a[] = { &vector, 0, &status, &flags }; + QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a); +} + +QVariant QDeclarativeVector4DValueType::value() +{ + return QVariant(vector); +} + +void QDeclarativeVector4DValueType::setValue(QVariant value) +{ + vector = qvariant_cast<QVector4D>(value); +} + +qreal QDeclarativeVector4DValueType::x() const +{ + return vector.x(); +} + +qreal QDeclarativeVector4DValueType::y() const +{ + return vector.y(); +} + +qreal QDeclarativeVector4DValueType::z() const +{ + return vector.z(); +} + +qreal QDeclarativeVector4DValueType::w() const +{ + return vector.w(); +} + +void QDeclarativeVector4DValueType::setX(qreal x) +{ + vector.setX(x); +} + +void QDeclarativeVector4DValueType::setY(qreal y) +{ + vector.setY(y); +} + +void QDeclarativeVector4DValueType::setZ(qreal z) +{ + vector.setZ(z); +} + +void QDeclarativeVector4DValueType::setW(qreal w) +{ + vector.setW(w); +} + +QDeclarativeQuaternionValueType::QDeclarativeQuaternionValueType(QObject *parent) +: QDeclarativeValueType(parent) +{ +} + +void QDeclarativeQuaternionValueType::read(QObject *obj, int idx) +{ + void *a[] = { &quaternion, 0 }; + QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a); +} + +void QDeclarativeQuaternionValueType::write(QObject *obj, int idx, QDeclarativePropertyPrivate::WriteFlags flags) +{ + int status = -1; + void *a[] = { &quaternion, 0, &status, &flags }; + QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a); +} + +QVariant QDeclarativeQuaternionValueType::value() +{ + return QVariant(quaternion); +} + +void QDeclarativeQuaternionValueType::setValue(QVariant value) +{ + quaternion = qvariant_cast<QQuaternion>(value); +} + +qreal QDeclarativeQuaternionValueType::scalar() const +{ + return quaternion.scalar(); +} + +qreal QDeclarativeQuaternionValueType::x() const +{ + return quaternion.x(); +} + +qreal QDeclarativeQuaternionValueType::y() const +{ + return quaternion.y(); +} + +qreal QDeclarativeQuaternionValueType::z() const +{ + return quaternion.z(); +} + +void QDeclarativeQuaternionValueType::setScalar(qreal scalar) +{ + quaternion.setScalar(scalar); +} + +void QDeclarativeQuaternionValueType::setX(qreal x) +{ + quaternion.setX(x); +} + +void QDeclarativeQuaternionValueType::setY(qreal y) +{ + quaternion.setY(y); +} + +void QDeclarativeQuaternionValueType::setZ(qreal z) +{ + quaternion.setZ(z); +} + +QDeclarativeMatrix4x4ValueType::QDeclarativeMatrix4x4ValueType(QObject *parent) +: QDeclarativeValueType(parent) +{ +} + +void QDeclarativeMatrix4x4ValueType::read(QObject *obj, int idx) +{ + void *a[] = { &matrix, 0 }; + QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a); +} + +void QDeclarativeMatrix4x4ValueType::write(QObject *obj, int idx, QDeclarativePropertyPrivate::WriteFlags flags) +{ + int status = -1; + void *a[] = { &matrix, 0, &status, &flags }; + QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a); +} + +QVariant QDeclarativeMatrix4x4ValueType::value() +{ + return QVariant(matrix); +} + +void QDeclarativeMatrix4x4ValueType::setValue(QVariant value) +{ + matrix = qvariant_cast<QMatrix4x4>(value); +} + QDeclarativeEasingValueType::QDeclarativeEasingValueType(QObject *parent) : QDeclarativeValueType(parent) { diff --git a/src/declarative/qml/qdeclarativevaluetype_p.h b/src/declarative/qml/qdeclarativevaluetype_p.h index d1833bb..476c73d 100644 --- a/src/declarative/qml/qdeclarativevaluetype_p.h +++ b/src/declarative/qml/qdeclarativevaluetype_p.h @@ -60,7 +60,11 @@ #include <QtCore/qrect.h> #include <QtCore/qeasingcurve.h> #include <QtCore/qvariant.h> +#include <QtGui/qvector2d.h> #include <QtGui/qvector3d.h> +#include <QtGui/qvector4d.h> +#include <QtGui/qmatrix4x4.h> +#include <QtGui/qquaternion.h> #include <QtGui/qfont.h> QT_BEGIN_NAMESPACE @@ -241,6 +245,28 @@ private: QRect rect; }; +class Q_AUTOTEST_EXPORT QDeclarativeVector2DValueType : public QDeclarativeValueType +{ + Q_PROPERTY(qreal x READ x WRITE setX) + Q_PROPERTY(qreal y READ y WRITE setY) + Q_OBJECT +public: + QDeclarativeVector2DValueType(QObject *parent = 0); + + virtual void read(QObject *, int); + virtual void write(QObject *, int, QDeclarativePropertyPrivate::WriteFlags); + virtual QVariant value(); + virtual void setValue(QVariant value); + + qreal x() const; + qreal y() const; + void setX(qreal); + void setY(qreal); + +private: + QVector2D vector; +}; + class Q_AUTOTEST_EXPORT QDeclarativeVector3DValueType : public QDeclarativeValueType { Q_PROPERTY(qreal x READ x WRITE setX) @@ -266,6 +292,127 @@ private: QVector3D vector; }; +class Q_AUTOTEST_EXPORT QDeclarativeVector4DValueType : public QDeclarativeValueType +{ + Q_PROPERTY(qreal x READ x WRITE setX) + Q_PROPERTY(qreal y READ y WRITE setY) + Q_PROPERTY(qreal z READ z WRITE setZ) + Q_PROPERTY(qreal w READ w WRITE setW) + Q_OBJECT +public: + QDeclarativeVector4DValueType(QObject *parent = 0); + + virtual void read(QObject *, int); + virtual void write(QObject *, int, QDeclarativePropertyPrivate::WriteFlags); + virtual QVariant value(); + virtual void setValue(QVariant value); + + qreal x() const; + qreal y() const; + qreal z() const; + qreal w() const; + void setX(qreal); + void setY(qreal); + void setZ(qreal); + void setW(qreal); + +private: + QVector4D vector; +}; + +class Q_AUTOTEST_EXPORT QDeclarativeQuaternionValueType : public QDeclarativeValueType +{ + Q_PROPERTY(qreal scalar READ scalar WRITE setScalar) + Q_PROPERTY(qreal x READ x WRITE setX) + Q_PROPERTY(qreal y READ y WRITE setY) + Q_PROPERTY(qreal z READ z WRITE setZ) + Q_OBJECT +public: + QDeclarativeQuaternionValueType(QObject *parent = 0); + + virtual void read(QObject *, int); + virtual void write(QObject *, int, QDeclarativePropertyPrivate::WriteFlags); + virtual QVariant value(); + virtual void setValue(QVariant value); + + qreal scalar() const; + qreal x() const; + qreal y() const; + qreal z() const; + void setScalar(qreal); + void setX(qreal); + void setY(qreal); + void setZ(qreal); + +private: + QQuaternion quaternion; +}; + +class Q_AUTOTEST_EXPORT QDeclarativeMatrix4x4ValueType : public QDeclarativeValueType +{ + Q_PROPERTY(qreal m11 READ m11 WRITE setM11) + Q_PROPERTY(qreal m12 READ m12 WRITE setM12) + Q_PROPERTY(qreal m13 READ m13 WRITE setM13) + Q_PROPERTY(qreal m14 READ m14 WRITE setM14) + Q_PROPERTY(qreal m21 READ m21 WRITE setM21) + Q_PROPERTY(qreal m22 READ m22 WRITE setM22) + Q_PROPERTY(qreal m23 READ m23 WRITE setM23) + Q_PROPERTY(qreal m24 READ m24 WRITE setM24) + Q_PROPERTY(qreal m31 READ m31 WRITE setM31) + Q_PROPERTY(qreal m32 READ m32 WRITE setM32) + Q_PROPERTY(qreal m33 READ m33 WRITE setM33) + Q_PROPERTY(qreal m34 READ m34 WRITE setM34) + Q_PROPERTY(qreal m41 READ m41 WRITE setM41) + Q_PROPERTY(qreal m42 READ m42 WRITE setM42) + Q_PROPERTY(qreal m43 READ m43 WRITE setM43) + Q_PROPERTY(qreal m44 READ m44 WRITE setM44) + Q_OBJECT +public: + QDeclarativeMatrix4x4ValueType(QObject *parent = 0); + + virtual void read(QObject *, int); + virtual void write(QObject *, int, QDeclarativePropertyPrivate::WriteFlags); + virtual QVariant value(); + virtual void setValue(QVariant value); + + qreal m11() const { return matrix(0, 0); } + qreal m12() const { return matrix(0, 1); } + qreal m13() const { return matrix(0, 2); } + qreal m14() const { return matrix(0, 3); } + qreal m21() const { return matrix(1, 0); } + qreal m22() const { return matrix(1, 1); } + qreal m23() const { return matrix(1, 2); } + qreal m24() const { return matrix(1, 3); } + qreal m31() const { return matrix(2, 0); } + qreal m32() const { return matrix(2, 1); } + qreal m33() const { return matrix(2, 2); } + qreal m34() const { return matrix(2, 3); } + qreal m41() const { return matrix(3, 0); } + qreal m42() const { return matrix(3, 1); } + qreal m43() const { return matrix(3, 2); } + qreal m44() const { return matrix(3, 3); } + + void setM11(qreal value) { matrix(0, 0) = value; } + void setM12(qreal value) { matrix(0, 1) = value; } + void setM13(qreal value) { matrix(0, 2) = value; } + void setM14(qreal value) { matrix(0, 3) = value; } + void setM21(qreal value) { matrix(1, 0) = value; } + void setM22(qreal value) { matrix(1, 1) = value; } + void setM23(qreal value) { matrix(1, 2) = value; } + void setM24(qreal value) { matrix(1, 3) = value; } + void setM31(qreal value) { matrix(2, 0) = value; } + void setM32(qreal value) { matrix(2, 1) = value; } + void setM33(qreal value) { matrix(2, 2) = value; } + void setM34(qreal value) { matrix(2, 3) = value; } + void setM41(qreal value) { matrix(3, 0) = value; } + void setM42(qreal value) { matrix(3, 1) = value; } + void setM43(qreal value) { matrix(3, 2) = value; } + void setM44(qreal value) { matrix(3, 3) = value; } + +private: + QMatrix4x4 matrix; +}; + class Q_AUTOTEST_EXPORT QDeclarativeEasingValueType : public QDeclarativeValueType { Q_OBJECT diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index 57bf726..3e63e24 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -898,6 +898,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, QDeclarativeEnginePrivate::clear(bindValues); QDeclarativeEnginePrivate::clear(parserStatus); + ep->finalizedParserStatus.clear(); return 0; } diff --git a/src/declarative/qml/qdeclarativevmemetaobject.cpp b/src/declarative/qml/qdeclarativevmemetaobject.cpp index 45f04a0..13e9c26 100644 --- a/src/declarative/qml/qdeclarativevmemetaobject.cpp +++ b/src/declarative/qml/qdeclarativevmemetaobject.cpp @@ -106,8 +106,7 @@ QDeclarativeVMEVariant::~QDeclarativeVMEVariant() void QDeclarativeVMEVariant::cleanup() { if (type == QVariant::Invalid) { - } else if (type == QMetaType::QObjectStar || - type == QMetaType::Int || + } else if (type == QMetaType::Int || type == QMetaType::Bool || type == QMetaType::Double) { type = QVariant::Invalid; diff --git a/src/declarative/qml/qdeclarativeworkerscript.cpp b/src/declarative/qml/qdeclarativeworkerscript.cpp index 138d979..c55998f 100644 --- a/src/declarative/qml/qdeclarativeworkerscript.cpp +++ b/src/declarative/qml/qdeclarativeworkerscript.cpp @@ -538,7 +538,7 @@ void QDeclarativeWorkerScriptEngine::run() by the \tt onMessage() handler of \tt myWorker. */ QDeclarativeWorkerScript::QDeclarativeWorkerScript(QObject *parent) -: QObject(parent), m_engine(0), m_scriptId(-1) +: QObject(parent), m_engine(0), m_scriptId(-1), m_componentComplete(true) { } @@ -565,7 +565,7 @@ void QDeclarativeWorkerScript::setSource(const QUrl &source) m_source = source; - if (m_engine) + if (engine()) m_engine->executeUrl(m_scriptId, m_source); emit sourceChanged(); @@ -580,7 +580,7 @@ void QDeclarativeWorkerScript::setSource(const QUrl &source) */ void QDeclarativeWorkerScript::sendMessage(const QScriptValue &message) { - if (!m_engine) { + if (!engine()) { qWarning("QDeclarativeWorkerScript: Attempt to send message before WorkerScript establishment"); return; } @@ -588,13 +588,19 @@ void QDeclarativeWorkerScript::sendMessage(const QScriptValue &message) m_engine->sendMessage(m_scriptId, QDeclarativeWorkerScriptEnginePrivate::scriptValueToVariant(message)); } -void QDeclarativeWorkerScript::componentComplete() +void QDeclarativeWorkerScript::classBegin() { - if (!m_engine) { + m_componentComplete = false; +} + +QDeclarativeWorkerScriptEngine *QDeclarativeWorkerScript::engine() +{ + if (m_engine) return m_engine; + if (m_componentComplete) { QDeclarativeEngine *engine = qmlEngine(this); if (!engine) { - qWarning("QDeclarativeWorkerScript: componentComplete() called without qmlEngine() set"); - return; + qWarning("QDeclarativeWorkerScript: engine() called without qmlEngine() set"); + return 0; } m_engine = QDeclarativeEnginePrivate::get(engine)->getWorkerScriptEngine(); @@ -602,7 +608,16 @@ void QDeclarativeWorkerScript::componentComplete() if (m_source.isValid()) m_engine->executeUrl(m_scriptId, m_source); + + return m_engine; } + return 0; +} + +void QDeclarativeWorkerScript::componentComplete() +{ + m_componentComplete = true; + engine(); // Get it started now. } /*! diff --git a/src/declarative/qml/qdeclarativeworkerscript_p.h b/src/declarative/qml/qdeclarativeworkerscript_p.h index 4019d13..dc73811 100644 --- a/src/declarative/qml/qdeclarativeworkerscript_p.h +++ b/src/declarative/qml/qdeclarativeworkerscript_p.h @@ -108,13 +108,16 @@ signals: void message(const QScriptValue &messageObject); protected: + virtual void classBegin(); virtual void componentComplete(); virtual bool event(QEvent *); private: + QDeclarativeWorkerScriptEngine *engine(); QDeclarativeWorkerScriptEngine *m_engine; int m_scriptId; QUrl m_source; + bool m_componentComplete; }; QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativexmlhttprequest.cpp b/src/declarative/qml/qdeclarativexmlhttprequest.cpp index e034165..80510f8 100644 --- a/src/declarative/qml/qdeclarativexmlhttprequest.cpp +++ b/src/declarative/qml/qdeclarativexmlhttprequest.cpp @@ -46,6 +46,7 @@ #include "private/qdeclarativerefcount_p.h" #include "private/qdeclarativeengine_p.h" #include "private/qdeclarativeexpression_p.h" +#include "qdeclarativeglobal_p.h" #include <QtCore/qobject.h> #include <QtScript/qscriptvalue.h> @@ -94,6 +95,8 @@ QT_BEGIN_NAMESPACE +DEFINE_BOOL_CONFIG_OPTION(xhrDump, QML_XHR_DUMP); + class DocumentImpl; class NodeImpl { @@ -1131,6 +1134,14 @@ void QDeclarativeXMLHttpRequest::requestFromUrl(const QUrl &url) } } + if (xhrDump()) { + qWarning().nospace() << "XMLHttpRequest: " << qPrintable(m_method) << " " << qPrintable(url.toString()); + if (!m_data.isEmpty()) { + qWarning().nospace() << " " + << qPrintable(QString::fromUtf8(m_data)); + } + } + if (m_method == QLatin1String("GET")) m_network = networkAccessManager()->get(request); else if (m_method == QLatin1String("HEAD")) @@ -1264,6 +1275,16 @@ void QDeclarativeXMLHttpRequest::finished() if (cbv.isError()) printError(cbv); } m_responseEntityBody.append(m_network->readAll()); + + if (xhrDump()) { + qWarning().nospace() << "XMLHttpRequest: RESPONSE " << qPrintable(m_url.toString()); + if (!m_responseEntityBody.isEmpty()) { + qWarning().nospace() << " " + << qPrintable(QString::fromUtf8(m_responseEntityBody)); + } + } + + m_data.clear(); destroyNetwork(); if (m_state < Loading) { diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri index 3848593..dab9767 100644 --- a/src/declarative/qml/qml.pri +++ b/src/declarative/qml/qml.pri @@ -54,6 +54,7 @@ SOURCES += \ $$PWD/qdeclarativenetworkaccessmanagerfactory.cpp \ $$PWD/qdeclarativedirparser.cpp \ $$PWD/qdeclarativeextensionplugin.cpp \ + $$PWD/qdeclarativeimport.cpp \ $$PWD/qdeclarativelist.cpp HEADERS += \ @@ -128,6 +129,7 @@ HEADERS += \ $$PWD/qdeclarativenetworkaccessmanagerfactory.h \ $$PWD/qdeclarativedirparser_p.h \ $$PWD/qdeclarativeextensioninterface.h \ + $$PWD/qdeclarativeimport_p.h \ $$PWD/qdeclarativeextensionplugin.h QT += sql diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index 4059522..0f7c946 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -55,6 +55,7 @@ #include <qdeclarativemetatype_p.h> #include <qdeclarativevaluetype_p.h> #include <qdeclarativeproperty_p.h> +#include <qdeclarativeengine_p.h> #include <qvariant.h> #include <qcolor.h> @@ -178,6 +179,10 @@ void QDeclarativeAbstractAnimation::setRunning(bool r) d->running = r; if (r == false) d->avoidPropertyValueSourceStart = true; + else { + QDeclarativeEnginePrivate *engPriv = QDeclarativeEnginePrivate::get(qmlEngine(this)); + engPriv->registerFinalizedParserStatusObject(this, this->metaObject()->indexOfSlot("componentFinalized()")); + } return; } @@ -268,6 +273,11 @@ void QDeclarativeAbstractAnimation::componentComplete() { Q_D(QDeclarativeAbstractAnimation); d->componentComplete = true; +} + +void QDeclarativeAbstractAnimation::componentFinalized() +{ + Q_D(QDeclarativeAbstractAnimation); if (d->running) { d->running = false; setRunning(true); @@ -745,7 +755,7 @@ void QDeclarativeScriptAction::setScript(const QDeclarativeScriptString &script) } /*! - \qmlproperty QString ScriptAction::scriptName + \qmlproperty string ScriptAction::scriptName This property holds the the name of the StateChangeScript to run. This property is only valid when ScriptAction is used as part of a transition. @@ -781,7 +791,7 @@ void QDeclarativeScriptActionPrivate::execute() if (ddata && ddata->outerContext && !ddata->outerContext->url.isEmpty()) expr.setSourceLocation(ddata->outerContext->url.toString(), ddata->lineNumber); expr.evaluate(); - if (expr.hasError()) + if (expr.hasError()) qmlInfo(q) << expr.error(); } } @@ -834,7 +844,7 @@ QAbstractAnimation *QDeclarativeScriptAction::qtAnimation() The PropertyAction is immediate - the target property is not animated to the selected value in any way. - + \sa QtDeclarative */ /*! @@ -864,7 +874,7 @@ void QDeclarativePropertyActionPrivate::init() This property holds an explicit target object to animate. The exact effect of the \c target property depends on how the animation - is being used. Refer to the \l animation documentation for details. + is being used. Refer to the \l {QML Animation} documentation for details. */ QObject *QDeclarativePropertyAction::target() const @@ -1320,27 +1330,27 @@ void QDeclarativeRotationAnimation::setTo(qreal t) /*! \qmlproperty enumeration RotationAnimation::direction The direction in which to rotate. - Possible values are Numerical, Clockwise, Counterclockwise, - or Shortest. + + Possible values are: \table \row - \o Numerical + \o RotationAnimation.Numerical \o Rotate by linearly interpolating between the two numbers. A rotation from 10 to 350 will rotate 340 degrees clockwise. \row - \o Clockwise + \o RotationAnimation.Clockwise \o Rotate clockwise between the two values \row - \o Counterclockwise + \o RotationAnimation.Counterclockwise \o Rotate counterclockwise between the two values \row - \o Shortest + \o RotationAnimation.Shortest \o Rotate in the direction that produces the shortest animation path. A rotation from 10 to 350 will rotate 20 degrees counterclockwise. \endtable - The default direction is Numerical. + The default direction is RotationAnimation.Numerical. */ QDeclarativeRotationAnimation::RotationDirection QDeclarativeRotationAnimation::direction() const { @@ -1605,7 +1615,7 @@ void QDeclarativePropertyAnimationPrivate::convertVariant(QVariant &variant, int Animate any objects that have changed their x or y properties in the target state using an InOutQuad easing curve: \qml - Transition { PropertyAnimation { properties: "x,y"; easing.type: "InOutQuad" } } + Transition { PropertyAnimation { properties: "x,y"; easing.type: Easing.InOutQuad } } \endqml \o In a Behavior @@ -1754,189 +1764,189 @@ void QDeclarativePropertyAnimation::setTo(const QVariant &t) Linear. \qml - PropertyAnimation { properties: "y"; easing.type: "InOutElastic"; easing.amplitude: 2.0; easing.period: 1.5 } + PropertyAnimation { properties: "y"; easing.type: Easing.InOutElastic; easing.amplitude: 2.0; easing.period: 1.5 } \endqml Available types are: \table \row - \o \c Linear + \o \c Easing.Linear \o Easing curve for a linear (t) function: velocity is constant. \o \inlineimage qeasingcurve-linear.png \row - \o \c InQuad + \o \c Easing.InQuad \o Easing curve for a quadratic (t^2) function: accelerating from zero velocity. \o \inlineimage qeasingcurve-inquad.png \row - \o \c OutQuad + \o \c Easing.OutQuad \o Easing curve for a quadratic (t^2) function: decelerating to zero velocity. \o \inlineimage qeasingcurve-outquad.png \row - \o \c InOutQuad + \o \c Easing.InOutQuad \o Easing curve for a quadratic (t^2) function: acceleration until halfway, then deceleration. \o \inlineimage qeasingcurve-inoutquad.png \row - \o \c OutInQuad + \o \c Easing.OutInQuad \o Easing curve for a quadratic (t^2) function: deceleration until halfway, then acceleration. \o \inlineimage qeasingcurve-outinquad.png \row - \o \c InCubic + \o \c Easing.InCubic \o Easing curve for a cubic (t^3) function: accelerating from zero velocity. \o \inlineimage qeasingcurve-incubic.png \row - \o \c OutCubic + \o \c Easing.OutCubic \o Easing curve for a cubic (t^3) function: decelerating from zero velocity. \o \inlineimage qeasingcurve-outcubic.png \row - \o \c InOutCubic + \o \c Easing.InOutCubic \o Easing curve for a cubic (t^3) function: acceleration until halfway, then deceleration. \o \inlineimage qeasingcurve-inoutcubic.png \row - \o \c OutInCubic + \o \c Easing.OutInCubic \o Easing curve for a cubic (t^3) function: deceleration until halfway, then acceleration. \o \inlineimage qeasingcurve-outincubic.png \row - \o \c InQuart + \o \c Easing.InQuart \o Easing curve for a quartic (t^4) function: accelerating from zero velocity. \o \inlineimage qeasingcurve-inquart.png \row - \o \c OutQuart + \o \c Easing.OutQuart \o Easing curve for a cubic (t^4) function: decelerating from zero velocity. \o \inlineimage qeasingcurve-outquart.png \row - \o \c InOutQuart + \o \c Easing.InOutQuart \o Easing curve for a cubic (t^4) function: acceleration until halfway, then deceleration. \o \inlineimage qeasingcurve-inoutquart.png \row - \o \c OutInQuart + \o \c Easing.OutInQuart \o Easing curve for a cubic (t^4) function: deceleration until halfway, then acceleration. \o \inlineimage qeasingcurve-outinquart.png \row - \o \c InQuint + \o \c Easing.InQuint \o Easing curve for a quintic (t^5) function: accelerating from zero velocity. \o \inlineimage qeasingcurve-inquint.png \row - \o \c OutQuint + \o \c Easing.OutQuint \o Easing curve for a cubic (t^5) function: decelerating from zero velocity. \o \inlineimage qeasingcurve-outquint.png \row - \o \c InOutQuint + \o \c Easing.InOutQuint \o Easing curve for a cubic (t^5) function: acceleration until halfway, then deceleration. \o \inlineimage qeasingcurve-inoutquint.png \row - \o \c OutInQuint + \o \c Easing.OutInQuint \o Easing curve for a cubic (t^5) function: deceleration until halfway, then acceleration. \o \inlineimage qeasingcurve-outinquint.png \row - \o \c InSine + \o \c Easing.InSine \o Easing curve for a sinusoidal (sin(t)) function: accelerating from zero velocity. \o \inlineimage qeasingcurve-insine.png \row - \o \c OutSine + \o \c Easing.OutSine \o Easing curve for a sinusoidal (sin(t)) function: decelerating from zero velocity. \o \inlineimage qeasingcurve-outsine.png \row - \o \c InOutSine + \o \c Easing.InOutSine \o Easing curve for a sinusoidal (sin(t)) function: acceleration until halfway, then deceleration. \o \inlineimage qeasingcurve-inoutsine.png \row - \o \c OutInSine + \o \c Easing.OutInSine \o Easing curve for a sinusoidal (sin(t)) function: deceleration until halfway, then acceleration. \o \inlineimage qeasingcurve-outinsine.png \row - \o \c InExpo + \o \c Easing.InExpo \o Easing curve for an exponential (2^t) function: accelerating from zero velocity. \o \inlineimage qeasingcurve-inexpo.png \row - \o \c OutExpo + \o \c Easing.OutExpo \o Easing curve for an exponential (2^t) function: decelerating from zero velocity. \o \inlineimage qeasingcurve-outexpo.png \row - \o \c InOutExpo + \o \c Easing.InOutExpo \o Easing curve for an exponential (2^t) function: acceleration until halfway, then deceleration. \o \inlineimage qeasingcurve-inoutexpo.png \row - \o \c OutInExpo + \o \c Easing.OutInExpo \o Easing curve for an exponential (2^t) function: deceleration until halfway, then acceleration. \o \inlineimage qeasingcurve-outinexpo.png \row - \o \c InCirc + \o \c Easing.InCirc \o Easing curve for a circular (sqrt(1-t^2)) function: accelerating from zero velocity. \o \inlineimage qeasingcurve-incirc.png \row - \o \c OutCirc + \o \c Easing.OutCirc \o Easing curve for a circular (sqrt(1-t^2)) function: decelerating from zero velocity. \o \inlineimage qeasingcurve-outcirc.png \row - \o \c InOutCirc + \o \c Easing.InOutCirc \o Easing curve for a circular (sqrt(1-t^2)) function: acceleration until halfway, then deceleration. \o \inlineimage qeasingcurve-inoutcirc.png \row - \o \c OutInCirc + \o \c Easing.OutInCirc \o Easing curve for a circular (sqrt(1-t^2)) function: deceleration until halfway, then acceleration. \o \inlineimage qeasingcurve-outincirc.png \row - \o \c InElastic + \o \c Easing.InElastic \o Easing curve for an elastic (exponentially decaying sine wave) function: accelerating from zero velocity. \br The peak amplitude can be set with the \e amplitude parameter, and the period of decay by the \e period parameter. \o \inlineimage qeasingcurve-inelastic.png \row - \o \c OutElastic + \o \c Easing.OutElastic \o Easing curve for an elastic (exponentially decaying sine wave) function: decelerating from zero velocity. \br The peak amplitude can be set with the \e amplitude parameter, and the period of decay by the \e period parameter. \o \inlineimage qeasingcurve-outelastic.png \row - \o \c InOutElastic + \o \c Easing.InOutElastic \o Easing curve for an elastic (exponentially decaying sine wave) function: acceleration until halfway, then deceleration. \o \inlineimage qeasingcurve-inoutelastic.png \row - \o \c OutInElastic + \o \c Easing.OutInElastic \o Easing curve for an elastic (exponentially decaying sine wave) function: deceleration until halfway, then acceleration. \o \inlineimage qeasingcurve-outinelastic.png \row - \o \c InBack + \o \c Easing.InBack \o Easing curve for a back (overshooting cubic function: (s+1)*t^3 - s*t^2) easing in: accelerating from zero velocity. \o \inlineimage qeasingcurve-inback.png \row - \o \c OutBack + \o \c Easing.OutBack \o Easing curve for a back (overshooting cubic function: (s+1)*t^3 - s*t^2) easing out: decelerating to zero velocity. \o \inlineimage qeasingcurve-outback.png \row - \o \c InOutBack + \o \c Easing.InOutBack \o Easing curve for a back (overshooting cubic function: (s+1)*t^3 - s*t^2) easing in/out: acceleration until halfway, then deceleration. \o \inlineimage qeasingcurve-inoutback.png \row - \o \c OutInBack + \o \c Easing.OutInBack \o Easing curve for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing out/in: deceleration until halfway, then acceleration. \o \inlineimage qeasingcurve-outinback.png \row - \o \c InBounce + \o \c Easing.InBounce \o Easing curve for a bounce (exponentially decaying parabolic bounce) function: accelerating from zero velocity. \o \inlineimage qeasingcurve-inbounce.png \row - \o \c OutBounce + \o \c Easing.OutBounce \o Easing curve for a bounce (exponentially decaying parabolic bounce) function: decelerating from zero velocity. \o \inlineimage qeasingcurve-outbounce.png \row - \o \c InOutBounce + \o \c Easing.InOutBounce \o Easing curve for a bounce (exponentially decaying parabolic bounce) function easing in/out: acceleration until halfway, then deceleration. \o \inlineimage qeasingcurve-inoutbounce.png \row - \o \c OutInBounce + \o \c Easing.OutInBounce \o Easing curve for a bounce (exponentially decaying parabolic bounce) function easing out/in: deceleration until halfway, then acceleration. \o \inlineimage qeasingcurve-outinbounce.png \endtable - easing.amplitude is not applicable for all curve types. It is only applicable for bounce and elastic curves (curves of type - QEasingCurve::InBounce, QEasingCurve::OutBounce, QEasingCurve::InOutBounce, QEasingCurve::OutInBounce, QEasingCurve::InElastic, - QEasingCurve::OutElastic, QEasingCurve::InOutElastic or QEasingCurve::OutInElastic). + easing.amplitude is only applicable for bounce and elastic curves (curves of type + Easing.InBounce, Easing.OutBounce, Easing.InOutBounce, Easing.OutInBounce, Easing.InElastic, + Easing.OutElastic, Easing.InOutElastic or Easing.OutInElastic). - easing.overshoot is not applicable for all curve types. It is only applicable if type is: QEasingCurve::InBack, QEasingCurve::OutBack, - QEasingCurve::InOutBack or QEasingCurve::OutInBack. + easing.overshoot is only applicable if type is: Easing.InBack, Easing.OutBack, + Easing.InOutBack or Easing.OutInBack. - easing.period is not applicable for all curve types. It is only applicable if type is: QEasingCurve::InElastic, QEasingCurve::OutElastic, - QEasingCurve::InOutElastic or QEasingCurve::OutInElastic. + easing.period is only applicable if type is: Easing.InElastic, Easing.OutElastic, + Easing.InOutElastic or Easing.OutInElastic. */ QEasingCurve QDeclarativePropertyAnimation::easing() const { @@ -2337,7 +2347,7 @@ QDeclarativeParentAnimation::~QDeclarativeParentAnimation() } /*! - \qmlproperty item ParentAnimation::target + \qmlproperty Item ParentAnimation::target The item to reparent. When used in a transition, if no target is specified all @@ -2360,7 +2370,7 @@ void QDeclarativeParentAnimation::setTarget(QDeclarativeItem *target) } /*! - \qmlproperty item ParentAnimation::newParent + \qmlproperty Item ParentAnimation::newParent The new parent to animate to. If not set, then the parent defined in the end state of the transition. @@ -2382,7 +2392,7 @@ void QDeclarativeParentAnimation::setNewParent(QDeclarativeItem *newParent) } /*! - \qmlproperty item ParentAnimation::via + \qmlproperty Item ParentAnimation::via The item to reparent via. This provides a way to do an unclipped animation when both the old parent and new parent are clipped @@ -2730,7 +2740,7 @@ void QDeclarativeAnchorAnimation::setDuration(int duration) Linear. \qml - AnchorAnimation { easing.type: "InOutQuad" } + AnchorAnimation { easing.type: Easing.InOutQuad } \endqml See the \l{PropertyAnimation::easing.type} documentation for information diff --git a/src/declarative/util/qdeclarativeanimation_p.h b/src/declarative/util/qdeclarativeanimation_p.h index 40c893c..e7cd8a8 100644 --- a/src/declarative/util/qdeclarativeanimation_p.h +++ b/src/declarative/util/qdeclarativeanimation_p.h @@ -133,6 +133,7 @@ public: private Q_SLOTS: void timelineComplete(); + void componentFinalized(); private: virtual void setTarget(const QDeclarativeProperty &); diff --git a/src/declarative/util/qdeclarativebehavior.cpp b/src/declarative/util/qdeclarativebehavior.cpp index 1089d31..ba90007 100644 --- a/src/declarative/util/qdeclarativebehavior.cpp +++ b/src/declarative/util/qdeclarativebehavior.cpp @@ -48,6 +48,7 @@ #include <qdeclarativeinfo.h> #include <qdeclarativeproperty_p.h> #include <qdeclarativeguard_p.h> +#include <qdeclarativeengine_p.h> #include <private/qobject_p.h> @@ -57,12 +58,13 @@ class QDeclarativeBehaviorPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QDeclarativeBehavior) public: - QDeclarativeBehaviorPrivate() : animation(0), enabled(true) {} + QDeclarativeBehaviorPrivate() : animation(0), enabled(true), finalized(false) {} QDeclarativeProperty property; QVariant currentValue; QDeclarativeGuard<QDeclarativeAbstractAnimation> animation; bool enabled; + bool finalized; }; /*! @@ -80,7 +82,7 @@ public: y: 200 // initial value Behavior on y { NumberAnimation { - easing.type: "OutBounce" + easing.type: Easing.OutBounce easing.amplitude: 100 duration: 200 } @@ -158,7 +160,7 @@ void QDeclarativeBehavior::write(const QVariant &value) { Q_D(QDeclarativeBehavior); qmlExecuteDeferred(this); - if (!d->animation || !d->enabled) { + if (!d->animation || !d->enabled || !d->finalized) { QDeclarativePropertyPrivate::write(d->property, value, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding); return; } @@ -189,6 +191,15 @@ void QDeclarativeBehavior::setTarget(const QDeclarativeProperty &property) d->currentValue = property.read(); if (d->animation) d->animation->setDefaultTarget(property); + + QDeclarativeEnginePrivate *engPriv = QDeclarativeEnginePrivate::get(qmlEngine(this)); + engPriv->registerFinalizedParserStatusObject(this, this->metaObject()->indexOfSlot("componentFinalized()")); +} + +void QDeclarativeBehavior::componentFinalized() +{ + Q_D(QDeclarativeBehavior); + d->finalized = true; } QT_END_NAMESPACE diff --git a/src/declarative/util/qdeclarativebehavior_p.h b/src/declarative/util/qdeclarativebehavior_p.h index e8a809f..6c10eec 100644 --- a/src/declarative/util/qdeclarativebehavior_p.h +++ b/src/declarative/util/qdeclarativebehavior_p.h @@ -82,6 +82,9 @@ public: Q_SIGNALS: void enabledChanged(); + +private Q_SLOTS: + void componentFinalized(); }; QT_END_NAMESPACE diff --git a/src/declarative/util/qdeclarativebind.cpp b/src/declarative/util/qdeclarativebind.cpp index 5516628..5fab631 100644 --- a/src/declarative/util/qdeclarativebind.cpp +++ b/src/declarative/util/qdeclarativebind.cpp @@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE class QDeclarativeBindPrivate : public QObjectPrivate { public: - QDeclarativeBindPrivate() : when(true), componentComplete(false), obj(0) {} + QDeclarativeBindPrivate() : when(true), componentComplete(true), obj(0) {} bool when : 1; bool componentComplete : 1; @@ -98,7 +98,6 @@ public: /*! \internal \class QDeclarativeBind - \ingroup group_utility \brief The QDeclarativeBind class allows arbitrary property bindings to be created. Simple bindings are usually earier to do in-place rather than creating a @@ -198,6 +197,12 @@ void QDeclarativeBind::setValue(const QVariant &v) eval(); } +void QDeclarativeBind::classBegin() +{ + Q_D(QDeclarativeBind); + d->componentComplete = false; +} + void QDeclarativeBind::componentComplete() { Q_D(QDeclarativeBind); diff --git a/src/declarative/util/qdeclarativebind_p.h b/src/declarative/util/qdeclarativebind_p.h index f756e80..f89c2eb 100644 --- a/src/declarative/util/qdeclarativebind_p.h +++ b/src/declarative/util/qdeclarativebind_p.h @@ -80,6 +80,7 @@ public: void setValue(const QVariant &); protected: + virtual void classBegin(); virtual void componentComplete(); private: diff --git a/src/declarative/util/qdeclarativeconnections.cpp b/src/declarative/util/qdeclarativeconnections.cpp index 20d878b..ffa160f 100644 --- a/src/declarative/util/qdeclarativeconnections.cpp +++ b/src/declarative/util/qdeclarativeconnections.cpp @@ -57,11 +57,13 @@ QT_BEGIN_NAMESPACE class QDeclarativeConnectionsPrivate : public QObjectPrivate { public: - QDeclarativeConnectionsPrivate() : target(0), componentcomplete(false) {} + QDeclarativeConnectionsPrivate() : target(0), targetSet(false), ignoreUnknownSignals(false), componentcomplete(true) {} QList<QDeclarativeBoundSignal*> boundsignals; QObject *target; + bool targetSet; + bool ignoreUnknownSignals; bool componentcomplete; QByteArray data; @@ -139,17 +141,21 @@ QDeclarativeConnections::~QDeclarativeConnections() \qmlproperty Object Connections::target This property holds the object that sends the signal. - By default, the target is assumed to be the parent of the Connections. + If not set at all, the target defaults to be the parent of the Connections. + + If set to null, no connection is made and any signal handlers are ignored + until the target is not null. */ QObject *QDeclarativeConnections::target() const { Q_D(const QDeclarativeConnections); - return d->target ? d->target : parent(); + return d->targetSet ? d->target : parent(); } void QDeclarativeConnections::setTarget(QObject *obj) { Q_D(QDeclarativeConnections); + d->targetSet = true; // even if setting to 0, it is *set* if (d->target == obj) return; foreach (QDeclarativeBoundSignal *s, d->boundsignals) { @@ -166,6 +172,29 @@ void QDeclarativeConnections::setTarget(QObject *obj) emit targetChanged(); } +/*! + \qmlproperty bool Connections::ignoreUnknownSignals + + Normally, you will get a runtime error if you try to connect + to signals on an object which the object does not have. + + By setting this flag to true, such errors are ignored. This is + useful if you intend to connect to different types of object, handling + a different set of signals for each. +*/ +bool QDeclarativeConnections::ignoreUnknownSignals() const +{ + Q_D(const QDeclarativeConnections); + return d->ignoreUnknownSignals; +} + +void QDeclarativeConnections::setIgnoreUnknownSignals(bool ignore) +{ + Q_D(QDeclarativeConnections); + d->ignoreUnknownSignals = ignore; +} + + QByteArray QDeclarativeConnectionsParser::compile(const QList<QDeclarativeCustomParserProperty> &props) @@ -220,7 +249,7 @@ void QDeclarativeConnectionsParser::setCustomData(QObject *object, void QDeclarativeConnections::connectSignals() { Q_D(QDeclarativeConnections); - if (!d->componentcomplete) + if (!d->componentcomplete || (d->targetSet && !target())) return; QDataStream ds(d->data); @@ -230,19 +259,24 @@ void QDeclarativeConnections::connectSignals() QString script; ds >> script; QDeclarativeProperty prop(target(), propName); - if (!prop.isValid()) { - qmlInfo(this) << tr("Cannot assign to non-existent property \"%1\"").arg(propName); - } else if (prop.type() & QDeclarativeProperty::SignalProperty) { + if (prop.isValid() && (prop.type() & QDeclarativeProperty::SignalProperty)) { QDeclarativeBoundSignal *signal = new QDeclarativeBoundSignal(target(), prop.method(), this); signal->setExpression(new QDeclarativeExpression(qmlContext(this), script, 0)); d->boundsignals += signal; } else { - qmlInfo(this) << tr("Cannot assign to non-existent property \"%1\"").arg(propName); + if (!d->ignoreUnknownSignals) + qmlInfo(this) << tr("Cannot assign to non-existent property \"%1\"").arg(propName); } } } +void QDeclarativeConnections::classBegin() +{ + Q_D(QDeclarativeConnections); + d->componentcomplete=false; +} + void QDeclarativeConnections::componentComplete() { Q_D(QDeclarativeConnections); diff --git a/src/declarative/util/qdeclarativeconnections_p.h b/src/declarative/util/qdeclarativeconnections_p.h index 3eacf12..a914166 100644 --- a/src/declarative/util/qdeclarativeconnections_p.h +++ b/src/declarative/util/qdeclarativeconnections_p.h @@ -65,6 +65,7 @@ class Q_DECLARATIVE_EXPORT QDeclarativeConnections : public QObject, public QDec Q_INTERFACES(QDeclarativeParserStatus) Q_PROPERTY(QObject *target READ target WRITE setTarget NOTIFY targetChanged) + Q_PROPERTY(bool ignoreUnknownSignals READ ignoreUnknownSignals WRITE setIgnoreUnknownSignals) public: QDeclarativeConnections(QObject *parent=0); @@ -73,11 +74,15 @@ public: QObject *target() const; void setTarget(QObject *); + bool ignoreUnknownSignals() const; + void setIgnoreUnknownSignals(bool ignore); + Q_SIGNALS: void targetChanged(); private: void connectSignals(); + void classBegin(); void componentComplete(); }; diff --git a/src/declarative/util/qdeclarativefontloader.cpp b/src/declarative/util/qdeclarativefontloader.cpp index 4115193..adfcd62 100644 --- a/src/declarative/util/qdeclarativefontloader.cpp +++ b/src/declarative/util/qdeclarativefontloader.cpp @@ -78,7 +78,6 @@ public: /*! \qmlclass FontLoader QDeclarativeFontLoader \since 4.7 - \ingroup group_utility \brief This item allows using fonts by name or url. Example: @@ -186,10 +185,10 @@ void QDeclarativeFontLoader::setName(const QString &name) This property holds the status of font loading. It can be one of: \list - \o Null - no font has been set - \o Ready - the font has been loaded - \o Loading - the font is currently being loaded - \o Error - an error occurred while loading the font + \o FontLoader.Null - no font has been set + \o FontLoader.Ready - the font has been loaded + \o FontLoader.Loading - the font is currently being loaded + \o FontLoader.Error - an error occurred while loading the font \endlist Note that a change in the status property does not cause anything to happen diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp index 3810256..0985a6b 100644 --- a/src/declarative/util/qdeclarativelistmodel.cpp +++ b/src/declarative/util/qdeclarativelistmodel.cpp @@ -591,7 +591,7 @@ void QDeclarativeListModel::set(int index, const QScriptValue& valuemap) Changes the \a property of the item at \a index in the list model to \a value. \code - fruitModel.set(3, "cost", 5.95) + fruitModel.setProperty(3, "cost", 5.95) \endcode The \a index must be an element in the list. diff --git a/src/declarative/util/qdeclarativeopenmetaobject.cpp b/src/declarative/util/qdeclarativeopenmetaobject.cpp index 0e5aaa6..ba5d534 100644 --- a/src/declarative/util/qdeclarativeopenmetaobject.cpp +++ b/src/declarative/util/qdeclarativeopenmetaobject.cpp @@ -305,7 +305,7 @@ void QDeclarativeOpenMetaObject::setCached(bool c) QDeclarativeData *qmldata = QDeclarativeData::get(d->object, true); if (d->cacheProperties) { if (!d->type->d->cache) - d->type->d->cache = QDeclarativePropertyCache::create(d->type->d->engine, this); + d->type->d->cache = new QDeclarativePropertyCache(d->type->d->engine, this); qmldata->propertyCache = d->type->d->cache; d->type->d->cache->addref(); } else { diff --git a/src/declarative/util/qdeclarativepropertychanges.cpp b/src/declarative/util/qdeclarativepropertychanges.cpp index 4b2d5a0..94780c4 100644 --- a/src/declarative/util/qdeclarativepropertychanges.cpp +++ b/src/declarative/util/qdeclarativepropertychanges.cpp @@ -51,6 +51,7 @@ #include <qdeclarativecontext.h> #include <qdeclarativeguard_p.h> #include <qdeclarativeproperty_p.h> +#include <qdeclarativecontext_p.h> #include <QtCore/qdebug.h> @@ -160,13 +161,22 @@ public: QDeclarativeExpression *rewindExpression; QDeclarativeGuard<QDeclarativeExpression> ownedExpression; + virtual bool changesBindings() { return true; } + virtual void clearBindings() { + ownedExpression = QDeclarativePropertyPrivate::setSignalExpression(property, 0); + } + virtual void execute(Reason) { - ownedExpression = QDeclarativePropertyPrivate::setSignalExpression(property, expression); + QDeclarativePropertyPrivate::setSignalExpression(property, expression); + if (ownedExpression == expression) + ownedExpression = 0; } virtual bool isReversable() { return true; } virtual void reverse(Reason) { - ownedExpression = QDeclarativePropertyPrivate::setSignalExpression(property, reverseExpression); + QDeclarativePropertyPrivate::setSignalExpression(property, reverseExpression); + if (ownedExpression == reverseExpression) + ownedExpression = 0; } virtual void saveOriginals() { @@ -174,11 +184,26 @@ public: reverseExpression = rewindExpression; } + virtual void copyOriginals(QDeclarativeActionEvent *other) + { + QDeclarativeReplaceSignalHandler *rsh = static_cast<QDeclarativeReplaceSignalHandler*>(other); + saveCurrentValues(); + if (rsh == this) + return; + reverseExpression = rsh->reverseExpression; + if (rsh->ownedExpression == reverseExpression) { + ownedExpression = rsh->ownedExpression; + rsh->ownedExpression = 0; + } + } + virtual void rewind() { - ownedExpression = QDeclarativePropertyPrivate::setSignalExpression(property, rewindExpression); + QDeclarativePropertyPrivate::setSignalExpression(property, rewindExpression); + if (ownedExpression == rewindExpression) + ownedExpression = 0; } virtual void saveCurrentValues() { - rewindExpression = QDeclarativePropertyPrivate::signalExpression(property); + rewindExpression = QDeclarativePropertyPrivate::signalExpression(property); } virtual bool override(QDeclarativeActionEvent*other) { @@ -302,12 +327,18 @@ void QDeclarativePropertyChangesPrivate::decode() QDeclarativeProperty prop = property(name); //### better way to check for signal property? if (prop.type() & QDeclarativeProperty::SignalProperty) { QDeclarativeExpression *expression = new QDeclarativeExpression(qmlContext(q), data.toString(), object); + QDeclarativeData *ddata = QDeclarativeData::get(q); + if (ddata && ddata->outerContext && !ddata->outerContext->url.isEmpty()) + expression->setSourceLocation(ddata->outerContext->url.toString(), ddata->lineNumber); QDeclarativeReplaceSignalHandler *handler = new QDeclarativeReplaceSignalHandler; handler->property = prop; handler->expression = expression; signalReplacements << handler; } else if (isScript) { QDeclarativeExpression *expression = new QDeclarativeExpression(qmlContext(q), data.toString(), object); + QDeclarativeData *ddata = QDeclarativeData::get(q); + if (ddata && ddata->outerContext && !ddata->outerContext->url.isEmpty()) + expression->setSourceLocation(ddata->outerContext->url.toString(), ddata->lineNumber); expressions << qMakePair(name, expression); } else { properties << qMakePair(name, data); @@ -437,9 +468,11 @@ QDeclarativePropertyChanges::ActionList QDeclarativePropertyChanges::actions() if (d->isExplicit) { a.toValue = d->expressions.at(ii).second->evaluate(); } else { + QDeclarativeExpression *e = d->expressions.at(ii).second; QDeclarativeBinding *newBinding = - new QDeclarativeBinding(d->expressions.at(ii).second->expression(), object(), qmlContext(this)); + new QDeclarativeBinding(e->expression(), object(), qmlContext(this)); newBinding->setTarget(prop); + newBinding->setSourceLocation(e->sourceFile(), e->lineNumber()); a.toBinding = newBinding; a.deletableToBinding = true; } diff --git a/src/declarative/util/qdeclarativesmoothedanimation.cpp b/src/declarative/util/qdeclarativesmoothedanimation.cpp index 19a00ee..bd48ef0 100644 --- a/src/declarative/util/qdeclarativesmoothedanimation.cpp +++ b/src/declarative/util/qdeclarativesmoothedanimation.cpp @@ -388,10 +388,10 @@ void QDeclarativeSmoothedAnimation::transition(QDeclarativeStateActions &actions Sets how the SmoothedAnimation behaves if an animation direction is reversed. - If reversing mode is \c Eased, the animation will smoothly decelerate, and - then reverse direction. If the reversing mode is \c Immediate, the + If reversing mode is \c SmoothedAnimation.Eased, the animation will smoothly decelerate, and + then reverse direction. If the reversing mode is \c SmoothedAnimation.Immediate, the animation will immediately begin accelerating in the reverse direction, - begining with a velocity of 0. If the reversing mode is \c Sync, the + begining with a velocity of 0. If the reversing mode is \c SmoothedAnimation.Sync, the property is immediately set to the target value. */ QDeclarativeSmoothedAnimation::ReversingMode QDeclarativeSmoothedAnimation::reversingMode() const diff --git a/src/declarative/util/qdeclarativesmoothedfollow.cpp b/src/declarative/util/qdeclarativesmoothedfollow.cpp index 3ed9257..f70df9d 100644 --- a/src/declarative/util/qdeclarativesmoothedfollow.cpp +++ b/src/declarative/util/qdeclarativesmoothedfollow.cpp @@ -143,10 +143,10 @@ QDeclarativeSmoothedFollowPrivate::QDeclarativeSmoothedFollowPrivate() Sets how the SmoothedFollow behaves if an animation direction is reversed. - If reversing mode is \c Eased, the animation will smoothly decelerate, and - then reverse direction. If the reversing mode is \c Immediate, the + If reversing mode is \c SmoothedFollow.Eased, the animation will smoothly decelerate, and + then reverse direction. If the reversing mode is \c SmoothedFollow.Immediate, the animation will immediately begin accelerating in the reverse direction, - begining with a velocity of 0. If the reversing mode is \c Sync, the + begining with a velocity of 0. If the reversing mode is \c SmoothedFollow.Sync, the property is immediately set to the target value. */ QDeclarativeSmoothedFollow::ReversingMode QDeclarativeSmoothedFollow::reversingMode() const diff --git a/src/declarative/util/qdeclarativespringfollow.cpp b/src/declarative/util/qdeclarativespringfollow.cpp index 70077f3..aae66ac 100644 --- a/src/declarative/util/qdeclarativespringfollow.cpp +++ b/src/declarative/util/qdeclarativespringfollow.cpp @@ -227,7 +227,7 @@ void QDeclarativeSpringFollowPrivate::stop() loops: Animation.Infinite NumberAnimation { to: 200 - easing.type: "OutBounce" + easing.type: Easing.OutBounce easing.amplitude: 100 duration: 2000 } diff --git a/src/declarative/util/qdeclarativestate.cpp b/src/declarative/util/qdeclarativestate.cpp index 861cbc8..ea209aa 100644 --- a/src/declarative/util/qdeclarativestate.cpp +++ b/src/declarative/util/qdeclarativestate.cpp @@ -149,7 +149,6 @@ QDeclarativeStateOperation::QDeclarativeStateOperation(QObjectPrivate &dd, QObje \class QDeclarativeState \brief The QDeclarativeState class allows you to define configurations of objects and properties. - \ingroup group_states QDeclarativeState allows you to specify a state as a set of batched changes from the default configuration. diff --git a/src/declarative/util/qdeclarativestategroup.cpp b/src/declarative/util/qdeclarativestategroup.cpp index 5b51495..9b042d7 100644 --- a/src/declarative/util/qdeclarativestategroup.cpp +++ b/src/declarative/util/qdeclarativestategroup.cpp @@ -47,6 +47,7 @@ #include <qdeclarativebinding_p.h> #include <qdeclarativeglobal_p.h> +#include <QtCore/qstringbuilder.h> #include <QtCore/qdebug.h> #include <private/qobject_p.h> @@ -62,7 +63,7 @@ class QDeclarativeStateGroupPrivate : public QObjectPrivate public: QDeclarativeStateGroupPrivate() : nullState(0), componentComplete(true), - ignoreTrans(false), applyingState(false) {} + ignoreTrans(false), applyingState(false), unnamedCount(0) {} QString currentState; QDeclarativeState *nullState; @@ -78,6 +79,7 @@ public: bool componentComplete; bool ignoreTrans; bool applyingState; + int unnamedCount; QDeclarativeTransition *findTransition(const QString &from, const QString &to); void setCurrentStateInternal(const QString &state, bool = false); @@ -259,6 +261,12 @@ void QDeclarativeStateGroup::componentComplete() Q_D(QDeclarativeStateGroup); d->componentComplete = true; + for (int ii = 0; ii < d->states.count(); ++ii) { + QDeclarativeState *state = d->states.at(ii); + if (state->name().isEmpty()) + state->setName(QLatin1String("anonymousState") % QString::number(++d->unnamedCount)); + } + if (d->updateAutoState()) { return; } else if (!d->currentState.isEmpty()) { diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp index 689f53c..a93a25d 100644 --- a/src/declarative/util/qdeclarativestateoperations.cpp +++ b/src/declarative/util/qdeclarativestateoperations.cpp @@ -1056,40 +1056,41 @@ void QDeclarativeAnchorChanges::execute(Reason reason) if (!d->target) return; + QDeclarativeItemPrivate *targetPrivate = QDeclarativeItemPrivate::get(d->target); //incorporate any needed "reverts" if (d->applyOrigLeft) { if (!d->origLeftBinding) - d->target->anchors()->resetLeft(); + targetPrivate->anchors()->resetLeft(); QDeclarativePropertyPrivate::setBinding(d->leftProp, d->origLeftBinding); } if (d->applyOrigRight) { if (!d->origRightBinding) - d->target->anchors()->resetRight(); + targetPrivate->anchors()->resetRight(); QDeclarativePropertyPrivate::setBinding(d->rightProp, d->origRightBinding); } if (d->applyOrigHCenter) { if (!d->origHCenterBinding) - d->target->anchors()->resetHorizontalCenter(); + targetPrivate->anchors()->resetHorizontalCenter(); QDeclarativePropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding); } if (d->applyOrigTop) { if (!d->origTopBinding) - d->target->anchors()->resetTop(); + targetPrivate->anchors()->resetTop(); QDeclarativePropertyPrivate::setBinding(d->topProp, d->origTopBinding); } if (d->applyOrigBottom) { if (!d->origBottomBinding) - d->target->anchors()->resetBottom(); + targetPrivate->anchors()->resetBottom(); QDeclarativePropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding); } if (d->applyOrigVCenter) { if (!d->origVCenterBinding) - d->target->anchors()->resetVerticalCenter(); + targetPrivate->anchors()->resetVerticalCenter(); QDeclarativePropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding); } if (d->applyOrigBaseline) { if (!d->origBaselineBinding) - d->target->anchors()->resetBaseline(); + targetPrivate->anchors()->resetBaseline(); QDeclarativePropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding); } @@ -1105,31 +1106,31 @@ void QDeclarativeAnchorChanges::execute(Reason reason) //reset any anchors that have been specified as "undefined" if (d->anchorSet->d_func()->resetAnchors & QDeclarativeAnchors::LeftAnchor) { - d->target->anchors()->resetLeft(); + targetPrivate->anchors()->resetLeft(); QDeclarativePropertyPrivate::setBinding(d->leftProp, 0); } if (d->anchorSet->d_func()->resetAnchors & QDeclarativeAnchors::RightAnchor) { - d->target->anchors()->resetRight(); + targetPrivate->anchors()->resetRight(); QDeclarativePropertyPrivate::setBinding(d->rightProp, 0); } if (d->anchorSet->d_func()->resetAnchors & QDeclarativeAnchors::HCenterAnchor) { - d->target->anchors()->resetHorizontalCenter(); + targetPrivate->anchors()->resetHorizontalCenter(); QDeclarativePropertyPrivate::setBinding(d->hCenterProp, 0); } if (d->anchorSet->d_func()->resetAnchors & QDeclarativeAnchors::TopAnchor) { - d->target->anchors()->resetTop(); + targetPrivate->anchors()->resetTop(); QDeclarativePropertyPrivate::setBinding(d->topProp, 0); } if (d->anchorSet->d_func()->resetAnchors & QDeclarativeAnchors::BottomAnchor) { - d->target->anchors()->resetBottom(); + targetPrivate->anchors()->resetBottom(); QDeclarativePropertyPrivate::setBinding(d->bottomProp, 0); } if (d->anchorSet->d_func()->resetAnchors & QDeclarativeAnchors::VCenterAnchor) { - d->target->anchors()->resetVerticalCenter(); + targetPrivate->anchors()->resetVerticalCenter(); QDeclarativePropertyPrivate::setBinding(d->vCenterProp, 0); } if (d->anchorSet->d_func()->resetAnchors & QDeclarativeAnchors::BaselineAnchor) { - d->target->anchors()->resetBaseline(); + targetPrivate->anchors()->resetBaseline(); QDeclarativePropertyPrivate::setBinding(d->baselineProp, 0); } @@ -1161,51 +1162,52 @@ void QDeclarativeAnchorChanges::reverse(Reason reason) if (!d->target) return; + QDeclarativeItemPrivate *targetPrivate = QDeclarativeItemPrivate::get(d->target); //reset any anchors set by the state if (d->leftBinding) { - d->target->anchors()->resetLeft(); + targetPrivate->anchors()->resetLeft(); QDeclarativePropertyPrivate::setBinding(d->leftBinding->property(), 0); if (reason == ActualChange) { d->leftBinding->destroy(); d->leftBinding = 0; } } if (d->rightBinding) { - d->target->anchors()->resetRight(); + targetPrivate->anchors()->resetRight(); QDeclarativePropertyPrivate::setBinding(d->rightBinding->property(), 0); if (reason == ActualChange) { d->rightBinding->destroy(); d->rightBinding = 0; } } if (d->hCenterBinding) { - d->target->anchors()->resetHorizontalCenter(); + targetPrivate->anchors()->resetHorizontalCenter(); QDeclarativePropertyPrivate::setBinding(d->hCenterBinding->property(), 0); if (reason == ActualChange) { d->hCenterBinding->destroy(); d->hCenterBinding = 0; } } if (d->topBinding) { - d->target->anchors()->resetTop(); + targetPrivate->anchors()->resetTop(); QDeclarativePropertyPrivate::setBinding(d->topBinding->property(), 0); if (reason == ActualChange) { d->topBinding->destroy(); d->topBinding = 0; } } if (d->bottomBinding) { - d->target->anchors()->resetBottom(); + targetPrivate->anchors()->resetBottom(); QDeclarativePropertyPrivate::setBinding(d->bottomBinding->property(), 0); if (reason == ActualChange) { d->bottomBinding->destroy(); d->bottomBinding = 0; } } if (d->vCenterBinding) { - d->target->anchors()->resetVerticalCenter(); + targetPrivate->anchors()->resetVerticalCenter(); QDeclarativePropertyPrivate::setBinding(d->vCenterBinding->property(), 0); if (reason == ActualChange) { d->vCenterBinding->destroy(); d->vCenterBinding = 0; } } if (d->baselineBinding) { - d->target->anchors()->resetBaseline(); + targetPrivate->anchors()->resetBaseline(); QDeclarativePropertyPrivate::setBinding(d->baselineBinding->property(), 0); if (reason == ActualChange) { d->baselineBinding->destroy(); d->baselineBinding = 0; @@ -1335,37 +1337,38 @@ void QDeclarativeAnchorChanges::clearBindings() d->fromWidth = d->target->width(); d->fromHeight = d->target->height(); + QDeclarativeItemPrivate *targetPrivate = QDeclarativeItemPrivate::get(d->target); //reset any anchors with corresponding reverts //reset any anchors that have been specified as "undefined" //reset any anchors that we'll be setting in the state QDeclarativeAnchors::Anchors combined = d->anchorSet->d_func()->resetAnchors | d->anchorSet->d_func()->usedAnchors; if (d->applyOrigLeft || (combined & QDeclarativeAnchors::LeftAnchor)) { - d->target->anchors()->resetLeft(); + targetPrivate->anchors()->resetLeft(); QDeclarativePropertyPrivate::setBinding(d->leftProp, 0); } if (d->applyOrigRight || (combined & QDeclarativeAnchors::RightAnchor)) { - d->target->anchors()->resetRight(); + targetPrivate->anchors()->resetRight(); QDeclarativePropertyPrivate::setBinding(d->rightProp, 0); } if (d->applyOrigHCenter || (combined & QDeclarativeAnchors::HCenterAnchor)) { - d->target->anchors()->resetHorizontalCenter(); + targetPrivate->anchors()->resetHorizontalCenter(); QDeclarativePropertyPrivate::setBinding(d->hCenterProp, 0); } if (d->applyOrigTop || (combined & QDeclarativeAnchors::TopAnchor)) { - d->target->anchors()->resetTop(); + targetPrivate->anchors()->resetTop(); QDeclarativePropertyPrivate::setBinding(d->topProp, 0); } if (d->applyOrigBottom || (combined & QDeclarativeAnchors::BottomAnchor)) { - d->target->anchors()->resetBottom(); + targetPrivate->anchors()->resetBottom(); QDeclarativePropertyPrivate::setBinding(d->bottomProp, 0); } if (d->applyOrigVCenter || (combined & QDeclarativeAnchors::VCenterAnchor)) { - d->target->anchors()->resetVerticalCenter(); + targetPrivate->anchors()->resetVerticalCenter(); QDeclarativePropertyPrivate::setBinding(d->vCenterProp, 0); } if (d->applyOrigBaseline || (combined & QDeclarativeAnchors::BaselineAnchor)) { - d->target->anchors()->resetBaseline(); + targetPrivate->anchors()->resetBaseline(); QDeclarativePropertyPrivate::setBinding(d->baselineProp, 0); } } @@ -1387,21 +1390,22 @@ void QDeclarativeAnchorChanges::rewind() if (!d->target) return; + QDeclarativeItemPrivate *targetPrivate = QDeclarativeItemPrivate::get(d->target); //restore previous anchors if (d->rewindLeft.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->setLeft(d->rewindLeft); + targetPrivate->anchors()->setLeft(d->rewindLeft); if (d->rewindRight.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->setRight(d->rewindRight); + targetPrivate->anchors()->setRight(d->rewindRight); if (d->rewindHCenter.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->setHorizontalCenter(d->rewindHCenter); + targetPrivate->anchors()->setHorizontalCenter(d->rewindHCenter); if (d->rewindTop.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->setTop(d->rewindTop); + targetPrivate->anchors()->setTop(d->rewindTop); if (d->rewindBottom.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->setBottom(d->rewindBottom); + targetPrivate->anchors()->setBottom(d->rewindBottom); if (d->rewindVCenter.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->setVerticalCenter(d->rewindVCenter); + targetPrivate->anchors()->setVerticalCenter(d->rewindVCenter); if (d->rewindBaseline.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->setBaseline(d->rewindBaseline); + targetPrivate->anchors()->setBaseline(d->rewindBaseline); d->target->setX(d->rewindX); d->target->setY(d->rewindY); @@ -1415,13 +1419,14 @@ void QDeclarativeAnchorChanges::saveCurrentValues() if (!d->target) return; - d->rewindLeft = d->target->anchors()->left(); - d->rewindRight = d->target->anchors()->right(); - d->rewindHCenter = d->target->anchors()->horizontalCenter(); - d->rewindTop = d->target->anchors()->top(); - d->rewindBottom = d->target->anchors()->bottom(); - d->rewindVCenter = d->target->anchors()->verticalCenter(); - d->rewindBaseline = d->target->anchors()->baseline(); + QDeclarativeItemPrivate *targetPrivate = QDeclarativeItemPrivate::get(d->target); + d->rewindLeft = targetPrivate->anchors()->left(); + d->rewindRight = targetPrivate->anchors()->right(); + d->rewindHCenter = targetPrivate->anchors()->horizontalCenter(); + d->rewindTop = targetPrivate->anchors()->top(); + d->rewindBottom = targetPrivate->anchors()->bottom(); + d->rewindVCenter = targetPrivate->anchors()->verticalCenter(); + d->rewindBaseline = targetPrivate->anchors()->baseline(); d->rewindX = d->target->x(); d->rewindY = d->target->y(); diff --git a/src/declarative/util/qdeclarativesystempalette.cpp b/src/declarative/util/qdeclarativesystempalette.cpp index 9bb3f69..6c62446 100644 --- a/src/declarative/util/qdeclarativesystempalette.cpp +++ b/src/declarative/util/qdeclarativesystempalette.cpp @@ -59,7 +59,6 @@ public: /*! \qmlclass SystemPalette QDeclarativeSystemPalette \since 4.7 - \ingroup group_utility \brief The SystemPalette item gives access to the Qt palettes. \sa QPalette diff --git a/src/declarative/util/qdeclarativetimeline.cpp b/src/declarative/util/qdeclarativetimeline.cpp index 656c62b..0258b3c 100644 --- a/src/declarative/util/qdeclarativetimeline.cpp +++ b/src/declarative/util/qdeclarativetimeline.cpp @@ -255,7 +255,6 @@ qreal QDeclarativeTimeLinePrivate::value(const Op &op, int time, qreal base, boo /*! \internal \class QDeclarativeTimeLine - \ingroup group_animation \brief The QDeclarativeTimeLine class provides a timeline for controlling animations. QDeclarativeTimeLine is similar to QTimeLine except: @@ -387,7 +386,10 @@ void QDeclarativeTimeLine::set(QDeclarativeTimeLineValue &timeLineValue, qreal v */ int QDeclarativeTimeLine::accel(QDeclarativeTimeLineValue &timeLineValue, qreal velocity, qreal acceleration) { - if ((velocity > 0.0f) == (acceleration > 0.0f)) + if (acceleration == 0.0f) + return -1; + + if ((velocity > 0.0f) == (acceleration > 0.0f)) acceleration = acceleration * -1.0f; int time = static_cast<int>(-1000 * velocity / acceleration); @@ -410,13 +412,16 @@ int QDeclarativeTimeLine::accel(QDeclarativeTimeLineValue &timeLineValue, qreal */ int QDeclarativeTimeLine::accel(QDeclarativeTimeLineValue &timeLineValue, qreal velocity, qreal acceleration, qreal maxDistance) { - Q_ASSERT(acceleration >= 0.0f && maxDistance >= 0.0f); + if (maxDistance == 0.0f || acceleration == 0.0f) + return -1; + + Q_ASSERT(acceleration > 0.0f && maxDistance > 0.0f); qreal maxAccel = (velocity * velocity) / (2.0f * maxDistance); if (maxAccel > acceleration) acceleration = maxAccel; - if ((velocity > 0.0f) == (acceleration > 0.0f)) + if ((velocity > 0.0f) == (acceleration > 0.0f)) acceleration = acceleration * -1.0f; int time = static_cast<int>(-1000 * velocity / acceleration); @@ -438,6 +443,7 @@ int QDeclarativeTimeLine::accelDistance(QDeclarativeTimeLineValue &timeLineValue { if (distance == 0.0f || velocity == 0.0f) return -1; + Q_ASSERT((distance >= 0.0f) == (velocity >= 0.0f)); int time = static_cast<int>(1000 * (2.0f * distance) / velocity); @@ -868,7 +874,6 @@ void QDeclarativeTimeLine::remove(QDeclarativeTimeLineObject *v) /*! \internal \class QDeclarativeTimeLineValue - \ingroup group_animation \brief The QDeclarativeTimeLineValue class provides a value that can be modified by QDeclarativeTimeLine. */ diff --git a/src/declarative/util/qdeclarativetransition.cpp b/src/declarative/util/qdeclarativetransition.cpp index f284156..ab8b116 100644 --- a/src/declarative/util/qdeclarativetransition.cpp +++ b/src/declarative/util/qdeclarativetransition.cpp @@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE /*! \qmlclass Transition QDeclarativeTransition - \since 4.7 + \since 4.7 \brief The Transition element defines animated transitions that occur on state changes. \sa {qmlstates}{States}, {state-transitions}{Transitions}, {QtDeclarative} @@ -63,8 +63,6 @@ QT_BEGIN_NAMESPACE \internal \class QDeclarativeTransition \brief The QDeclarativeTransition class allows you to define animated transitions that occur on state changes. - - \ingroup group_states */ //ParallelAnimationWrapper allows us to do a "callback" when the animation finishes, rather than connecting diff --git a/src/declarative/util/qdeclarativeview.cpp b/src/declarative/util/qdeclarativeview.cpp index 62d913c..833e284 100644 --- a/src/declarative/util/qdeclarativeview.cpp +++ b/src/declarative/util/qdeclarativeview.cpp @@ -484,10 +484,7 @@ QSize QDeclarativeViewPrivate::rootObjectSize() QSize rootObjectSize(0,0); int widthCandidate = -1; int heightCandidate = -1; - if (declarativeItemRoot) { - widthCandidate = declarativeItemRoot->width(); - heightCandidate = declarativeItemRoot->height(); - } else if (root) { + if (root) { QSizeF size = root->boundingRect().size(); widthCandidate = size.width(); heightCandidate = size.height(); @@ -614,16 +611,15 @@ bool QDeclarativeView::eventFilter(QObject *watched, QEvent *e) /*! \internal - Preferred size follows the root object in - resize mode SizeViewToRootObject and - the view in resize mode SizeRootObjectToView. + Preferred size follows the root object geometry. */ QSize QDeclarativeView::sizeHint() const { - if (d->resizeMode == SizeRootObjectToView) { + QSize rootObjectSize = d->rootObjectSize(); + if (rootObjectSize.isEmpty()) { return size(); - } else { // d->resizeMode == SizeViewToRootObject - return d->rootObjectSize(); + } else { + return rootObjectSize; } } diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp index bdebadf..ae3b5d7 100644 --- a/src/declarative/util/qdeclarativexmllistmodel.cpp +++ b/src/declarative/util/qdeclarativexmllistmodel.cpp @@ -675,10 +675,10 @@ void QDeclarativeXmlListModel::setNamespaceDeclarations(const QString &declarati Specifies the model loading status, which can be one of the following: \list - \o Null - No XML data has been set for this model. - \o Ready - The XML data has been loaded into the model. - \o Loading - The model is in the process of reading and loading XML data. - \o Error - An error occurred while the model was loading. + \o XmlListModel.Null - No XML data has been set for this model. + \o XmlListModel.Ready - The XML data has been loaded into the model. + \o XmlListModel.Loading - The model is in the process of reading and loading XML data. + \o XmlListModel.Error - An error occurred while the model was loading. \endlist \sa progress diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 7fcf4d2..7f43b96 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1090,6 +1090,10 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const Q if (newParent == parent) return; + if (isWidget) + static_cast<QGraphicsWidgetPrivate *>(this)->fixFocusChainBeforeReparenting((newParent && + newParent->isWidget()) ? static_cast<QGraphicsWidget *>(newParent) : 0, + scene); if (scene) { // Deliver the change to the index if (scene->d_func()->indexMethod != QGraphicsScene::NoIndex) @@ -1803,9 +1807,6 @@ static void _q_qgraphicsItemSetFlag(QGraphicsItem *item, QGraphicsItem::Graphics */ void QGraphicsItem::setFlags(GraphicsItemFlags flags) { - if (isWindow()) - flags |= ItemIsPanel; - // Notify change and check for adjustment. if (quint32(d_ptr->flags) == quint32(flags)) return; @@ -7644,7 +7645,13 @@ void QGraphicsObject::ungrabGesture(Qt::GestureType gesture) manager->cleanupCachedGestures(this, gesture); } } +/*! + Updates the item's micro focus. This is slot for convenience. + \since 4.7 + + \sa QInputContext +*/ void QGraphicsObject::updateMicroFocus() { QGraphicsItem::updateMicroFocus(); @@ -7953,6 +7960,13 @@ void QGraphicsItemPrivate::resetHeight() */ /*! + \property QGraphicsObject::effect + \brief the effect attached to this item + + \sa QGraphicsItem::setGraphicsEffect(), QGraphicsItem::graphicsEffect() +*/ + +/*! \class QAbstractGraphicsShapeItem \brief The QAbstractGraphicsShapeItem class provides a common base for all path items. diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 06a44b7..478c0c3 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -747,6 +747,17 @@ QSizeF QGraphicsWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) c } /*! + \property QGraphicsWidget::layout + \brief The layout of the widget +*/ + +/*! + \fn void QGraphicsWidget::layoutChanged() + This signal gets emitted whenever the layout of the item changes + \internal +*/ + +/*! Returns this widget's layout, or 0 if no layout is currently managing this widget. @@ -1094,9 +1105,6 @@ QVariant QGraphicsWidget::itemChange(GraphicsItemChange change, const QVariant & } break; case ItemParentChange: { - QGraphicsItem *parent = qVariantValue<QGraphicsItem *>(value); - d->fixFocusChainBeforeReparenting((parent && parent->isWidget()) ? static_cast<QGraphicsWidget *>(parent) : 0, scene()); - // Deliver ParentAboutToChange. QEvent event(QEvent::ParentAboutToChange); QApplication::sendEvent(this, &event); diff --git a/src/gui/graphicsview/qgraphicswidget_p.cpp b/src/gui/graphicsview/qgraphicswidget_p.cpp index 6e397b6..50b315a 100644 --- a/src/gui/graphicsview/qgraphicswidget_p.cpp +++ b/src/gui/graphicsview/qgraphicswidget_p.cpp @@ -71,14 +71,17 @@ void QGraphicsWidgetPrivate::init(QGraphicsItem *parentItem, Qt::WindowFlags wFl adjustWindowFlags(&wFlags); windowFlags = wFlags; - q->setParentItem(parentItem); + if (parentItem) + setParentItemHelper(parentItem, 0, 0); + q->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred, QSizePolicy::DefaultType)); q->setGraphicsItem(q); resolveLayoutDirection(); q->unsetWindowFrameMargins(); - q->setFlag(QGraphicsItem::ItemUsesExtendedStyleOption); - q->setFlag(QGraphicsItem::ItemSendsGeometryChanges); + flags |= QGraphicsItem::ItemUsesExtendedStyleOption | QGraphicsItem::ItemSendsGeometryChanges; + if (windowFlags & Qt::Window) + flags |= QGraphicsItem::ItemIsPanel; } qreal QGraphicsWidgetPrivate::titleBarHeight(const QStyleOptionTitleBar &options) const diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 0334d47..e39526e 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -6235,6 +6235,12 @@ void QWidget::setFocus(Qt::FocusReason reason) QApplication::sendEvent(that->style(), &event); } if (!isHidden()) { +#ifndef QT_NO_GRAPHICSVIEW + // Update proxy state + if (QWExtra *topData = window()->d_func()->extra) + if (topData->proxyWidget && topData->proxyWidget->hasFocus()) + topData->proxyWidget->d_func()->updateProxyInputMethodAcceptanceFromWidget(); +#endif // Send event to self QFocusEvent event(QEvent::FocusIn, reason); QPointer<QWidget> that = f; diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp index 37ac6bf..43f510c 100644 --- a/src/gui/kernel/qwidget_x11.cpp +++ b/src/gui/kernel/qwidget_x11.cpp @@ -3000,7 +3000,7 @@ Picture QX11Data::getSolidFill(int screen, const QColor &c) return X11->solid_fills[i].picture; } // none found, replace one - int i = rand() % 16; + int i = qrand() % 16; if (X11->solid_fills[i].screen != screen && X11->solid_fills[i].picture) { XRenderFreePicture (X11->display, X11->solid_fills[i].picture); diff --git a/src/gui/painting/qdatabuffer_p.h b/src/gui/painting/qdatabuffer_p.h index bc5f1ef..8f8544f 100644 --- a/src/gui/painting/qdatabuffer_p.h +++ b/src/gui/painting/qdatabuffer_p.h @@ -60,16 +60,20 @@ QT_BEGIN_NAMESPACE template <typename Type> class QDataBuffer { public: - QDataBuffer(int res = 64) + QDataBuffer(int res) { capacity = res; - buffer = (Type*) qMalloc(capacity * sizeof(Type)); + if (res) + buffer = (Type*) qMalloc(capacity * sizeof(Type)); + else + buffer = 0; siz = 0; } ~QDataBuffer() { - qFree(buffer); + if (buffer) + qFree(buffer); } inline void reset() { siz = 0; } @@ -104,6 +108,8 @@ public: inline void reserve(int size) { if (size > capacity) { + if (capacity == 0) + capacity = 1; while (capacity < size) capacity *= 2; buffer = (Type*) qRealloc(buffer, capacity * sizeof(Type)); @@ -112,7 +118,12 @@ public: inline void shrink(int size) { capacity = size; - buffer = (Type*) qRealloc(buffer, capacity * sizeof(Type)); + if (size) + buffer = (Type*) qRealloc(buffer, capacity * sizeof(Type)); + else { + qFree(buffer); + buffer = 0; + } } inline void swap(QDataBuffer<Type> &other) { diff --git a/src/gui/painting/qdrawutil.cpp b/src/gui/painting/qdrawutil.cpp index a62f06b..ef9b18c 100644 --- a/src/gui/painting/qdrawutil.cpp +++ b/src/gui/painting/qdrawutil.cpp @@ -1137,6 +1137,15 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin xTarget.resize(columns + 1); yTarget.resize(rows + 1); + bool oldAA = painter->testRenderHint(QPainter::Antialiasing); + bool oldSmooth = painter->testRenderHint(QPainter::SmoothPixmapTransform); + if (painter->paintEngine()->type() != QPaintEngine::OpenGL + && painter->paintEngine()->type() != QPaintEngine::OpenGL2 + && (oldSmooth || oldAA) && painter->combinedTransform().type() != QTransform::TxNone) { + painter->setRenderHint(QPainter::Antialiasing, false); + painter->setRenderHint(QPainter::SmoothPixmapTransform, false); + } + xTarget[0] = targetRect.left(); xTarget[1] = targetCenterLeft; xTarget[columns - 1] = targetCenterRight; @@ -1342,6 +1351,11 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin painter->drawPixmapFragments(opaqueData.data(), opaqueData.size(), pixmap, QPainter::OpaqueHint); if (translucentData.size()) painter->drawPixmapFragments(translucentData.data(), translucentData.size(), pixmap); + + if (oldAA) + painter->setRenderHint(QPainter::Antialiasing, true); + if (oldSmooth) + painter->setRenderHint(QPainter::SmoothPixmapTransform, true); } QT_END_NAMESPACE diff --git a/src/gui/painting/qoutlinemapper.cpp b/src/gui/painting/qoutlinemapper.cpp index ad0c2eb..1b01960 100644 --- a/src/gui/painting/qoutlinemapper.cpp +++ b/src/gui/painting/qoutlinemapper.cpp @@ -154,7 +154,8 @@ QT_FT_Outline *QOutlineMapper::convertPath(const QVectorPath &path) // ### We can kill this copying and just use the buffer straight... m_elements.resize(count); - memcpy(m_elements.data(), path.points(), count* sizeof(QPointF)); + if (count) + memcpy(m_elements.data(), path.points(), count* sizeof(QPointF)); m_element_types.resize(0); } diff --git a/src/gui/painting/qoutlinemapper_p.h b/src/gui/painting/qoutlinemapper_p.h index d0ce1a9..39b7593 100644 --- a/src/gui/painting/qoutlinemapper_p.h +++ b/src/gui/painting/qoutlinemapper_p.h @@ -87,8 +87,15 @@ const int QT_RASTER_COORD_LIMIT = 32767; class QOutlineMapper { public: - QOutlineMapper() - : m_round_coords(false) + QOutlineMapper() : + m_element_types(0), + m_elements(0), + m_elements_dev(0), + m_points(0), + m_tags(0), + m_contours(0), + m_polygon_dev(0), + m_round_coords(false) { } diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 9148ac2..6f395f6 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -251,6 +251,11 @@ static void qt_debug_path(const QPainterPath &path) } #endif +QRasterPaintEnginePrivate::QRasterPaintEnginePrivate() : + QPaintEngineExPrivate(), + cachedLines(0) +{ +} /*! @@ -336,17 +341,6 @@ void QRasterPaintEngine::init() d->hdc = 0; #endif - d->rasterPoolSize = 8192; - d->rasterPoolBase = -#if defined(Q_WS_WIN64) - // We make use of setjmp and longjmp in qgrayraster.c which requires - // 16-byte alignment, hence we hardcode this requirement here.. - (unsigned char *) _aligned_malloc(d->rasterPoolSize, sizeof(void*) * 2); -#else - (unsigned char *) malloc(d->rasterPoolSize); -#endif - Q_CHECK_PTR(d->rasterPoolBase); - // The antialiasing raster. d->grayRaster.reset(new QT_FT_Raster); Q_CHECK_PTR(d->grayRaster.data()); @@ -354,8 +348,6 @@ void QRasterPaintEngine::init() QT_THROW(std::bad_alloc()); // an error creating the raster is caused by a bad malloc - qt_ft_grays_raster.raster_reset(*d->grayRaster.data(), d->rasterPoolBase, d->rasterPoolSize); - d->rasterizer.reset(new QRasterizer); d->rasterBuffer.reset(new QRasterBuffer()); d->outlineMapper.reset(new QOutlineMapper); @@ -437,12 +429,6 @@ QRasterPaintEngine::~QRasterPaintEngine() { Q_D(QRasterPaintEngine); -#if defined(Q_WS_WIN64) - _aligned_free(d->rasterPoolBase); -#else - free(d->rasterPoolBase); -#endif - qt_ft_grays_raster.raster_done(*d->grayRaster.data()); } @@ -4090,6 +4076,22 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, return; } + const int rasterPoolInitialSize = 8192; + int rasterPoolSize = rasterPoolInitialSize; + unsigned char *rasterPoolBase; +#if defined(Q_WS_WIN64) + rasterPoolBase = + // We make use of setjmp and longjmp in qgrayraster.c which requires + // 16-byte alignment, hence we hardcode this requirement here.. + (unsigned char *) _aligned_malloc(rasterPoolSize, sizeof(void*) * 2); +#else + unsigned char rasterPoolOnStack[rasterPoolInitialSize]; + rasterPoolBase = rasterPoolOnStack; +#endif + Q_CHECK_PTR(rasterPoolBase); + + qt_ft_grays_raster.raster_reset(*grayRaster.data(), rasterPoolBase, rasterPoolSize); + void *data = userData; QT_FT_BBox clip_box = { deviceRect.x(), @@ -4122,13 +4124,14 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, int new_size = rasterPoolSize * 2; if (new_size > 1024 * 1024) { qWarning("QPainter: Rasterization of primitive failed"); - return; + break; } #if defined(Q_WS_WIN64) _aligned_free(rasterPoolBase); #else - free(rasterPoolBase); + if (rasterPoolBase != rasterPoolOnStack) // initially on the stack + free(rasterPoolBase); #endif rasterPoolSize = new_size; @@ -4149,6 +4152,13 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, done = true; } } + +#if defined(Q_WS_WIN64) + _aligned_free(rasterPoolBase); +#else + if (rasterPoolBase != rasterPoolOnStack) // initially on the stack + free(rasterPoolBase); +#endif } void QRasterPaintEnginePrivate::recalculateFastImages() diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h index 55eb82e..1016f8d 100644 --- a/src/gui/painting/qpaintengine_raster_p.h +++ b/src/gui/painting/qpaintengine_raster_p.h @@ -300,6 +300,7 @@ QRasterPaintEnginePrivate : public QPaintEngineExPrivate { Q_DECLARE_PUBLIC(QRasterPaintEngine) public: + QRasterPaintEnginePrivate(); void rasterizeLine_dashed(QLineF line, qreal width, int *dashIndex, qreal *dashOffset, bool *inDash); @@ -354,8 +355,6 @@ public: QScopedPointer<QDashStroker> dashStroker; QScopedPointer<QT_FT_Raster> grayRaster; - unsigned long rasterPoolSize; - unsigned char *rasterPoolBase; QDataBuffer<QLineF> cachedLines; QSpanData image_filler; diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp index da48fcb..aef8b80 100644 --- a/src/gui/painting/qpaintengine_x11.cpp +++ b/src/gui/painting/qpaintengine_x11.cpp @@ -315,7 +315,7 @@ static Picture getPatternFill(int screen, const QBrush &b) return X11->pattern_fills[i].picture; } // none found, replace one - int i = rand() % 16; + int i = qrand() % 16; if (X11->pattern_fills[i].screen != screen && X11->pattern_fills[i].picture) { XRenderFreePicture (X11->display, X11->pattern_fills[i].picture); diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index a78cafb..fda937e 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -149,6 +149,7 @@ QDebug Q_GUI_EXPORT &operator<<(QDebug &s, const QVectorPath &path) struct StrokeHandler { + StrokeHandler(int reserve) : pts(reserve), types(reserve) {} QDataBuffer<qreal> pts; QDataBuffer<QPainterPath::ElementType> types; }; @@ -394,7 +395,7 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) return; if (!d->strokeHandler) { - d->strokeHandler = new StrokeHandler; + d->strokeHandler = new StrokeHandler(path.elementCount()+4); d->stroker.setMoveToHook(qpaintengineex_moveTo); d->stroker.setLineToHook(qpaintengineex_lineTo); d->stroker.setCubicToHook(qpaintengineex_cubicTo); diff --git a/src/gui/painting/qpathclipper.cpp b/src/gui/painting/qpathclipper.cpp index c910024..78553c9 100644 --- a/src/gui/painting/qpathclipper.cpp +++ b/src/gui/painting/qpathclipper.cpp @@ -278,7 +278,8 @@ private: }; SegmentTree::SegmentTree(QPathSegments &segments) - : m_segments(segments) + : m_segments(segments), + m_intersections(0) { m_bounds.x1 = qt_inf(); m_bounds.y1 = qt_inf(); @@ -806,7 +807,7 @@ void QWingedEdge::intersectAndAdd() for (int i = 0; i < m_segments.points(); ++i) addVertex(m_segments.pointAt(i)); - QDataBuffer<QPathSegments::Intersection> intersections; + QDataBuffer<QPathSegments::Intersection> intersections(m_segments.segments()); for (int i = 0; i < m_segments.segments(); ++i) { intersections.reset(); @@ -857,11 +858,17 @@ void QWingedEdge::intersectAndAdd() } } -QWingedEdge::QWingedEdge() +QWingedEdge::QWingedEdge() : + m_edges(0), + m_vertices(0), + m_segments(0) { } -QWingedEdge::QWingedEdge(const QPainterPath &subject, const QPainterPath &clip) +QWingedEdge::QWingedEdge(const QPainterPath &subject, const QPainterPath &clip) : + m_edges(subject.length()), + m_vertices(subject.length()), + m_segments(subject.length()) { m_segments.setPath(subject); m_segments.addPath(clip); @@ -1414,9 +1421,9 @@ bool QPathClipper::intersect() else if (clipIsRect) return subjectPath.intersects(r2); - QPathSegments a; + QPathSegments a(subjectPath.length()); a.setPath(subjectPath); - QPathSegments b; + QPathSegments b(clipPath.length()); b.setPath(clipPath); QIntersectionFinder finder; @@ -1459,9 +1466,9 @@ bool QPathClipper::contains() if (clipIsRect) return subjectPath.contains(r2); - QPathSegments a; + QPathSegments a(subjectPath.length()); a.setPath(subjectPath); - QPathSegments b; + QPathSegments b(clipPath.length()); b.setPath(clipPath); QIntersectionFinder finder; diff --git a/src/gui/painting/qpathclipper_p.h b/src/gui/painting/qpathclipper_p.h index 7962400..fab618d 100644 --- a/src/gui/painting/qpathclipper_p.h +++ b/src/gui/painting/qpathclipper_p.h @@ -199,7 +199,7 @@ public: }; - QPathSegments(); + QPathSegments(int reserve); void setPath(const QPainterPath &path); void addPath(const QPainterPath &path); @@ -345,7 +345,10 @@ inline QPathVertex::operator QPointF() const return QPointF(x, y); } -inline QPathSegments::QPathSegments() +inline QPathSegments::QPathSegments(int reserve) : + m_points(reserve), + m_segments(reserve), + m_intersections(reserve) { } diff --git a/src/gui/painting/qpolygonclipper_p.h b/src/gui/painting/qpolygonclipper_p.h index 1b4cbb3..cdaac1c 100644 --- a/src/gui/painting/qpolygonclipper_p.h +++ b/src/gui/painting/qpolygonclipper_p.h @@ -62,7 +62,8 @@ QT_BEGIN_NAMESPACE template <typename InType, typename OutType, typename CastType> class QPolygonClipper { public: - QPolygonClipper() + QPolygonClipper() : + buffer1(0), buffer2(0) { x1 = y1 = x2 = y2 = 0; } diff --git a/src/gui/painting/qrasterizer.cpp b/src/gui/painting/qrasterizer.cpp index 51d01c9..f8f8afb 100644 --- a/src/gui/painting/qrasterizer.cpp +++ b/src/gui/painting/qrasterizer.cpp @@ -198,9 +198,11 @@ public: }; QScanConverter::QScanConverter() - : m_alloc(0) + : m_lines(0) + , m_alloc(0) , m_size(0) , m_intersections(0) + , m_active(0) { } @@ -310,6 +312,10 @@ struct QBoolToType template <typename T> void qScanConvert(QScanConverter &d, T allVertical) { + if (!d.m_lines.size()) { + d.m_active.reset(); + return; + } qSort(d.m_lines.data(), d.m_lines.data() + d.m_lines.size(), QT_PREPEND_NAMESPACE(topOrder)); int line = 0; for (int y = d.m_lines.first().top; y <= d.m_bottom; ++y) { diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp index e43544c..9b8e099 100644 --- a/src/gui/painting/qstroker.cpp +++ b/src/gui/painting/qstroker.cpp @@ -187,7 +187,7 @@ static inline qreal adapted_angle_on_x(const QLineF &line) } QStrokerOps::QStrokerOps() - : m_customData(0), m_moveTo(0), m_lineTo(0), m_cubicTo(0) + : m_elements(0), m_customData(0), m_moveTo(0), m_lineTo(0), m_cubicTo(0) { } diff --git a/src/imports/gestures/qdeclarativegesturearea.cpp b/src/imports/gestures/qdeclarativegesturearea.cpp index 615c674..19afe0c 100644 --- a/src/imports/gestures/qdeclarativegesturearea.cpp +++ b/src/imports/gestures/qdeclarativegesturearea.cpp @@ -259,7 +259,7 @@ bool QDeclarativeGestureAreaPrivate::gestureEvent(QGestureEvent *event) bool accept = true; for (Bindings::Iterator it = bindings.begin(); it != bindings.end(); ++it) { if ((gesture = event->gesture(it.key()))) { - it.value()->value(); + it.value()->evaluate(); event->setAccepted(true); // XXX only if value returns true? } } diff --git a/src/imports/imports.pro b/src/imports/imports.pro index ecde0cc..a9d600e 100644 --- a/src/imports/imports.pro +++ b/src/imports/imports.pro @@ -1,6 +1,6 @@ TEMPLATE = subdirs -SUBDIRS += widgets particles +SUBDIRS += particles gestures contains(QT_CONFIG, webkit): SUBDIRS += webkit contains(QT_CONFIG, mediaservices): SUBDIRS += multimedia diff --git a/src/imports/multimedia/qdeclarativeaudio.cpp b/src/imports/multimedia/qdeclarativeaudio.cpp index a163b10..234b6df 100644 --- a/src/imports/multimedia/qdeclarativeaudio.cpp +++ b/src/imports/multimedia/qdeclarativeaudio.cpp @@ -330,9 +330,14 @@ QDeclarativeAudio::Error QDeclarativeAudio::error() const return Error(m_error); } +void QDeclarativeAudio::classBegin() +{ +} + void QDeclarativeAudio::componentComplete() { - setObject(this); + if (m_playerControl == 0) + setObject(this); } diff --git a/src/imports/multimedia/qdeclarativeaudio_p.h b/src/imports/multimedia/qdeclarativeaudio_p.h index 24276ea..e960b9d 100644 --- a/src/imports/multimedia/qdeclarativeaudio_p.h +++ b/src/imports/multimedia/qdeclarativeaudio_p.h @@ -115,6 +115,7 @@ public: Status status() const; Error error() const; + void classBegin(); void componentComplete(); public Q_SLOTS: diff --git a/src/imports/webkit/qdeclarativewebview.cpp b/src/imports/webkit/qdeclarativewebview.cpp index 5db812c..9571470 100644 --- a/src/imports/webkit/qdeclarativewebview.cpp +++ b/src/imports/webkit/qdeclarativewebview.cpp @@ -437,24 +437,39 @@ void QDeclarativeWebView::paintPage(const QRect& r) /*! \qmlproperty list<object> WebView::javaScriptWindowObjects - This property is a list of object that are available from within - the webview's JavaScript context. + A list of QML objects to expose to the web page. - The \a object will be inserted as a child of the frame's window - object, under the name given by the attached property \c WebView.windowObjectName. + Each object will be added as a property of the web frame's window object. The + property name is controlled by the value of \c WebView.windowObjectName + attached property. + + Exposing QML objects to a web page allows JavaScript executing in the web + page itself to communicate with QML, by reading and writing properties and + by calling methods of the exposed QML objects. + + This example shows how to call into a QML method using a window object. \qml WebView { - javaScriptWindowObjects: Object { - WebView.windowObjectName: "coordinates" + javaScriptWindowObjects: QtObject { + WebView.windowObjectName: "qml" + + function qmlCall() { + console.log("This call is in QML!"); + } } + + html: "<script>console.log(\"This is in WebKit!\"); window.qml.qmlCall();</script>" } \endqml - Properties of the object will be exposed as JavaScript properties and slots as - JavaScript methods. + The output of the example will be: + \code + This is in WebKit! + This call is in QML! + \endcode - If Javascript is not enabled for this page, then this property does nothing. + If Javascript is not enabled for the page, then this property does nothing. */ QDeclarativeListProperty<QObject> QDeclarativeWebView::javaScriptWindowObjects() { diff --git a/src/imports/widgets/graphicslayouts.cpp b/src/imports/widgets/graphicslayouts.cpp deleted file mode 100644 index 25cf994..0000000 --- a/src/imports/widgets/graphicslayouts.cpp +++ /dev/null @@ -1,366 +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 "graphicslayouts_p.h" - -#include <QtGui/qgraphicswidget.h> -#include <QtCore/qdebug.h> - -QT_BEGIN_NAMESPACE - -LinearLayoutAttached::LinearLayoutAttached(QObject *parent) -: QObject(parent), _stretch(1), _alignment(Qt::AlignCenter), _spacing(0) -{ -} - -void LinearLayoutAttached::setStretchFactor(int f) -{ - if (_stretch == f) - return; - - _stretch = f; - emit stretchChanged(reinterpret_cast<QGraphicsLayoutItem*>(parent()), _stretch); -} - -void LinearLayoutAttached::setSpacing(int s) -{ - if (_spacing == s) - return; - - _spacing = s; - emit spacingChanged(reinterpret_cast<QGraphicsLayoutItem*>(parent()), _spacing); -} - -void LinearLayoutAttached::setAlignment(Qt::Alignment a) -{ - if (_alignment == a) - return; - - _alignment = a; - emit alignmentChanged(reinterpret_cast<QGraphicsLayoutItem*>(parent()), _alignment); -} - -QGraphicsLinearLayoutStretchItemObject::QGraphicsLinearLayoutStretchItemObject(QObject *parent) - : QObject(parent) -{ -} - -QSizeF QGraphicsLinearLayoutStretchItemObject::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const -{ -Q_UNUSED(which); -Q_UNUSED(constraint); -return QSizeF(); -} - - -QGraphicsLinearLayoutObject::QGraphicsLinearLayoutObject(QObject *parent) -: QObject(parent) -{ -} - -QGraphicsLinearLayoutObject::~QGraphicsLinearLayoutObject() -{ -} - -void QGraphicsLinearLayoutObject::insertLayoutItem(int index, QGraphicsLayoutItem *item) -{ -insertItem(index, item); - -//connect attached properties -if (LinearLayoutAttached *obj = attachedProperties.value(item)) { - setStretchFactor(item, obj->stretchFactor()); - setAlignment(item, obj->alignment()); - updateSpacing(item, obj->spacing()); - QObject::connect(obj, SIGNAL(stretchChanged(QGraphicsLayoutItem*,int)), - this, SLOT(updateStretch(QGraphicsLayoutItem*,int))); - QObject::connect(obj, SIGNAL(alignmentChanged(QGraphicsLayoutItem*,Qt::Alignment)), - this, SLOT(updateAlignment(QGraphicsLayoutItem*,Qt::Alignment))); - QObject::connect(obj, SIGNAL(spacingChanged(QGraphicsLayoutItem*,int)), - this, SLOT(updateSpacing(QGraphicsLayoutItem*,int))); - //### need to disconnect when widget is removed? -} -} - -//### is there a better way to do this? -void QGraphicsLinearLayoutObject::clearChildren() -{ -for (int i = 0; i < count(); ++i) - removeAt(i); -} - -qreal QGraphicsLinearLayoutObject::contentsMargin() const -{ - qreal a,b,c,d; - getContentsMargins(&a, &b, &c, &d); - if(a==b && a==c && a==d) - return a; - return -1; -} - -void QGraphicsLinearLayoutObject::setContentsMargin(qreal m) -{ - setContentsMargins(m,m,m,m); -} - -void QGraphicsLinearLayoutObject::updateStretch(QGraphicsLayoutItem *item, int stretch) -{ -QGraphicsLinearLayout::setStretchFactor(item, stretch); -} - -void QGraphicsLinearLayoutObject::updateSpacing(QGraphicsLayoutItem* item, int spacing) -{ - for(int i=0; i < count(); i++){ - if(itemAt(i) == item){ //I do not see the reverse function, which is why we must loop over all items - QGraphicsLinearLayout::setItemSpacing(i, spacing); - return; - } - } -} - -void QGraphicsLinearLayoutObject::updateAlignment(QGraphicsLayoutItem *item, Qt::Alignment alignment) -{ -QGraphicsLinearLayout::setAlignment(item, alignment); -} - -QHash<QGraphicsLayoutItem*, LinearLayoutAttached*> QGraphicsLinearLayoutObject::attachedProperties; -LinearLayoutAttached *QGraphicsLinearLayoutObject::qmlAttachedProperties(QObject *obj) -{ -// ### This is not allowed - you must attach to any object -if (!qobject_cast<QGraphicsLayoutItem*>(obj)) - return 0; -LinearLayoutAttached *rv = new LinearLayoutAttached(obj); -attachedProperties.insert(qobject_cast<QGraphicsLayoutItem*>(obj), rv); -return rv; -} - -////////////////////////////////////////////////////////////////////////////////////////////////////// -// QGraphicsGridLayout-related classes -////////////////////////////////////////////////////////////////////////////////////////////////////// -GridLayoutAttached::GridLayoutAttached(QObject *parent) -: QObject(parent), _row(-1), _column(-1), _rowspan(1), _colspan(1), _alignment(-1), _rowstretch(-1), - _colstretch(-1), _rowspacing(-1), _colspacing(-1), _rowprefheight(-1), _rowmaxheight(-1), _rowminheight(-1), - _rowfixheight(-1), _colprefwidth(-1), _colmaxwidth(-1), _colminwidth(-1), _colfixwidth(-1) -{ -} - -void GridLayoutAttached::setRow(int r) -{ - if (_row == r) - return; - - _row = r; - //emit rowChanged(reinterpret_cast<QGraphicsLayoutItem*>(parent()), _row); -} - -void GridLayoutAttached::setColumn(int c) -{ - if (_column == c) - return; - - _column = c; - //emit columnChanged(reinterpret_cast<QGraphicsLayoutItem*>(parent()), _column); -} - -void GridLayoutAttached::setRowSpan(int rs) -{ - if (_rowspan == rs) - return; - - _rowspan = rs; - //emit rowSpanChanged(reinterpret_cast<QGraphicsLayoutItem*>(parent()), _rowSpan); -} - -void GridLayoutAttached::setColumnSpan(int cs) -{ - if (_colspan == cs) - return; - - _colspan = cs; - //emit columnSpanChanged(reinterpret_cast<QGraphicsLayoutItem*>(parent()), _columnSpan); -} - -void GridLayoutAttached::setAlignment(Qt::Alignment a) -{ - if (_alignment == a) - return; - - _alignment = a; - emit alignmentChanged(reinterpret_cast<QGraphicsLayoutItem*>(parent()), _alignment); -} - -void GridLayoutAttached::setRowStretchFactor(int f) -{ - _rowstretch = f; -} - -void GridLayoutAttached::setColumnStretchFactor(int f) -{ - _colstretch = f; -} - -void GridLayoutAttached::setRowSpacing(int s) -{ - _rowspacing = s; -} - -void GridLayoutAttached::setColumnSpacing(int s) -{ - _colspacing = s; -} - - -QGraphicsGridLayoutObject::QGraphicsGridLayoutObject(QObject *parent) -: QObject(parent) -{ -} - -QGraphicsGridLayoutObject::~QGraphicsGridLayoutObject() -{ -} - -void QGraphicsGridLayoutObject::addWidget(QGraphicsWidget *wid) -{ -//use attached properties -if (QObject *obj = attachedProperties.value(qobject_cast<QGraphicsLayoutItem*>(wid))) { - int row = static_cast<GridLayoutAttached *>(obj)->row(); - int column = static_cast<GridLayoutAttached *>(obj)->column(); - int rowSpan = static_cast<GridLayoutAttached *>(obj)->rowSpan(); - int columnSpan = static_cast<GridLayoutAttached *>(obj)->columnSpan(); - if (row == -1 || column == -1) { - qWarning() << "Must set row and column for an item in a grid layout"; - return; - } - addItem(wid, row, column, rowSpan, columnSpan); -} -} - -void QGraphicsGridLayoutObject::addLayoutItem(QGraphicsLayoutItem *item) -{ -//use attached properties -if (GridLayoutAttached *obj = attachedProperties.value(item)) { - int row = obj->row(); - int column = obj->column(); - int rowSpan = obj->rowSpan(); - int columnSpan = obj->columnSpan(); - Qt::Alignment alignment = obj->alignment(); - if (row == -1 || column == -1) { - qWarning() << "Must set row and column for an item in a grid layout"; - return; - } - if(obj->rowSpacing() != -1) - setRowSpacing(row, obj->rowSpacing()); - if(obj->columnSpacing() != -1) - setColumnSpacing(column, obj->columnSpacing()); - if(obj->rowStretchFactor() != -1) - setRowStretchFactor(row, obj->rowStretchFactor()); - if(obj->columnStretchFactor() != -1) - setColumnStretchFactor(column, obj->columnStretchFactor()); - if(obj->rowPreferredHeight() != -1) - setRowPreferredHeight(row, obj->rowPreferredHeight()); - if(obj->rowMaximumHeight() != -1) - setRowMaximumHeight(row, obj->rowMaximumHeight()); - if(obj->rowMinimumHeight() != -1) - setRowMinimumHeight(row, obj->rowMinimumHeight()); - if(obj->rowFixedHeight() != -1) - setRowFixedHeight(row, obj->rowFixedHeight()); - if(obj->columnPreferredWidth() != -1) - setColumnPreferredWidth(row, obj->columnPreferredWidth()); - if(obj->columnMaximumWidth() != -1) - setColumnMaximumWidth(row, obj->columnMaximumWidth()); - if(obj->columnMinimumWidth() != -1) - setColumnMinimumWidth(row, obj->columnMinimumWidth()); - if(obj->columnFixedWidth() != -1) - setColumnFixedWidth(row, obj->columnFixedWidth()); - addItem(item, row, column, rowSpan, columnSpan); - if (alignment != -1) - setAlignment(item,alignment); - QObject::connect(obj, SIGNAL(alignmentChanged(QGraphicsLayoutItem*,Qt::Alignment)), - this, SLOT(updateAlignment(QGraphicsLayoutItem*,Qt::Alignment))); - //### need to disconnect when widget is removed? -} -} - -//### is there a better way to do this? -void QGraphicsGridLayoutObject::clearChildren() -{ -for (int i = 0; i < count(); ++i) - removeAt(i); -} - -qreal QGraphicsGridLayoutObject::spacing() const -{ -if (verticalSpacing() == horizontalSpacing()) - return verticalSpacing(); -return -1; //### -} - -qreal QGraphicsGridLayoutObject::contentsMargin() const -{ - qreal a,b,c,d; - getContentsMargins(&a, &b, &c, &d); - if(a==b && a==c && a==d) - return a; - return -1; -} - -void QGraphicsGridLayoutObject::setContentsMargin(qreal m) -{ - setContentsMargins(m,m,m,m); -} - - -void QGraphicsGridLayoutObject::updateAlignment(QGraphicsLayoutItem *item, Qt::Alignment alignment) -{ -QGraphicsGridLayout::setAlignment(item, alignment); -} - -QHash<QGraphicsLayoutItem*, GridLayoutAttached*> QGraphicsGridLayoutObject::attachedProperties; -GridLayoutAttached *QGraphicsGridLayoutObject::qmlAttachedProperties(QObject *obj) -{ -// ### This is not allowed - you must attach to any object -if (!qobject_cast<QGraphicsLayoutItem*>(obj)) - return 0; -GridLayoutAttached *rv = new GridLayoutAttached(obj); -attachedProperties.insert(qobject_cast<QGraphicsLayoutItem*>(obj), rv); -return rv; -} - -QT_END_NAMESPACE diff --git a/src/imports/widgets/graphicslayouts_p.h b/src/imports/widgets/graphicslayouts_p.h deleted file mode 100644 index ea9c614..0000000 --- a/src/imports/widgets/graphicslayouts_p.h +++ /dev/null @@ -1,303 +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 GRAPHICSLAYOUTS_H -#define GRAPHICSLAYOUTS_H - -#include <QtGui/QGraphicsLinearLayout> -#include <QtGui/QGraphicsGridLayout> -#include <qdeclarative.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class QGraphicsLinearLayoutStretchItemObject : public QObject, public QGraphicsLayoutItem -{ - Q_OBJECT - Q_INTERFACES(QGraphicsLayoutItem) -public: - QGraphicsLinearLayoutStretchItemObject(QObject *parent = 0); - - virtual QSizeF sizeHint(Qt::SizeHint, const QSizeF &) const; -}; - -class LinearLayoutAttached; -class QGraphicsLinearLayoutObject : public QObject, public QGraphicsLinearLayout -{ - Q_OBJECT - Q_INTERFACES(QGraphicsLayout QGraphicsLayoutItem) - - Q_PROPERTY(QDeclarativeListProperty<QGraphicsLayoutItem> children READ children) - Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation) - Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing) - Q_PROPERTY(qreal contentsMargin READ contentsMargin WRITE setContentsMargin) - Q_CLASSINFO("DefaultProperty", "children") -public: - QGraphicsLinearLayoutObject(QObject * = 0); - ~QGraphicsLinearLayoutObject(); - - QDeclarativeListProperty<QGraphicsLayoutItem> children() { return QDeclarativeListProperty<QGraphicsLayoutItem>(this, 0, children_append, children_count, children_at, children_clear); } - - static LinearLayoutAttached *qmlAttachedProperties(QObject *); - - qreal contentsMargin() const; - void setContentsMargin(qreal); - -private Q_SLOTS: - void updateStretch(QGraphicsLayoutItem*,int); - void updateSpacing(QGraphicsLayoutItem*,int); - void updateAlignment(QGraphicsLayoutItem*,Qt::Alignment); - -private: - friend class LinearLayoutAttached; - void clearChildren(); - void insertLayoutItem(int, QGraphicsLayoutItem *); - static QHash<QGraphicsLayoutItem*, LinearLayoutAttached*> attachedProperties; - - static void children_append(QDeclarativeListProperty<QGraphicsLayoutItem> *prop, QGraphicsLayoutItem *item) { - static_cast<QGraphicsLinearLayoutObject*>(prop->object)->insertLayoutItem(-1, item); - } - - static void children_clear(QDeclarativeListProperty<QGraphicsLayoutItem> *prop) { - static_cast<QGraphicsLinearLayoutObject*>(prop->object)->clearChildren(); - } - - static int children_count(QDeclarativeListProperty<QGraphicsLayoutItem> *prop) { - return static_cast<QGraphicsLinearLayoutObject*>(prop->object)->count(); - } - - static QGraphicsLayoutItem *children_at(QDeclarativeListProperty<QGraphicsLayoutItem> *prop, int index) { - return static_cast<QGraphicsLinearLayoutObject*>(prop->object)->itemAt(index); - } -}; - -class GridLayoutAttached; -class QGraphicsGridLayoutObject : public QObject, public QGraphicsGridLayout -{ - Q_OBJECT - Q_INTERFACES(QGraphicsLayout QGraphicsLayoutItem) - - Q_PROPERTY(QDeclarativeListProperty<QGraphicsLayoutItem> children READ children) - Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing) - Q_PROPERTY(qreal contentsMargin READ contentsMargin WRITE setContentsMargin) - Q_PROPERTY(qreal verticalSpacing READ verticalSpacing WRITE setVerticalSpacing) - Q_PROPERTY(qreal horizontalSpacing READ horizontalSpacing WRITE setHorizontalSpacing) - Q_CLASSINFO("DefaultProperty", "children") -public: - QGraphicsGridLayoutObject(QObject * = 0); - ~QGraphicsGridLayoutObject(); - - QDeclarativeListProperty<QGraphicsLayoutItem> children() { return QDeclarativeListProperty<QGraphicsLayoutItem>(this, 0, children_append, children_count, children_at, children_clear); } - - qreal spacing() const; - qreal contentsMargin() const; - void setContentsMargin(qreal); - - static GridLayoutAttached *qmlAttachedProperties(QObject *); - -private Q_SLOTS: - void updateAlignment(QGraphicsLayoutItem*,Qt::Alignment); - -private: - friend class GraphicsLayoutAttached; - void addWidget(QGraphicsWidget *); - void clearChildren(); - void addLayoutItem(QGraphicsLayoutItem *); - static QHash<QGraphicsLayoutItem*, GridLayoutAttached*> attachedProperties; - - static void children_append(QDeclarativeListProperty<QGraphicsLayoutItem> *prop, QGraphicsLayoutItem *item) { - static_cast<QGraphicsGridLayoutObject*>(prop->object)->addLayoutItem(item); - } - - static void children_clear(QDeclarativeListProperty<QGraphicsLayoutItem> *prop) { - static_cast<QGraphicsGridLayoutObject*>(prop->object)->clearChildren(); - } - - static int children_count(QDeclarativeListProperty<QGraphicsLayoutItem> *prop) { - return static_cast<QGraphicsGridLayoutObject*>(prop->object)->count(); - } - - static QGraphicsLayoutItem *children_at(QDeclarativeListProperty<QGraphicsLayoutItem> *prop, int index) { - return static_cast<QGraphicsGridLayoutObject*>(prop->object)->itemAt(index); - } -}; - -class LinearLayoutAttached : public QObject -{ - Q_OBJECT - - Q_PROPERTY(int stretchFactor READ stretchFactor WRITE setStretchFactor NOTIFY stretchChanged) - Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment NOTIFY alignmentChanged) - Q_PROPERTY(int spacing READ spacing WRITE setSpacing NOTIFY spacingChanged) -public: - LinearLayoutAttached(QObject *parent); - - int stretchFactor() const { return _stretch; } - void setStretchFactor(int f); - Qt::Alignment alignment() const { return _alignment; } - void setAlignment(Qt::Alignment a); - int spacing() const { return _spacing; } - void setSpacing(int s); - -Q_SIGNALS: - void stretchChanged(QGraphicsLayoutItem*,int); - void alignmentChanged(QGraphicsLayoutItem*,Qt::Alignment); - void spacingChanged(QGraphicsLayoutItem*,int); - -private: - int _stretch; - Qt::Alignment _alignment; - int _spacing; -}; - -class GridLayoutAttached : public QObject -{ - Q_OBJECT - - Q_PROPERTY(int row READ row WRITE setRow) - Q_PROPERTY(int column READ column WRITE setColumn) - Q_PROPERTY(int rowSpan READ rowSpan WRITE setRowSpan) - Q_PROPERTY(int columnSpan READ columnSpan WRITE setColumnSpan) - Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment) - Q_PROPERTY(int rowStretchFactor READ rowStretchFactor WRITE setRowStretchFactor) - Q_PROPERTY(int columnStretchFactor READ columnStretchFactor WRITE setColumnStretchFactor) - Q_PROPERTY(int rowSpacing READ rowSpacing WRITE setRowSpacing) - Q_PROPERTY(int columnSpacing READ columnSpacing WRITE setColumnSpacing) - Q_PROPERTY(int rowPreferredHeight READ rowPreferredHeight WRITE setRowPreferredHeight) - Q_PROPERTY(int rowMinimumHeight READ rowMinimumHeight WRITE setRowMinimumHeight) - Q_PROPERTY(int rowMaximumHeight READ rowMaximumHeight WRITE setRowMaximumHeight) - Q_PROPERTY(int rowFixedHeight READ rowFixedHeight WRITE setRowFixedHeight) - Q_PROPERTY(int columnPreferredWidth READ columnPreferredWidth WRITE setColumnPreferredWidth) - Q_PROPERTY(int columnMaximumWidth READ columnMaximumWidth WRITE setColumnMaximumWidth) - Q_PROPERTY(int columnMinimumWidth READ columnMinimumWidth WRITE setColumnMinimumWidth) - Q_PROPERTY(int columnFixedWidth READ columnFixedWidth WRITE setColumnFixedWidth) - -public: - GridLayoutAttached(QObject *parent); - - int row() const { return _row; } - void setRow(int r); - - int column() const { return _column; } - void setColumn(int c); - - int rowSpan() const { return _rowspan; } - void setRowSpan(int rs); - - int columnSpan() const { return _colspan; } - void setColumnSpan(int cs); - - Qt::Alignment alignment() const { return _alignment; } - void setAlignment(Qt::Alignment a); - - int rowStretchFactor() const { return _rowstretch; } - void setRowStretchFactor(int f); - int columnStretchFactor() const { return _colstretch; } - void setColumnStretchFactor(int f); - - int rowSpacing() const { return _rowspacing; } - void setRowSpacing(int s); - int columnSpacing() const { return _colspacing; } - void setColumnSpacing(int s); - - int rowPreferredHeight() const { return _rowprefheight; } - void setRowPreferredHeight(int s) { _rowprefheight = s; } - - int rowMaximumHeight() const { return _rowmaxheight; } - void setRowMaximumHeight(int s) { _rowmaxheight = s; } - - int rowMinimumHeight() const { return _rowminheight; } - void setRowMinimumHeight(int s) { _rowminheight = s; } - - int rowFixedHeight() const { return _rowfixheight; } - void setRowFixedHeight(int s) { _rowfixheight = s; } - - int columnPreferredWidth() const { return _colprefwidth; } - void setColumnPreferredWidth(int s) { _colprefwidth = s; } - - int columnMaximumWidth() const { return _colmaxwidth; } - void setColumnMaximumWidth(int s) { _colmaxwidth = s; } - - int columnMinimumWidth() const { return _colminwidth; } - void setColumnMinimumWidth(int s) { _colminwidth = s; } - - int columnFixedWidth() const { return _colfixwidth; } - void setColumnFixedWidth(int s) { _colfixwidth = s; } - -Q_SIGNALS: - void alignmentChanged(QGraphicsLayoutItem*,Qt::Alignment); - -private: - int _row; - int _column; - int _rowspan; - int _colspan; - Qt::Alignment _alignment; - int _rowstretch; - int _colstretch; - int _rowspacing; - int _colspacing; - int _rowprefheight; - int _rowmaxheight; - int _rowminheight; - int _rowfixheight; - int _colprefwidth; - int _colmaxwidth; - int _colminwidth; - int _colfixwidth; -}; - -QT_END_NAMESPACE - -QML_DECLARE_INTERFACE(QGraphicsLayoutItem) -QML_DECLARE_INTERFACE(QGraphicsLayout) -QML_DECLARE_TYPE(QGraphicsLinearLayoutStretchItemObject) -QML_DECLARE_TYPE(QGraphicsLinearLayoutObject) -QML_DECLARE_TYPEINFO(QGraphicsLinearLayoutObject, QML_HAS_ATTACHED_PROPERTIES) -QML_DECLARE_TYPE(QGraphicsGridLayoutObject) -QML_DECLARE_TYPEINFO(QGraphicsGridLayoutObject, QML_HAS_ATTACHED_PROPERTIES) - -QT_END_HEADER - -#endif // GRAPHICSLAYOUTS_H diff --git a/src/imports/widgets/qmldir b/src/imports/widgets/qmldir deleted file mode 100644 index 6f19878..0000000 --- a/src/imports/widgets/qmldir +++ /dev/null @@ -1 +0,0 @@ -plugin widgets diff --git a/src/imports/widgets/widgets.cpp b/src/imports/widgets/widgets.cpp deleted file mode 100644 index 20de1fe..0000000 --- a/src/imports/widgets/widgets.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the plugins 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 <QtDeclarative/qdeclarativeextensionplugin.h> -#include <QtDeclarative/qdeclarative.h> -#include <QGraphicsWidget> - -#include "graphicslayouts_p.h" -#include <private/qdeclarativegraphicswidget_p.h> -QT_BEGIN_NAMESPACE - -class QWidgetsQmlModule : public QDeclarativeExtensionPlugin -{ - Q_OBJECT -public: - virtual void registerTypes(const char *uri) - { - Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.widgets")); - - qmlRegisterInterface<QGraphicsLayoutItem>("QGraphicsLayoutItem"); - qmlRegisterInterface<QGraphicsLayout>("QGraphicsLayout"); - qmlRegisterType<QGraphicsLinearLayoutStretchItemObject>(uri,4,7,"QGraphicsLinearLayoutStretchItem"); - qmlRegisterType<QGraphicsLinearLayoutObject>(uri,4,7,"QGraphicsLinearLayout"); - qmlRegisterType<QGraphicsGridLayoutObject>(uri,4,7,"QGraphicsGridLayout"); - } -}; - -QT_END_NAMESPACE - -#include "widgets.moc" - -Q_EXPORT_PLUGIN2(qtwidgetsqmlmodule, QT_PREPEND_NAMESPACE(QWidgetsQmlModule)); - diff --git a/src/imports/widgets/widgets.pro b/src/imports/widgets/widgets.pro deleted file mode 100644 index 234ff1e..0000000 --- a/src/imports/widgets/widgets.pro +++ /dev/null @@ -1,30 +0,0 @@ -TARGET = widgets -TARGETPATH = Qt/widgets -include(../qimportbase.pri) - -QT += declarative - -SOURCES += \ - graphicslayouts.cpp \ - widgets.cpp - -HEADERS += \ - graphicslayouts_p.h - -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH -target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH - -qmldir.files += $$PWD/qmldir -qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH - -symbian:{ - load(data_caging_paths) - include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri) - - importFiles.sources = widgets.dll qmldir - importFiles.path = $$QT_IMPORTS_BASE_DIR/$$TARGETPATH - - DEPLOYMENT = importFiles -} - -INSTALLS += target qmldir diff --git a/src/multimedia/mediaservices/mediaservices.pro b/src/multimedia/mediaservices/mediaservices.pro index d5b0e4c..8a065f4 100644 --- a/src/multimedia/mediaservices/mediaservices.pro +++ b/src/multimedia/mediaservices/mediaservices.pro @@ -2,6 +2,8 @@ TARGET = QtMediaServices QPRO_PWD = $$PWD QT = core gui multimedia +contains(QT_CONFIG, opengl): QT += opengl + DEFINES += QT_BUILD_MEDIASERVICES_LIB QT_NO_USING_NAMESPACE unix:QMAKE_PKGCONFIG_REQUIRES = QtCore QtGui QtMultimedia diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h index adc69ee..46029b9 100644 --- a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h +++ b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h @@ -100,8 +100,10 @@ class QGL2PEXVertexArray { public: QGL2PEXVertexArray() : + vertexArray(0), vertexArrayStops(0), maxX(-2e10), maxY(-2e10), minX(2e10), minY(2e10), - boundingRectDirty(true) {} + boundingRectDirty(true) + { } inline void addRect(const QRectF &rect) { diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 6ba0c42..0a046dc 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -177,6 +177,7 @@ public: ctx(0), useSystemClip(true), elementIndicesVBOId(0), + opacityArray(0), snapToPixelGrid(false), addOffset(false), nativePaintingActive(false), diff --git a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp index f677ce1..9bc099d 100644 --- a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp +++ b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp @@ -481,7 +481,8 @@ static void qdashprocessor_cubicTo(qreal, qreal, qreal, qreal, qreal, qreal, voi } QDashedStrokeProcessor::QDashedStrokeProcessor() - : m_dash_stroker(0), m_inv_scale(1) + : m_points(0), m_types(0), + m_dash_stroker(0), m_inv_scale(1) { m_dash_stroker.setMoveToHook(qdashprocessor_moveTo); m_dash_stroker.setLineToHook(qdashprocessor_lineTo); @@ -499,6 +500,8 @@ void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen, c m_points.reset(); m_types.reset(); + m_points.reserve(path.elementCount()); + m_types.reserve(path.elementCount()); qreal width = qpen_widthf(pen); if (width == 0) diff --git a/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h b/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h index 956d7cc..ab27ed6 100644 --- a/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h +++ b/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h @@ -54,6 +54,7 @@ QT_BEGIN_NAMESPACE class QTriangulatingStroker { public: + QTriangulatingStroker() : m_vertices(0) {} void process(const QVectorPath &path, const QPen &pen, const QRectF &clip); inline int vertexCount() const { return m_vertices.size(); } diff --git a/src/opengl/gl2paintengineex/qtriangulator.cpp b/src/opengl/gl2paintengineex/qtriangulator.cpp index ce917ff..df7cbc2 100644 --- a/src/opengl/gl2paintengineex/qtriangulator.cpp +++ b/src/opengl/gl2paintengineex/qtriangulator.cpp @@ -510,6 +510,7 @@ template <class T> class QMaxHeap { public: + QMaxHeap() : m_data(0) {} inline int size() const {return m_data.size();} inline bool empty() const {return m_data.isEmpty();} inline bool isEmpty() const {return m_data.isEmpty();} @@ -1299,7 +1300,8 @@ public: class ComplexToSimple { public: - inline ComplexToSimple(QTriangulator *parent) : m_parent(parent) { } + inline ComplexToSimple(QTriangulator *parent) : m_parent(parent), + m_edges(0), m_events(0), m_splits(0) { } void decompose(); private: struct Edge @@ -1412,7 +1414,7 @@ public: class SimpleToMonotone { public: - inline SimpleToMonotone(QTriangulator *parent) : m_parent(parent) { } + inline SimpleToMonotone(QTriangulator *parent) : m_parent(parent), m_edges(0), m_upperVertex(0) { } void decompose(); private: enum VertexType {MergeVertex, EndVertex, RegularVertex, StartVertex, SplitVertex}; @@ -1486,7 +1488,7 @@ public: int m_length; }; - inline QTriangulator() { } + inline QTriangulator() : m_vertices(0) { } // Call this only once. void initialize(const qreal *polygon, int count, uint hint, const QTransform &matrix); @@ -2709,7 +2711,7 @@ void QTriangulator::SimpleToMonotone::monotoneDecomposition() return; Q_ASSERT(!m_edgeList.root); - QDataBuffer<QPair<int, int> > diagonals; + QDataBuffer<QPair<int, int> > diagonals(m_upperVertex.size()); int i = 0; for (int index = 1; index < m_edges.size(); ++index) { @@ -2853,7 +2855,7 @@ bool QTriangulator::SimpleToMonotone::CompareVertices::operator () (int i, int j void QTriangulator::MonotoneToTriangles::decompose() { QVector<quint32> result; - QDataBuffer<int> stack; + QDataBuffer<int> stack(m_parent->m_indices.size()); m_first = 0; // Require at least three more indices. while (m_first + 3 <= m_parent->m_indices.size()) { diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index 306fd8b..d2b0d4f 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -668,6 +668,7 @@ public: , last_created_state(0) , shader_ctx(0) , grad_palette(0) + , tess_points(0) , drawable_texture(0) , ref_cleaner(this) {} @@ -1950,6 +1951,8 @@ void QOpenGLPaintEnginePrivate::pathToVertexArrays(const QPainterPath &path) void QOpenGLPaintEnginePrivate::drawVertexArrays() { + if (tess_points_stops.count() == 0) + return; glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_DOUBLE, 0, tess_points.data()); int previous_stop = 0; |