aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--examples/quick/rendercontrol/window_singlethreaded.cpp5
-rw-r--r--src/particles/qquickparticleemitter.cpp2
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc4
-rw-r--r--src/qml/qml/qqmlcomponent.cpp7
-rw-r--r--src/qmltest/quicktest.cpp2
-rw-r--r--src/quick/items/context2d/qquickcontext2dtexture.cpp5
-rw-r--r--src/quick/items/qquickflickable.cpp36
-rw-r--r--src/quick/items/qquickflickable_p.h1
-rw-r--r--src/quick/items/qquickflickable_p_p.h1
-rw-r--r--src/quick/items/qquickgridview.cpp80
-rw-r--r--src/quick/items/qquickitem.cpp2
-rw-r--r--src/quick/items/qquickitemview.cpp6
-rw-r--r--src/quick/items/qquickwindowattached.cpp16
-rw-r--r--src/quick/util/qquickanimator.cpp19
-rw-r--r--src/quick/util/qquickanimator_p_p.h2
-rw-r--r--src/quick/util/qquickpixmapcache.cpp2
-rw-r--r--tests/auto/quick/qquickanimators/data/positionerWithAnimator.qml63
-rw-r--r--tests/auto/quick/qquickanimators/tst_qquickanimators.cpp25
-rw-r--r--tests/auto/quick/qquickgridview/data/qtbug48870.qml30
-rw-r--r--tests/auto/quick/qquickgridview/tst_qquickgridview.cpp38
-rw-r--r--tests/auto/quick/qquicklistview/tst_qquicklistview.cpp92
-rw-r--r--tests/auto/quick/qquickwindow/tst_qquickwindow.cpp5
-rw-r--r--tests/auto/quick/shared/viewtestutil.cpp80
-rw-r--r--tests/auto/quick/shared/viewtestutil.h22
-rw-r--r--tests/manual/scenegraph_lancelot/data/text/textedit_multiline_selected_linebreaks_and_linewraps.qml22
-rw-r--r--tools/qmlimportscanner/main.cpp16
-rw-r--r--tools/qmlplugindump/main.cpp42
-rw-r--r--tools/qmlplugindump/qmlplugindump.pro6
-rw-r--r--tools/qmlplugindump/qmltypereader.cpp63
-rw-r--r--tools/qmlplugindump/qmltypereader.h42
31 files changed, 580 insertions, 158 deletions
diff --git a/.qmake.conf b/.qmake.conf
index fc13c75da5..5c42719444 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -2,4 +2,4 @@ load(qt_build_config)
CONFIG += qt_example_installs
CONFIG += warning_clean
-MODULE_VERSION = 5.6.0
+MODULE_VERSION = 5.6.1
diff --git a/examples/quick/rendercontrol/window_singlethreaded.cpp b/examples/quick/rendercontrol/window_singlethreaded.cpp
index e43093e241..45f2635ca4 100644
--- a/examples/quick/rendercontrol/window_singlethreaded.cpp
+++ b/examples/quick/rendercontrol/window_singlethreaded.cpp
@@ -265,9 +265,10 @@ void WindowSingleThreaded::startQuick(const QString &filename)
void WindowSingleThreaded::exposeEvent(QExposeEvent *)
{
if (isExposed()) {
- m_cubeRenderer->render(this, m_context, m_quickReady ? m_fbo->texture() : 0);
- if (!m_quickInitialized)
+ if (!m_quickInitialized) {
+ m_cubeRenderer->render(this, m_context, m_quickReady ? m_fbo->texture() : 0);
startQuick(QStringLiteral("qrc:/rendercontrol/demo.qml"));
+ }
}
}
diff --git a/src/particles/qquickparticleemitter.cpp b/src/particles/qquickparticleemitter.cpp
index e34356aa66..296f215174 100644
--- a/src/particles/qquickparticleemitter.cpp
+++ b/src/particles/qquickparticleemitter.cpp
@@ -337,7 +337,7 @@ void QQuickParticleEmitter::emitWindow(int timeStamp)
{
if (m_system == 0)
return;
- if ((!m_enabled || !m_particlesPerSecond)&& !m_pulseLeft && m_burstQueue.isEmpty()){
+ if ((!m_enabled || m_particlesPerSecond <= 0)&& !m_pulseLeft && m_burstQueue.isEmpty()){
m_reset_last = true;
return;
}
diff --git a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
index c0b74c4fc6..04d769e4dc 100644
--- a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
+++ b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
@@ -448,8 +448,8 @@ right-hand-side of the property declaration must be a valid alias reference:
[default] property alias <name>: <alias reference>
\endcode
-Unlike an ordinary property, an alias can only refer to a object, or the
-property of a object, that is within the scope of the \l{QML Object Types}
+Unlike an ordinary property, an alias can only refer to an object, or the
+property of an object, that is within the scope of the \l{QML Object Types}
{type} within which the alias is declared. It cannot contain arbitrary
JavaScript expressions and it cannot refer to objects declared outside of
the scope of its type. Also note the \e {alias reference} is not optional,
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 22a54d732e..9b52a951af 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -372,6 +372,13 @@ QQmlComponent::~QQmlComponent()
if (d->state.completePending) {
qWarning("QQmlComponent: Component destroyed while completion pending");
+
+ if (isError()) {
+ qWarning() << "This may have been caused by one of the following errors:";
+ foreach (const QQmlError &error, d->state.errors)
+ qWarning().nospace().noquote() << QLatin1String(" ") << error;
+ }
+
d->completeCreate();
}
diff --git a/src/qmltest/quicktest.cpp b/src/qmltest/quicktest.cpp
index c90308cf1a..3dbea37d27 100644
--- a/src/qmltest/quicktest.cpp
+++ b/src/qmltest/quicktest.cpp
@@ -290,7 +290,7 @@ int quick_test_main(int argc, char **argv, const char *name, const char *sourceD
const QFileInfo testPathInfo(testPath);
if (testPathInfo.isFile()) {
- if (!testPath.endsWith(QStringLiteral(".qml"))) {
+ if (!testPath.endsWith(QLatin1String(".qml"))) {
qWarning("'%s' does not have the suffix '.qml'.", qPrintable(testPath));
return 1;
}
diff --git a/src/quick/items/context2d/qquickcontext2dtexture.cpp b/src/quick/items/context2d/qquickcontext2dtexture.cpp
index 73b0b55a29..5ac971dc7d 100644
--- a/src/quick/items/context2d/qquickcontext2dtexture.cpp
+++ b/src/quick/items/context2d/qquickcontext2dtexture.cpp
@@ -599,6 +599,11 @@ QPaintDevice* QQuickContext2DFBOTexture::beginPainting()
void QQuickContext2DFBOTexture::endPainting()
{
QQuickContext2DTexture::endPainting();
+
+ // There may not be an FBO due to zero width or height.
+ if (!m_fbo)
+ return;
+
if (m_multisampledFbo)
QOpenGLFramebufferObject::blitFramebuffer(m_fbo, m_multisampledFbo);
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 43405db40d..b568db1d26 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -59,6 +59,8 @@ static const int FlickThreshold = 15;
// will ensure the Flickable retains the grab on consecutive flicks.
static const int RetainGrabVelocity = 100;
+static const int MovementEndingTimerInterval = 100;
+
static qreal EaseOvershoot(qreal t) {
return qAtan(t);
}
@@ -238,6 +240,8 @@ void QQuickFlickablePrivate::init()
contentItem->setParentItem(q);
qmlobject_connect(&timeline, QQuickTimeLine, SIGNAL(completed()),
q, QQuickFlickable, SLOT(timelineCompleted()))
+ qmlobject_connect(&velocityTimeline, QQuickTimeLine, SIGNAL(completed()),
+ q, QQuickFlickable, SLOT(velocityTimelineCompleted()))
q->setAcceptedMouseButtons(Qt::LeftButton);
q->setFiltersChildMouseEvents(true);
QQuickItemPrivate *viewportPrivate = QQuickItemPrivate::get(contentItem);
@@ -1196,6 +1200,8 @@ void QQuickFlickablePrivate::drag(qint64 currentTimestamp, QEvent::Type eventTyp
hData.velocity = 0;
}
+ if (momentum && !hData.flicking && !vData.flicking)
+ flickingStarted(hData.velocity != 0, vData.velocity != 0);
draggingStarting();
if ((hMoved && !prevHMoved) || (vMoved && !prevVMoved))
@@ -1385,9 +1391,15 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event)
d->maybeBeginDrag(currentTimestamp, event->posF());
break;
case Qt::ScrollUpdate:
+ if (d->scrollingPhase) {
+ d->pressed = true;
+ d->movementEndingTimer.start(MovementEndingTimerInterval, this);
+ }
break;
case Qt::ScrollEnd:
+ d->pressed = false;
d->scrollingPhase = false;
+ d->movementEndingTimer.start(MovementEndingTimerInterval, this);
d->draggingEnding();
event->accept();
returnToBounds();
@@ -1409,7 +1421,6 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event)
valid = true;
}
if (valid) {
- d->vData.flicking = false;
d->flickY(d->vData.velocity);
d->flickingStarted(false, true);
if (d->vData.flicking) {
@@ -1429,7 +1440,6 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event)
valid = true;
}
if (valid) {
- d->hData.flicking = false;
d->flickX(d->hData.velocity);
d->flickingStarted(true, false);
if (d->hData.flicking) {
@@ -1542,6 +1552,12 @@ void QQuickFlickable::timerEvent(QTimerEvent *event)
if (d->delayedPressEvent) {
d->replayDelayedPress();
}
+ } else if (event->timerId() == d->movementEndingTimer.timerId()) {
+ d->movementEndingTimer.stop();
+ d->pressed = false;
+ d->stealMouse = false;
+ if (!d->velocityTimeline.isActive())
+ movementEnding(true, true);
}
}
@@ -2469,6 +2485,22 @@ bool QQuickFlickable::isMovingVertically() const
return d->vData.moving;
}
+void QQuickFlickable::velocityTimelineCompleted()
+{
+ Q_D(QQuickFlickable);
+ if ( (d->hData.transitionToBounds && d->hData.transitionToBounds->isActive())
+ || (d->vData.transitionToBounds && d->vData.transitionToBounds->isActive()) ) {
+ return;
+ }
+ // With subclasses such as GridView, velocityTimeline.completed is emitted repeatedly:
+ // for example setting currentIndex results in a visual "flick" which the user
+ // didn't initiate directly. We don't want to end movement repeatedly, and in
+ // that case movementEnding will happen after the sequence of movements ends.
+ if (d->vData.flicking)
+ movementEnding();
+ d->updateBeginningEnd();
+}
+
void QQuickFlickable::timelineCompleted()
{
Q_D(QQuickFlickable);
diff --git a/src/quick/items/qquickflickable_p.h b/src/quick/items/qquickflickable_p.h
index ac072f0e50..f1299ee4f2 100644
--- a/src/quick/items/qquickflickable_p.h
+++ b/src/quick/items/qquickflickable_p.h
@@ -253,6 +253,7 @@ protected Q_SLOTS:
void movementStarting();
void movementEnding();
void movementEnding(bool hMovementEnding, bool vMovementEnding);
+ void velocityTimelineCompleted();
void timelineCompleted();
protected:
diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h
index 9d75533c8a..ea46720cb6 100644
--- a/src/quick/items/qquickflickable_p_p.h
+++ b/src/quick/items/qquickflickable_p_p.h
@@ -212,6 +212,7 @@ public:
bool calcVelocity : 1;
bool pixelAligned : 1;
QElapsedTimer timer;
+ QBasicTimer movementEndingTimer;
qint64 lastPosTime;
qint64 lastPressTime;
QPointF lastPos;
diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp
index 65d7362e84..8d84144519 100644
--- a/src/quick/items/qquickgridview.cpp
+++ b/src/quick/items/qquickgridview.cpp
@@ -176,6 +176,8 @@ public:
bool addVisibleItems(qreal fillFrom, qreal fillTo, qreal bufferFrom, qreal bufferTo, bool doBuffer) Q_DECL_OVERRIDE;
bool removeNonVisibleItems(qreal bufferFrom, qreal bufferTo) Q_DECL_OVERRIDE;
+ void removeItem(FxViewItem *item);
+
FxViewItem *newViewItem(int index, QQuickItem *item) Q_DECL_OVERRIDE;
void initializeViewItem(FxViewItem *item) Q_DECL_OVERRIDE;
void repositionItemAt(FxViewItem *item, int index, qreal sizeBuffer) Q_DECL_OVERRIDE;
@@ -561,6 +563,17 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal
return changed;
}
+void QQuickGridViewPrivate::removeItem(FxViewItem *item)
+{
+ if (item->transitionScheduledOrRunning()) {
+ qCDebug(lcItemViewDelegateLifecycle) << "\tnot releasing animating item:" << item->index << item->item->objectName();
+ item->releaseAfterTransition = true;
+ releasePendingTransition.append(item);
+ } else {
+ releaseItem(item);
+ }
+}
+
bool QQuickGridViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal bufferTo)
{
FxGridItemSG *item = 0;
@@ -575,13 +588,7 @@ bool QQuickGridViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal buffer
if (item->index != -1)
visibleIndex++;
visibleItems.removeFirst();
- if (item->transitionScheduledOrRunning()) {
- qCDebug(lcItemViewDelegateLifecycle) << "\tnot releasing animating item:" << item->index << item->item->objectName();
- item->releaseAfterTransition = true;
- releasePendingTransition.append(item);
- } else {
- releaseItem(item);
- }
+ removeItem(item);
changed = true;
}
while (visibleItems.count() > 1
@@ -591,13 +598,7 @@ bool QQuickGridViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal buffer
break;
qCDebug(lcItemViewDelegateLifecycle) << "refill: remove last" << visibleIndex+visibleItems.count()-1;
visibleItems.removeLast();
- if (item->transitionScheduledOrRunning()) {
- qCDebug(lcItemViewDelegateLifecycle) << "\tnot releasing animating item:" << item->index << item->item->objectName();
- item->releaseAfterTransition = true;
- releasePendingTransition.append(item);
- } else {
- releaseItem(item);
- }
+ removeItem(item);
changed = true;
}
@@ -2380,11 +2381,12 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
int i = count - 1;
int from = tempPos - buffer - displayMarginBeginning;
- while (i >= 0) {
- if (rowPos > from && insertionIdx < visibleIndex) {
- // item won't be visible, just note the size for repositioning
- insertResult->countChangeBeforeVisible++;
- } else {
+ if (rowPos > from && insertionIdx < visibleIndex) {
+ // items won't be visible, just note the size for repositioning
+ insertResult->countChangeBeforeVisible += count;
+ insertResult->sizeChangesBeforeVisiblePos += ((count + columns - 1) / columns) * rowSize();
+ } else {
+ while (i >= 0) {
// item is before first visible e.g. in cache buffer
FxViewItem *item = 0;
if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i))))
@@ -2400,19 +2402,40 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
insertResult->changedFirstItem = true;
if (!change.isMove()) {
addedItems->append(item);
- item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true);
+ if (transitioner)
+ item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true);
+ else
+ item->moveTo(QPointF(colPos, rowPos), true);
}
insertResult->sizeChangesBeforeVisiblePos += rowSize();
+
+ if (--colNum < 0 ) {
+ colNum = columns - 1;
+ rowPos -= rowSize();
+ }
+ colPos = colNum * colSize();
+ index++;
+ i--;
}
+ }
- if (--colNum < 0 ) {
- colNum = columns - 1;
- rowPos -= rowSize();
+ // There may be gaps in the index sequence of visibleItems because
+ // of the index shift/update done before the insertion just above.
+ // Find if there is any...
+ int firstOkIdx = -1;
+ for (int i = 0; i <= insertionIdx && i < visibleItems.count() - 1; i++) {
+ if (visibleItems.at(i)->index + 1 != visibleItems.at(i + 1)->index) {
+ firstOkIdx = i + 1;
+ break;
}
- colPos = colNum * colSize();
- index++;
- i--;
}
+ // ... and remove all the items before that one
+ for (int i = 0; i < firstOkIdx; i++) {
+ FxViewItem *nvItem = visibleItems.takeFirst();
+ addedItems->removeOne(nvItem);
+ removeItem(nvItem);
+ }
+
} else {
int i = 0;
int to = buffer+displayMarginEnd+tempPos+size()-1;
@@ -2437,7 +2460,10 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
movingIntoView->append(MovedItem(item, change.moveKey(item->index)));
} else {
addedItems->append(item);
- item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true);
+ if (transitioner)
+ item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true);
+ else
+ item->moveTo(QPointF(colPos, rowPos), true);
}
insertResult->sizeChangesAfterVisiblePos += rowSize();
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 2dc7a29a30..24e52ff65e 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -7226,7 +7226,7 @@ void QQuickItem::setKeepTouchGrab(bool keep)
}
/*!
- \qmlmethod object QtQuick::Item::contains(point point)
+ \qmlmethod bool QtQuick::Item::contains(point point)
Returns true if this item contains \a point, which is in local coordinates;
returns false otherwise.
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index e301e8f0f2..fbaec28c7c 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -2452,8 +2452,10 @@ void QQuickItemViewPrivate::updateUnrequestedIndexes()
void QQuickItemViewPrivate::updateUnrequestedPositions()
{
- for (QHash<QQuickItem*,int>::const_iterator it = unrequestedItems.cbegin(), cend = unrequestedItems.cend(); it != cend; ++it)
- repositionPackageItemAt(it.key(), it.value());
+ for (QHash<QQuickItem*,int>::const_iterator it = unrequestedItems.cbegin(), cend = unrequestedItems.cend(); it != cend; ++it) {
+ if (it.value() >= 0)
+ repositionPackageItemAt(it.key(), it.value());
+ }
}
void QQuickItemViewPrivate::updateVisibleIndex()
diff --git a/src/quick/items/qquickwindowattached.cpp b/src/quick/items/qquickwindowattached.cpp
index e33e32631c..b1961386bb 100644
--- a/src/quick/items/qquickwindowattached.cpp
+++ b/src/quick/items/qquickwindowattached.cpp
@@ -89,21 +89,21 @@ void QQuickWindowAttached::windowChanged(QQuickWindow *window)
if (oldWindow)
oldWindow->disconnect(this);
- if (!window)
- return; // No values to get, therefore nothing to emit
-
- if (!oldWindow || window->visibility() != oldWindow->visibility())
+ if (!oldWindow || !window || window->visibility() != oldWindow->visibility())
emit visibilityChanged();
- if (!oldWindow || window->isActive() != oldWindow->isActive())
+ if (!oldWindow || !window || window->isActive() != oldWindow->isActive())
emit activeChanged();
- if (!oldWindow || window->activeFocusItem() != oldWindow->activeFocusItem())
+ if (!oldWindow || !window || window->activeFocusItem() != oldWindow->activeFocusItem())
emit activeFocusItemChanged();
emit contentItemChanged();
- if (!oldWindow || window->width() != oldWindow->width())
+ if (!oldWindow || !window || window->width() != oldWindow->width())
emit widthChanged();
- if (!oldWindow || window->height() != oldWindow->height())
+ if (!oldWindow || !window || window->height() != oldWindow->height())
emit heightChanged();
+ if (!window)
+ return;
+
// QQuickWindowQmlImpl::visibilityChanged also exists, and window might even
// be QQuickWindowQmlImpl, but that's not what we are connecting to.
// So this is actual window state rather than a buffered or as-requested one.
diff --git a/src/quick/util/qquickanimator.cpp b/src/quick/util/qquickanimator.cpp
index 8a5cad4011..ca6dc74519 100644
--- a/src/quick/util/qquickanimator.cpp
+++ b/src/quick/util/qquickanimator.cpp
@@ -211,7 +211,8 @@ qreal QQuickAnimator::from() const
void QQuickAnimatorPrivate::apply(QQuickAnimatorJob *job,
const QString &propertyName,
QQuickStateActions &actions,
- QQmlProperties &modified)
+ QQmlProperties &modified,
+ QObject *defaultTarget)
{
if (actions.size()) {
@@ -243,14 +244,20 @@ void QQuickAnimatorPrivate::apply(QQuickAnimatorJob *job,
// the item when a transition is cancelled.
action.fromValue = action.toValue;
}
- } else {
+ }
+
+ if (modified.isEmpty()) {
job->setTarget(target);
job->setFrom(from);
job->setTo(to);
}
- if (!job->target() && defaultProperty.object())
- job->setTarget(qobject_cast<QQuickItem *>(defaultProperty.object()));
+ if (!job->target()) {
+ if (defaultProperty.object())
+ job->setTarget(qobject_cast<QQuickItem *>(defaultProperty.object()));
+ else
+ job->setTarget(qobject_cast<QQuickItem *>(defaultTarget));
+ }
job->setDuration(duration);
job->setLoopCount(loopCount);
@@ -260,7 +267,7 @@ void QQuickAnimatorPrivate::apply(QQuickAnimatorJob *job,
QAbstractAnimationJob *QQuickAnimator::transition(QQuickStateActions &actions,
QQmlProperties &modified,
TransitionDirection direction,
- QObject *)
+ QObject *defaultTarget)
{
Q_D(QQuickAnimator);
@@ -277,7 +284,7 @@ QAbstractAnimationJob *QQuickAnimator::transition(QQuickStateActions &actions,
if (!job)
return 0;
- d->apply(job, propertyName(), actions, modified);
+ d->apply(job, propertyName(), actions, modified, defaultTarget);
if (!job->target()) {
delete job;
diff --git a/src/quick/util/qquickanimator_p_p.h b/src/quick/util/qquickanimator_p_p.h
index f5f0295f74..11598bf78e 100644
--- a/src/quick/util/qquickanimator_p_p.h
+++ b/src/quick/util/qquickanimator_p_p.h
@@ -76,7 +76,7 @@ public:
uint isFromDefined : 1;
uint isToDefined : 1;
- void apply(QQuickAnimatorJob *job, const QString &propertyName, QQuickStateActions &actions, QQmlProperties &modified);
+ void apply(QQuickAnimatorJob *job, const QString &propertyName, QQuickStateActions &actions, QQmlProperties &modified, QObject *defaultTarget);
};
class QQuickRotationAnimatorPrivate : public QQuickAnimatorPrivate
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp
index ed6da8ac91..36374e628e 100644
--- a/src/quick/util/qquickpixmapcache.cpp
+++ b/src/quick/util/qquickpixmapcache.cpp
@@ -1185,8 +1185,6 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
*ok = true;
return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, autoTransform, appliedTransform);
}
- errorString = QQuickPixmap::tr("Invalid image data: %1").arg(url.toString());
-
} else {
errorString = QQuickPixmap::tr("Cannot open: %1").arg(url.toString());
}
diff --git a/tests/auto/quick/qquickanimators/data/positionerWithAnimator.qml b/tests/auto/quick/qquickanimators/data/positionerWithAnimator.qml
new file mode 100644
index 0000000000..bfd475266e
--- /dev/null
+++ b/tests/auto/quick/qquickanimators/data/positionerWithAnimator.qml
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+
+Column {
+ width: 200
+ height: 200
+
+ property alias repeater: repeater
+ property alias transition: transition
+
+ anchors.centerIn: parent
+ populate: Transition {
+ id: transition
+ ScaleAnimator {
+ from: 0
+ to: 1
+ }
+ }
+
+ Repeater {
+ id: repeater
+ model: ["red", "green", "blue"]
+
+ Rectangle {
+ width: 100
+ height: 100
+ color: modelData
+ scale: 0
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickanimators/tst_qquickanimators.cpp b/tests/auto/quick/qquickanimators/tst_qquickanimators.cpp
index 4108c1a124..7cacf3ba90 100644
--- a/tests/auto/quick/qquickanimators/tst_qquickanimators.cpp
+++ b/tests/auto/quick/qquickanimators/tst_qquickanimators.cpp
@@ -35,6 +35,8 @@
#include <QtQuick>
#include <private/qquickanimator_p.h>
+#include <private/qquickrepeater_p.h>
+#include <private/qquicktransition_p.h>
#include <QtQml>
@@ -45,6 +47,7 @@ class tst_Animators: public QObject
private slots:
void testMultiWinAnimator_data();
void testMultiWinAnimator();
+ void testTransitions();
};
void tst_Animators::testMultiWinAnimator_data()
@@ -99,6 +102,28 @@ void tst_Animators::testMultiWinAnimator()
QVERIFY(true);
}
+void tst_Animators::testTransitions()
+{
+ QQuickView view(QUrl::fromLocalFile("data/positionerWithAnimator.qml"));
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+ QVERIFY(view.rootObject());
+
+ QQuickRepeater *repeater = view.rootObject()->property("repeater").value<QQuickRepeater *>();
+ QVERIFY(repeater);
+
+ QQuickItem *child = repeater->itemAt(0);
+ QVERIFY(child);
+ QCOMPARE(child->scale(), qreal(0.0));
+
+ QQuickTransition *transition = view.rootObject()->property("transition").value<QQuickTransition *>();
+ QVERIFY(transition);
+
+ QTRY_VERIFY(transition->running());
+ QTRY_VERIFY(!transition->running());
+ QCOMPARE(child->scale(), qreal(1.0));
+}
+
#include "tst_qquickanimators.moc"
QTEST_MAIN(tst_Animators)
diff --git a/tests/auto/quick/qquickgridview/data/qtbug48870.qml b/tests/auto/quick/qquickgridview/data/qtbug48870.qml
new file mode 100644
index 0000000000..7c0783fbb5
--- /dev/null
+++ b/tests/auto/quick/qquickgridview/data/qtbug48870.qml
@@ -0,0 +1,30 @@
+import QtQuick 2.6
+
+Rectangle {
+ width: 500
+ height: 500
+ color: "blue"
+
+ GridView {
+ id: view
+ objectName: "view"
+ anchors.fill: parent
+ model: testModel
+ cellWidth: 150
+ cellHeight: 150
+ readonly property int columns: Math.floor(width / cellWidth)
+
+ delegate: Rectangle {
+ width: GridView.view.cellWidth
+ height: GridView.view.cellHeight
+ color: (row & 1) != (col & 1) ? "green" : "red"
+ readonly property int row: index / view.columns
+ readonly property int col: index % view.columns
+
+ Text {
+ anchors.centerIn: parent
+ text: "Item " + index
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
index 3699bef56d..4edfb0ed3b 100644
--- a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
+++ b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
@@ -41,6 +41,7 @@
#include <QtQml/qqmlincubator.h>
#include <QtQml/qqmlcontext.h>
#include <QtQuick/private/qquickitem_p.h>
+#include <QtQuick/private/qquickitemview_p_p.h>
#include <QtQuick/private/qquickgridview_p.h>
#include <QtQuick/private/qquicktext_p.h>
#include <QtQml/private/qqmllistmodel_p.h>
@@ -210,6 +211,7 @@ private slots:
void contentHeightWithDelayRemove();
void QTBUG_45640();
+ void QTBUG_48870_fastModelUpdates();
private:
QList<int> toIntList(const QVariantList &list);
@@ -6566,6 +6568,42 @@ void tst_QQuickGridView::QTBUG_45640()
delete window;
}
+void tst_QQuickGridView::QTBUG_48870_fastModelUpdates()
+{
+ StressTestModel model;
+
+ QScopedPointer<QQuickView> window(createView());
+ QQmlContext *ctxt = window->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+
+ window->setSource(testFileUrl("qtbug48870.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ QQuickGridView *view = findItem<QQuickGridView>(window->rootObject(), "view");
+ QTRY_VERIFY(view != 0);
+
+ QQuickItemViewPrivate *priv = QQuickItemViewPrivate::get(view);
+ bool nonUnique;
+ FxViewItem *item = Q_NULLPTR;
+ int expectedIdx;
+ QVERIFY(testVisibleItems(priv, &nonUnique, &item, &expectedIdx));
+
+ for (int i = 0; i < 10; i++) {
+ QTest::qWait(100);
+ QVERIFY2(testVisibleItems(priv, &nonUnique, &item, &expectedIdx),
+ qPrintable(!item ? QString("Unexpected null item")
+ : nonUnique ? QString("Non-unique item at %1 and %2").arg(item->index).arg(expectedIdx)
+ : QString("Found index %1, expected index is %3").arg(item->index).arg(expectedIdx)));
+ if (i % 3 != 0) {
+ if (i & 1)
+ flick(window.data(), QPoint(100, 200), QPoint(100, 0), 100);
+ else
+ flick(window.data(), QPoint(100, 200), QPoint(100, 400), 100);
+ }
+ }
+}
+
QTEST_MAIN(tst_QQuickGridView)
#include "tst_qquickgridview.moc"
diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
index 0153d40b50..19f4010f8c 100644
--- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
+++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
@@ -8202,99 +8202,9 @@ void tst_QQuickListView::QTBUG_48044_currentItemNotVisibleAfterTransition()
QVERIFY(!currentPriv->culled);
}
-static bool testVisibleItems(const QQuickItemViewPrivate *priv, bool *nonUnique, FxViewItem **failItem, int *expectedIdx)
-{
- QHash<QQuickItem*, int> uniqueItems;
-
- int skip = 0;
- for (int i = 0; i < priv->visibleItems.count(); ++i) {
- FxViewItem *item = priv->visibleItems.at(i);
- if (!item) {
- *failItem = Q_NULLPTR;
- return false;
- }
-#if 0
- qDebug() << "\t" << item->index
- << item->item
- << item->position()
- << (!item->item || QQuickItemPrivate::get(item->item)->culled ? "hidden" : "visible");
-#endif
- if (item->index == -1) {
- ++skip;
- } else if (item->index != priv->visibleIndex + i - skip) {
- *nonUnique = false;
- *failItem = item;
- *expectedIdx = priv->visibleIndex + i - skip;
- return false;
- } else if (uniqueItems.contains(item->item)) {
- *nonUnique = true;
- *failItem = item;
- *expectedIdx = uniqueItems.find(item->item).value();
- return false;
- }
-
- uniqueItems.insert(item->item, item->index);
- }
-
- return true;
-}
-
-class QTBUG_48870_Model : public QAbstractListModel
-{
- Q_OBJECT
-
-public:
-
- QTBUG_48870_Model()
- : QAbstractListModel()
- , m_rowCount(20)
- {
- QTimer *t = new QTimer(this);
- t->setInterval(500);
- t->start();
-
- qsrand(qHash(QDateTime::currentDateTime()));
- connect(t, &QTimer::timeout, this, &QTBUG_48870_Model::updateModel);
- }
-
- int rowCount(const QModelIndex &) const
- {
- return m_rowCount;
- }
-
- QVariant data(const QModelIndex &, int) const
- {
- return QVariant();
- }
-
-public Q_SLOTS:
- void updateModel()
- {
- if (m_rowCount > 10) {
- for (int i = 0; i < 10; ++i) {
- int rnum = qrand() % m_rowCount;
- beginRemoveRows(QModelIndex(), rnum, rnum);
- m_rowCount--;
- endRemoveRows();
- }
- }
- if (m_rowCount < 20) {
- for (int i = 0; i < 10; ++i) {
- int rnum = qrand() % m_rowCount;
- beginInsertRows(QModelIndex(), rnum, rnum);
- m_rowCount++;
- endInsertRows();
- }
- }
- }
-
-private:
- int m_rowCount;
-};
-
void tst_QQuickListView::QTBUG_48870_fastModelUpdates()
{
- QTBUG_48870_Model model;
+ StressTestModel model;
QScopedPointer<QQuickView> window(createView());
QQmlContext *ctxt = window->rootContext();
diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
index f53ade9541..c597cf03dd 100644
--- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
@@ -2050,6 +2050,11 @@ void tst_qquickwindow::attachedProperty()
QCOMPARE(text->property("contentItem").value<QQuickItem*>(), innerWindow->contentItem());
QCOMPARE(text->property("windowWidth").toInt(), innerWindow->width());
QCOMPARE(text->property("windowHeight").toInt(), innerWindow->height());
+
+ text->setParentItem(0);
+ QVERIFY(!text->property("contentItem").value<QQuickItem*>());
+ QCOMPARE(text->property("windowWidth").toInt(), 0);
+ QCOMPARE(text->property("windowHeight").toInt(), 0);
}
class RenderJob : public QRunnable
diff --git a/tests/auto/quick/shared/viewtestutil.cpp b/tests/auto/quick/shared/viewtestutil.cpp
index 1330cbccc9..5a1006c8e0 100644
--- a/tests/auto/quick/shared/viewtestutil.cpp
+++ b/tests/auto/quick/shared/viewtestutil.cpp
@@ -40,6 +40,7 @@
#include <QtTest/QTest>
#include <private/qquickwindow_p.h>
+#include <private/qquickitemview_p_p.h>
QQuickView *QQuickViewTestUtil::createView()
@@ -348,6 +349,85 @@ QList<QPair<QString,QString> > QQuickViewTestUtil::ListRange::getModelDataValues
return data;
}
+QQuickViewTestUtil::StressTestModel::StressTestModel()
+ : QAbstractListModel()
+ , m_rowCount(20)
+{
+ QTimer *t = new QTimer(this);
+ t->setInterval(500);
+ t->start();
+
+ qsrand(qHash(QDateTime::currentDateTime()));
+ connect(t, &QTimer::timeout, this, &StressTestModel::updateModel);
+}
+
+int QQuickViewTestUtil::StressTestModel::rowCount(const QModelIndex &) const
+{
+ return m_rowCount;
+}
+
+QVariant QQuickViewTestUtil::StressTestModel::data(const QModelIndex &, int) const
+{
+ return QVariant();
+}
+
+void QQuickViewTestUtil::StressTestModel::updateModel()
+{
+ if (m_rowCount > 10) {
+ for (int i = 0; i < 10; ++i) {
+ int rnum = qrand() % m_rowCount;
+ beginRemoveRows(QModelIndex(), rnum, rnum);
+ m_rowCount--;
+ endRemoveRows();
+ }
+ }
+ if (m_rowCount < 20) {
+ for (int i = 0; i < 10; ++i) {
+ int rnum = qrand() % m_rowCount;
+ beginInsertRows(QModelIndex(), rnum, rnum);
+ m_rowCount++;
+ endInsertRows();
+ }
+ }
+}
+
+bool QQuickViewTestUtil::testVisibleItems(const QQuickItemViewPrivate *priv, bool *nonUnique, FxViewItem **failItem, int *expectedIdx)
+{
+ QHash<QQuickItem*, int> uniqueItems;
+
+ int skip = 0;
+ for (int i = 0; i < priv->visibleItems.count(); ++i) {
+ FxViewItem *item = priv->visibleItems.at(i);
+ if (!item) {
+ *failItem = Q_NULLPTR;
+ return false;
+ }
+#if 0
+ qDebug() << "\t" << item->index
+ << item->item
+ << item->position()
+ << (!item->item || QQuickItemPrivate::get(item->item)->culled ? "hidden" : "visible");
+#endif
+ if (item->index == -1) {
+ ++skip;
+ } else if (item->index != priv->visibleIndex + i - skip) {
+ *nonUnique = false;
+ *failItem = item;
+ *expectedIdx = priv->visibleIndex + i - skip;
+ return false;
+ } else if (uniqueItems.contains(item->item)) {
+ *nonUnique = true;
+ *failItem = item;
+ *expectedIdx = uniqueItems.find(item->item).value();
+ return false;
+ }
+
+ uniqueItems.insert(item->item, item->index);
+ }
+
+ return true;
+}
+
namespace QQuickTouchUtils {
/* QQuickWindow does event compression and only delivers events just
diff --git a/tests/auto/quick/shared/viewtestutil.h b/tests/auto/quick/shared/viewtestutil.h
index 1643eca979..155d7967ba 100644
--- a/tests/auto/quick/shared/viewtestutil.h
+++ b/tests/auto/quick/shared/viewtestutil.h
@@ -39,6 +39,8 @@
#include <QtCore/QAbstractListModel>
QT_FORWARD_DECLARE_CLASS(QQuickView)
+QT_FORWARD_DECLARE_CLASS(QQuickItemViewPrivate)
+QT_FORWARD_DECLARE_CLASS(FxViewItem)
namespace QQuickViewTestUtil
{
@@ -158,6 +160,26 @@ namespace QQuickViewTestUtil
for (; f != replaced.end(); ++f, ++t)
*t = *f;
}
+
+ class StressTestModel : public QAbstractListModel
+ {
+ Q_OBJECT
+
+ public:
+
+ StressTestModel();
+
+ int rowCount(const QModelIndex &) const;
+ QVariant data(const QModelIndex &, int) const;
+
+ public Q_SLOTS:
+ void updateModel();
+
+ private:
+ int m_rowCount;
+ };
+
+ bool testVisibleItems(const QQuickItemViewPrivate *priv, bool *nonUnique, FxViewItem **failItem, int *expectedIdx);
}
namespace QQuickTouchUtils {
diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_multiline_selected_linebreaks_and_linewraps.qml b/tests/manual/scenegraph_lancelot/data/text/textedit_multiline_selected_linebreaks_and_linewraps.qml
new file mode 100644
index 0000000000..a1004d0374
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/text/textedit_multiline_selected_linebreaks_and_linewraps.qml
@@ -0,0 +1,22 @@
+import QtQuick 2.0
+
+Item {
+ width: 200
+ height: 480
+
+ TextEdit {
+ id: textEdit
+ anchors.centerIn: parent
+ font.family: "Arial"
+ font.pixelSize: 64
+ width: 200
+ textFormat: TextEdit.RichText
+ wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
+ text: "ABC ABC<br>ABC"
+
+ Component.onCompleted: {
+ textEdit.selectAll()
+ }
+ }
+
+}
diff --git a/tools/qmlimportscanner/main.cpp b/tools/qmlimportscanner/main.cpp
index 189459f9af..ce91062edc 100644
--- a/tools/qmlimportscanner/main.cpp
+++ b/tools/qmlimportscanner/main.cpp
@@ -90,7 +90,7 @@ QVariantList findImportsInAst(QQmlJS::AST::UiHeaderItemList *headerItemList, con
if (!importNode->fileName.isEmpty()) {
QString name = importNode->fileName.toString();
import[QStringLiteral("name")] = name;
- if (name.endsWith(QStringLiteral(".js"))) {
+ if (name.endsWith(QLatin1String(".js"))) {
import[QStringLiteral("type")] = QStringLiteral("javascript");
} else {
import[QStringLiteral("type")] = QStringLiteral("directory");
@@ -193,7 +193,7 @@ QVariantList findPathsForModuleImports(const QVariantList &imports)
for (int i = 0; i < importsCopy.length(); ++i) {
QVariantMap import = qvariant_cast<QVariantMap>(importsCopy[i]);
- if (import[QStringLiteral("type")] == QStringLiteral("module")) {
+ if (import[QStringLiteral("type")] == QLatin1String("module")) {
QString path = resolveImportPath(import.value(QStringLiteral("name")).toString(), import.value(QStringLiteral("version")).toString());
if (!path.isEmpty())
import[QStringLiteral("path")] = path;
@@ -324,9 +324,9 @@ QVariantList findQmlImportsInFile(const QString &filePath)
QFile f;
if (f.open(stdin, QIODevice::ReadOnly))
imports = findQmlImportsInQmlCode(QLatin1String("<stdin>"), QString::fromUtf8(f.readAll()));
- } else if (filePath.endsWith(QStringLiteral(".qml"))) {
+ } else if (filePath.endsWith(QLatin1String(".qml"))) {
imports = findQmlImportsInQmlFile(filePath);
- } else if (filePath.endsWith(QStringLiteral(".js"))) {
+ } else if (filePath.endsWith(QLatin1String(".js"))) {
imports = findQmlImportsInJavascriptFile(filePath);
}
@@ -387,10 +387,10 @@ QVariantList findQmlImportsInDirectory(const QString &qmlDir)
continue;
// skip obvious build output directories
- if (path.contains(QStringLiteral("Debug-iphoneos")) || path.contains(QStringLiteral("Release-iphoneos")) ||
- path.contains(QStringLiteral("Debug-iphonesimulator")) || path.contains(QStringLiteral("Release-iphonesimulator"))
+ if (path.contains(QLatin1String("Debug-iphoneos")) || path.contains(QLatin1String("Release-iphoneos")) ||
+ path.contains(QLatin1String("Debug-iphonesimulator")) || path.contains(QLatin1String("Release-iphonesimulator"))
#ifdef Q_OS_WIN
- || path.contains(QStringLiteral("/release/")) || path.contains(QStringLiteral("/debug/"))
+ || path.contains(QLatin1String("/release/")) || path.contains(QLatin1String("/debug/"))
#endif
){
continue;
@@ -409,7 +409,7 @@ QSet<QString> importModulePaths(QVariantList imports) {
QVariantMap import = qvariant_cast<QVariantMap>(importVariant);
QString path = import.value(QStringLiteral("path")).toString();
QString type = import.value(QStringLiteral("type")).toString();
- if (type == QStringLiteral("module") && !path.isEmpty())
+ if (type == QLatin1String("module") && !path.isEmpty())
ret.insert(QDir(path).canonicalPath());
}
return ret;
diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp
index fe92f80bad..393abc8883 100644
--- a/tools/qmlplugindump/main.cpp
+++ b/tools/qmlplugindump/main.cpp
@@ -56,9 +56,11 @@
#include <QtCore/private/qobject_p.h>
#include <QtCore/private/qmetaobject_p.h>
+#include <QRegularExpression>
#include <iostream>
#include <algorithm>
+#include "qmltypereader.h"
#include "qmlstreamwriter.h"
#ifdef QT_SIMULATOR
@@ -733,7 +735,7 @@ void sigSegvHandler(int) {
void printUsage(const QString &appName)
{
std::cerr << qPrintable(QString(
- "Usage: %1 [-v] [-noinstantiate] [-defaultplatform] [-[non]relocatable] [-dependencies <dependencies.json>] module.uri version [module/import/path]\n"
+ "Usage: %1 [-v] [-noinstantiate] [-defaultplatform] [-[non]relocatable] [-dependencies <dependencies.json>] [-merge <file-to-merge.qmltypes>] module.uri version [module/import/path]\n"
" %1 [-v] [-noinstantiate] -path path/to/qmldir/directory [version]\n"
" %1 [-v] -builtins\n"
"Example: %1 Qt.labs.folderlistmodel 2.0 /home/user/dev/qt-install/imports").arg(
@@ -987,6 +989,7 @@ int main(int argc, char *argv[])
QString pluginImportVersion;
bool relocatable = true;
QString dependenciesFile;
+ QString mergeFile;
enum Action { Uri, Path, Builtins };
Action action = Uri;
{
@@ -1005,6 +1008,13 @@ int main(int argc, char *argv[])
return EXIT_INVALIDARGUMENTS;
}
dependenciesFile = args.at(iArg);
+ } else if (arg == QLatin1String("--merge")
+ || arg == QLatin1String("-merge")) {
+ if (++iArg == args.size()) {
+ std::cerr << "missing merge file" << std::endl;
+ return EXIT_INVALIDARGUMENTS;
+ }
+ mergeFile = args.at(iArg);
} else if (arg == QLatin1String("--notrelocatable")
|| arg == QLatin1String("-notrelocatable")
|| arg == QLatin1String("--nonrelocatable")
@@ -1066,6 +1076,26 @@ int main(int argc, char *argv[])
QDir::setCurrent(pluginImportPath);
engine.addImportPath(pluginImportPath);
}
+
+ // Merge file.
+ QStringList mergeDependencies;
+ QString mergeComponents;
+ if (!mergeFile.isEmpty()) {
+ QStringList merge = readQmlTypes(mergeFile);
+ if (!merge.isEmpty()) {
+ QRegularExpression re("(\\w+\\.*\\w*\\s*\\d+\\.\\d+)");
+ QRegularExpressionMatchIterator i = re.globalMatch(merge[1]);
+ while (i.hasNext()) {
+ QRegularExpressionMatch m = i.next();
+ QString d = m.captured(1);
+ mergeDependencies << m.captured(1);
+ }
+ mergeComponents = merge [2];
+ }
+ }
+
+ // Dependencies.
+
bool calculateDependencies = !pluginImportUri.isEmpty() && !pluginImportVersion.isEmpty();
QStringList dependencies;
if (!dependenciesFile.isEmpty())
@@ -1215,6 +1245,13 @@ int main(int argc, char *argv[])
"// '%1 %2'\n"
"\n").arg(QFileInfo(args.at(0)).baseName(), args.mid(1).join(QLatin1Char(' '))));
qml.writeStartObject("Module");
+
+ // Insert merge dependencies.
+ if (!mergeDependencies.isEmpty()) {
+ dependencies << mergeDependencies;
+ }
+ compactDependencies(&dependencies);
+
QStringList quotedDependencies;
foreach (const QString &dep, dependencies)
quotedDependencies << enquote(dep);
@@ -1241,6 +1278,9 @@ int main(int argc, char *argv[])
if (pluginImportUri.isEmpty())
dumper.writeEasingCurve();
+ // Insert merge file.
+ qml.write(mergeComponents);
+
qml.writeEndObject();
qml.writeEndDocument();
diff --git a/tools/qmlplugindump/qmlplugindump.pro b/tools/qmlplugindump/qmlplugindump.pro
index 6fdcd349d1..e45a7fad83 100644
--- a/tools/qmlplugindump/qmlplugindump.pro
+++ b/tools/qmlplugindump/qmlplugindump.pro
@@ -6,10 +6,12 @@ QTPLUGIN.platforms = qminimal
SOURCES += \
main.cpp \
- qmlstreamwriter.cpp
+ qmlstreamwriter.cpp \
+ qmltypereader.cpp
HEADERS += \
- qmlstreamwriter.h
+ qmlstreamwriter.h \
+ qmltypereader.h
macx {
# Prevent qmlplugindump from popping up in the dock when launched.
diff --git a/tools/qmlplugindump/qmltypereader.cpp b/tools/qmlplugindump/qmltypereader.cpp
new file mode 100644
index 0000000000..67ba415388
--- /dev/null
+++ b/tools/qmlplugindump/qmltypereader.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmltypereader.h"
+
+#include <QFileInfo>
+#include <QFile>
+#include <QRegularExpression>
+
+#include <iostream>
+
+QStringList readQmlTypes(const QString &filename) {
+ QRegularExpression re("import QtQuick.tooling 1.2.*Module {\\s*dependencies:\\[([^\\]]*)\\](.*)}",
+ QRegularExpression::DotMatchesEverythingOption);
+ if (!QFileInfo(filename).exists()) {
+ std::cerr << "Non existing file: " << filename.toStdString() << std::endl;
+ return QStringList();
+ }
+ QFile f(filename);
+ if (!f.open(QFileDevice::ReadOnly)) {
+ std::cerr << "Error in opening file " << filename.toStdString() << " : "
+ << f.errorString().toStdString() << std::endl;
+ return QStringList();
+ }
+ QByteArray fileData = f.readAll();
+ QString data(fileData);
+ QRegularExpressionMatch m = re.match(data);
+ if (m.lastCapturedIndex() != 2) {
+ std::cerr << "Malformed file: " << filename.toStdString() << std::endl;
+ return QStringList();
+ }
+ return m.capturedTexts();
+}
diff --git a/tools/qmlplugindump/qmltypereader.h b/tools/qmlplugindump/qmltypereader.h
new file mode 100644
index 0000000000..b995566e0b
--- /dev/null
+++ b/tools/qmlplugindump/qmltypereader.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLTYPEREADER_H
+#define QMLTYPEREADER_H
+
+#include <QString>
+#include <QStringList>
+
+QStringList readQmlTypes(const QString &filename);
+
+#endif // QMLTYPEREADER_H