aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@theqtcompany.com>2016-02-12 10:53:43 +0100
committerLiang Qi <liang.qi@theqtcompany.com>2016-02-12 10:53:43 +0100
commit20a51e87fd15b8a6c1503b905399f7befe31114b (patch)
tree5a8667150568ed798d63eb165372c198549498c2
parent6c152bf27f94f01b2942b02e370df4fa01e0d40f (diff)
parent084dbb06d7b00c4a67edb6ce58956150036c35f2 (diff)
Merge remote-tracking branch 'origin/5.6' into dev
Conflicts: .qmake.conf Change-Id: I356ec83cf687bd2833f9a7c5e820d56b1efa8979
-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/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--tests/auto/quick/qquickanimators/data/positionerWithAnimator.qml63
-rw-r--r--tests/auto/quick/qquickanimators/tst_qquickanimators.cpp25
-rw-r--r--tests/auto/quick/qquickwindow/tst_qquickwindow.cpp5
-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
23 files changed, 355 insertions, 37 deletions
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 7e1a31f206..4d9f834492 100644
--- a/src/particles/qquickparticleemitter.cpp
+++ b/src/particles/qquickparticleemitter.cpp
@@ -343,7 +343,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 b8bd0f7f1d..fbd2d13e40 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -378,6 +378,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 adee4330d3..9ba93a1241 100644
--- a/src/qmltest/quicktest.cpp
+++ b/src/qmltest/quicktest.cpp
@@ -296,7 +296,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 12bd95101f..f3513f447a 100644
--- a/src/quick/items/context2d/qquickcontext2dtexture.cpp
+++ b/src/quick/items/context2d/qquickcontext2dtexture.cpp
@@ -605,6 +605,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 3663b379bb..3bfd1e8b9a 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -65,6 +65,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);
}
@@ -244,6 +246,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);
@@ -1202,6 +1206,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))
@@ -1391,9 +1397,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();
@@ -1415,7 +1427,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) {
@@ -1435,7 +1446,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) {
@@ -1548,6 +1558,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);
}
}
@@ -2475,6 +2491,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 a7995c5025..6cf78dcf63 100644
--- a/src/quick/items/qquickflickable_p.h
+++ b/src/quick/items/qquickflickable_p.h
@@ -259,6 +259,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 83e38af8a9..3c59b19ec2 100644
--- a/src/quick/items/qquickflickable_p_p.h
+++ b/src/quick/items/qquickflickable_p_p.h
@@ -218,6 +218,7 @@ public:
bool calcVelocity : 1;
bool pixelAligned : 1;
QElapsedTimer timer;
+ QBasicTimer movementEndingTimer;
qint64 lastPosTime;
qint64 lastPressTime;
QPointF lastPos;
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 5be1c86fb4..8715fa2772 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -7256,7 +7256,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 7009a8e328..188b347a20 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -2484,8 +2484,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 e1cd3c82f2..992bbae382 100644
--- a/src/quick/items/qquickwindowattached.cpp
+++ b/src/quick/items/qquickwindowattached.cpp
@@ -95,21 +95,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 f0d4caf7ab..abae6321b0 100644
--- a/src/quick/util/qquickanimator.cpp
+++ b/src/quick/util/qquickanimator.cpp
@@ -217,7 +217,8 @@ qreal QQuickAnimator::from() const
void QQuickAnimatorPrivate::apply(QQuickAnimatorJob *job,
const QString &propertyName,
QQuickStateActions &actions,
- QQmlProperties &modified)
+ QQmlProperties &modified,
+ QObject *defaultTarget)
{
if (actions.size()) {
@@ -249,14 +250,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);
@@ -266,7 +273,7 @@ void QQuickAnimatorPrivate::apply(QQuickAnimatorJob *job,
QAbstractAnimationJob *QQuickAnimator::transition(QQuickStateActions &actions,
QQmlProperties &modified,
TransitionDirection direction,
- QObject *)
+ QObject *defaultTarget)
{
Q_D(QQuickAnimator);
@@ -283,7 +290,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 7a61462762..b176119c70 100644
--- a/src/quick/util/qquickanimator_p_p.h
+++ b/src/quick/util/qquickanimator_p_p.h
@@ -82,7 +82,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/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 6943bf5045..29142dee12 100644
--- a/tests/auto/quick/qquickanimators/tst_qquickanimators.cpp
+++ b/tests/auto/quick/qquickanimators/tst_qquickanimators.cpp
@@ -30,6 +30,8 @@
#include <QtQuick>
#include <private/qquickanimator_p.h>
+#include <private/qquickrepeater_p.h>
+#include <private/qquicktransition_p.h>
#include <QtQml>
@@ -40,6 +42,7 @@ class tst_Animators: public QObject
private slots:
void testMultiWinAnimator_data();
void testMultiWinAnimator();
+ void testTransitions();
};
void tst_Animators::testMultiWinAnimator_data()
@@ -94,6 +97,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/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
index 5d1897ab2d..8aeb449a85 100644
--- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
@@ -2045,6 +2045,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/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 af6b272fc6..dcb9709bb8 100644
--- a/tools/qmlimportscanner/main.cpp
+++ b/tools/qmlimportscanner/main.cpp
@@ -85,7 +85,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");
@@ -188,7 +188,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;
@@ -319,9 +319,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);
}
@@ -382,10 +382,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;
@@ -404,7 +404,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 776e19fdf4..7870e3a9df 100644
--- a/tools/qmlplugindump/main.cpp
+++ b/tools/qmlplugindump/main.cpp
@@ -51,9 +51,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
@@ -728,7 +730,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(
@@ -982,6 +984,7 @@ int main(int argc, char *argv[])
QString pluginImportVersion;
bool relocatable = true;
QString dependenciesFile;
+ QString mergeFile;
enum Action { Uri, Path, Builtins };
Action action = Uri;
{
@@ -1000,6 +1003,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")
@@ -1061,6 +1071,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())
@@ -1210,6 +1240,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);
@@ -1236,6 +1273,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