Merge remote-tracking branch 'origin/5.5' into 5.6

Conflicts:
	tests/auto/qml/qml.pro
	tools/qmlprofiler/qmlprofilerclient.cpp

Change-Id: Id47f15a5ab38f8ec79f0a26c92805acba62caac4
This commit is contained in:
Liang Qi 2015-10-26 13:42:08 +01:00
commit 3832b1e05b
22 changed files with 290 additions and 69 deletions

View File

@ -374,6 +374,7 @@ void QQuickAnimatedSprite::stop()
return;
m_pauseOffset = 0;
emit runningChanged(false);
update();
}
/*!
@ -391,6 +392,7 @@ void QQuickAnimatedSprite::advance(int frames)
m_curFrame += m_spriteEngine->maxFrames();
m_curFrame = m_curFrame % m_spriteEngine->maxFrames();
emit currentFrameChanged(m_curFrame);
update();
}
/*!
@ -408,6 +410,7 @@ void QQuickAnimatedSprite::pause()
m_pauseOffset = m_timestamp.elapsed();
m_paused = true;
emit pausedChanged(true);
update();
}
/*!
@ -425,6 +428,7 @@ void QQuickAnimatedSprite::resume()
m_pauseOffset = m_pauseOffset - m_timestamp.elapsed();
m_paused = false;
emit pausedChanged(false);
update();
}
void QQuickAnimatedSprite::createEngine()
@ -436,6 +440,7 @@ void QQuickAnimatedSprite::createEngine()
m_spriteEngine = new QQuickSpriteEngine(QList<QQuickSprite*>(spriteList), this);
m_spriteEngine->startAssemblingImage();
reset();
update();
}
static QSGGeometry::Attribute AnimatedSprite_Attributes[] = {
@ -555,9 +560,12 @@ QSGNode *QQuickAnimatedSprite::updatePaintNode(QSGNode *, UpdatePaintNodeData *)
prepareNextFrame();
if (m_running) {
update();
if (m_node)
if (!m_paused)
update();
if (m_node) {
m_node->markDirty(QSGNode::DirtyMaterial);
}
}
return m_node;
@ -614,12 +622,16 @@ void QQuickAnimatedSprite::prepareNextFrame()
frameAt = 0;
m_running = false;
emit runningChanged(false);
update();
}
} else {
frameAt = m_curFrame;
}
if (m_curFrame != lastFrame && isCurrentFrameChangedConnected())
emit currentFrameChanged(m_curFrame);
if (m_curFrame != lastFrame) {
if (isCurrentFrameChangedConnected())
emit currentFrameChanged(m_curFrame);
update();
}
qreal frameCount = m_spriteEngine->spriteFrames();
bool reverse = m_spriteEngine->sprite()->reverse();

View File

@ -344,6 +344,7 @@ public Q_SLOTS:
if (m_curFrame != arg) {
m_curFrame = arg;
Q_EMIT currentFrameChanged(arg); //TODO-C Only emitted on manual advance!
update();
}
}

View File

@ -322,7 +322,7 @@ Item {
/*!
\qmlproperty point QtQuick::WheelEvent::pixelDelta
This property holds the delta in screen pixels and is available in plataforms that
This property holds the delta in screen pixels and is available in platforms that
have high-resolution trackpads, such as OS X.
The x and y cordinate of this property holds the delta in horizontal and
vertical orientation. The value should be used directly to scroll content on screen.

View File

@ -724,6 +724,7 @@ void QQuickKeyNavigationAttached::setFocusNavigation(QQuickItem *currentItem, co
{
QQuickItem *initialItem = currentItem;
bool isNextItem = false;
QVector<QQuickItem *> visitedItems;
do {
isNextItem = false;
if (currentItem->isVisible() && currentItem->isEnabled()) {
@ -734,13 +735,14 @@ void QQuickKeyNavigationAttached::setFocusNavigation(QQuickItem *currentItem, co
if (attached) {
QQuickItem *tempItem = qvariant_cast<QQuickItem*>(attached->property(dir));
if (tempItem) {
visitedItems.append(currentItem);
currentItem = tempItem;
isNextItem = true;
}
}
}
}
while (currentItem != initialItem && isNextItem);
while (currentItem != initialItem && isNextItem && !visitedItems.contains(currentItem));
}
struct SigMap {
@ -5918,7 +5920,7 @@ void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickIt
In Qt Quick 2.0, this property has minimal impact on performance.
By default is true.
By default, this property is set to \c true.
*/
/*!
\property QQuickItem::smooth
@ -5930,7 +5932,7 @@ void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickIt
In Qt Quick 2.0, this property has minimal impact on performance.
By default is true.
By default, this property is set to \c true.
*/
bool QQuickItem::smooth() const
{
@ -5952,10 +5954,10 @@ void QQuickItem::setSmooth(bool smooth)
/*!
\qmlproperty bool QtQuick::Item::activeFocusOnTab
This property holds whether the item wants to be in tab focus
chain. By default this is set to false.
This property holds whether the item wants to be in the tab focus
chain. By default, this is set to \c false.
The tab focus chain traverses elements by visiting first the
The tab focus chain traverses elements by first visiting the
parent, and then its children in the order they occur in the
children property. Pressing the tab key on an item in the tab
focus chain will move keyboard focus to the next item in the
@ -5964,14 +5966,14 @@ void QQuickItem::setSmooth(bool smooth)
To set up a manual tab focus chain, see \l KeyNavigation. Tab
key events used by Keys or KeyNavigation have precedence over
focus chain behavior, ignore the events in other key handlers
focus chain behavior; ignore the events in other key handlers
to allow it to propagate.
*/
/*!
\property QQuickItem::activeFocusOnTab
This property holds whether the item wants to be in tab focus
chain. By default this is set to false.
This property holds whether the item wants to be in the tab focus
chain. By default, this is set to \c false.
*/
bool QQuickItem::activeFocusOnTab() const
{

View File

@ -350,11 +350,22 @@ uint qHash(const QQuickShaderEffectMaterialKey &key)
return hash;
}
typedef QHash<QQuickShaderEffectMaterialKey, QWeakPointer<QSGMaterialType> > MaterialHash;
Q_GLOBAL_STATIC(MaterialHash, materialHash)
Q_GLOBAL_STATIC(QMutex, materialHashMutex)
class QQuickShaderEffectMaterialCache : public QObject
{
Q_OBJECT
public:
static QQuickShaderEffectMaterialCache *get(bool create = true) {
QOpenGLContext *ctx = QOpenGLContext::currentContext();
QQuickShaderEffectMaterialCache *me = ctx->findChild<QQuickShaderEffectMaterialCache *>(QStringLiteral("__qt_ShaderEffectCache"), Qt::FindDirectChildrenOnly);
if (!me && create) {
me = new QQuickShaderEffectMaterialCache();
me->setObjectName(QStringLiteral("__qt_ShaderEffectCache"));
me->setParent(ctx);
}
return me;
}
QHash<QQuickShaderEffectMaterialKey, QSGMaterialType *> cache;
};
QQuickShaderEffectMaterial::QQuickShaderEffectMaterial(QQuickShaderEffectNode *node)
: cullMode(NoCulling)
@ -367,7 +378,7 @@ QQuickShaderEffectMaterial::QQuickShaderEffectMaterial(QQuickShaderEffectNode *n
QSGMaterialType *QQuickShaderEffectMaterial::type() const
{
return m_type.data();
return m_type;
}
QSGMaterialShader *QQuickShaderEffectMaterial::createShader() const
@ -425,30 +436,23 @@ int QQuickShaderEffectMaterial::compare(const QSGMaterial *o) const
void QQuickShaderEffectMaterial::setProgramSource(const QQuickShaderEffectMaterialKey &source)
{
QMutexLocker locker(materialHashMutex);
Q_UNUSED(locker);
m_source = source;
m_emittedLogChanged = false;
QWeakPointer<QSGMaterialType> weakPtr = materialHash->value(m_source);
m_type = weakPtr.toStrongRef();
if (m_type.isNull()) {
m_type = QSharedPointer<QSGMaterialType>(new QSGMaterialType);
materialHash->insert(m_source, m_type.toWeakRef());
QQuickShaderEffectMaterialCache *cache = QQuickShaderEffectMaterialCache::get();
m_type = cache->cache.value(m_source);
if (!m_type) {
m_type = new QSGMaterialType();
cache->cache.insert(source, m_type);
}
}
void QQuickShaderEffectMaterial::cleanupMaterialCache()
{
QMutexLocker locker(materialHashMutex);
Q_UNUSED(locker);
for (MaterialHash::iterator it = materialHash->begin(); it != materialHash->end(); ) {
if (!it.value().toStrongRef())
it = materialHash->erase(it);
else
++it;
QQuickShaderEffectMaterialCache *cache = QQuickShaderEffectMaterialCache::get(false);
if (cache) {
qDeleteAll(cache->cache.values());
delete cache;
}
}
@ -501,4 +505,6 @@ void QQuickShaderEffectNode::preprocess()
static_cast<QQuickShaderEffectMaterial *>(material())->updateTextures();
}
#include "qquickshadereffectnode.moc"
QT_END_NAMESPACE

View File

@ -73,7 +73,6 @@ struct QQuickShaderEffectMaterialKey {
uint qHash(const QQuickShaderEffectMaterialKey &key);
class QQuickCustomMaterialShader;
class QQuickShaderEffectNode;
class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectMaterial : public QSGMaterial
@ -117,13 +116,12 @@ public:
protected:
friend class QQuickCustomMaterialShader;
// The type pointer needs to be unique. It is not safe to let the type object be part of the
// QQuickShaderEffectMaterial, since it can be deleted and a new one constructed on top of the old
// one. The new QQuickShaderEffectMaterial would then get the same type pointer as the old one, and
// CustomMaterialShaders based on the old one would incorrectly be used together with the new
// one. To guarantee that the type pointer is unique, the type object must live as long as
// there are any CustomMaterialShaders of that type.
QSharedPointer<QSGMaterialType> m_type;
// Each material needs a unique type to ensure that the renderer has a one
// and exactly one GL program for every unique set of shader sources.
// setProgramSource() stores the sources in a cache along with the right
// type. The type is cleaned up in cleanupMaterialCache() which is called
// when the GL context is shut down.
QSGMaterialType *m_type;
QQuickShaderEffectMaterialKey m_source;
QQuickShaderEffectNode *m_node;

View File

@ -129,14 +129,15 @@ QQuickTextDocumentWithImageResources::~QQuickTextDocumentWithImageResources()
QVariant QQuickTextDocumentWithImageResources::loadResource(int type, const QUrl &name)
{
QQmlContext *context = qmlContext(parent());
if (type == QTextDocument::ImageResource) {
QQuickPixmap *p = loadPixmap(context, name);
return p->image();
QVariant resource = QTextDocument::loadResource(type, name);
if (resource.isNull() && type == QTextDocument::ImageResource) {
QQmlContext *context = qmlContext(parent());
QUrl url = baseUrl().resolved(name);
QQuickPixmap *p = loadPixmap(context, url);
resource = p->image();
}
return QTextDocument::loadResource(type, name);
return resource;
}
void QQuickTextDocumentWithImageResources::requestFinished()
@ -161,30 +162,28 @@ QSizeF QQuickTextDocumentWithImageResources::intrinsicSize(
QSizeF size(width, height);
if (!hasWidth || !hasHeight) {
QQmlContext *context = qmlContext(parent());
QUrl url = baseUrl().resolved(QUrl(imageFormat.name()));
QQuickPixmap *p = loadPixmap(context, url);
if (!p->isReady()) {
QVariant res = resource(QTextDocument::ImageResource, QUrl(imageFormat.name()));
QImage image = res.value<QImage>();
if (image.isNull()) {
if (!hasWidth)
size.setWidth(16);
if (!hasHeight)
size.setHeight(16);
return size;
}
QSize implicitSize = p->implicitSize();
QSize imgSize = image.size();
if (!hasWidth) {
if (!hasHeight)
size.setWidth(implicitSize.width());
size.setWidth(imgSize.width());
else
size.setWidth(qRound(height * (implicitSize.width() / (qreal) implicitSize.height())));
size.setWidth(qRound(height * (imgSize.width() / (qreal) imgSize.height())));
}
if (!hasHeight) {
if (!hasWidth)
size.setHeight(implicitSize.height());
size.setHeight(imgSize.height());
else
size.setHeight(qRound(width * (implicitSize.height() / (qreal) implicitSize.width())));
size.setHeight(qRound(width * (imgSize.height() / (qreal) imgSize.width())));
}
}
return size;
@ -199,11 +198,8 @@ void QQuickTextDocumentWithImageResources::drawObject(
QImage QQuickTextDocumentWithImageResources::image(const QTextImageFormat &format)
{
QQmlContext *context = qmlContext(parent());
QUrl url = baseUrl().resolved(QUrl(format.name()));
QQuickPixmap *p = loadPixmap(context, url);
return p->image();
QVariant res = resource(QTextDocument::ImageResource, QUrl(format.name()));
return res.value<QImage>();
}
void QQuickTextDocumentWithImageResources::reset()

View File

@ -197,7 +197,7 @@ public:
};
class QQuickPixmap;
class QQuickTextDocumentWithImageResources : public QTextDocument, public QTextObjectInterface
class Q_AUTOTEST_EXPORT QQuickTextDocumentWithImageResources : public QTextDocument, public QTextObjectInterface
{
Q_OBJECT
Q_INTERFACES(QTextObjectInterface)

View File

@ -890,11 +890,11 @@ void Renderer::map(Buffer *buffer, int byteSize, bool isIndexBuf)
if (byteSize > pool.size())
pool.resize(byteSize);
buffer->data = pool.data();
} else {
} else if (buffer->size != byteSize) {
free(buffer->data);
buffer->data = (char *) malloc(byteSize);
}
buffer->size = byteSize;
}
void Renderer::unmap(Buffer *buffer, bool isIndexBuf)

View File

@ -72,7 +72,10 @@ qtHaveModule(widgets) {
SUBDIRS += $$PUBLICTESTS
SUBDIRS += $$METATYPETESTS
!winrt:!contains(QT_CONFIG, no-qml-debug): SUBDIRS += debugger # no QProcess on winrt
!winrt { # no QProcess on winrt
!contains(QT_CONFIG, no-qml-debug): SUBDIRS += debugger
SUBDIRS += qmllint
}
contains(QT_CONFIG, private_tests) {
SUBDIRS += $$PRIVATETESTS

View File

@ -0,0 +1,6 @@
.pragma library
.import QtQuick 2.4 as JSQtQuick
function foo(url)
{
}

View File

@ -0,0 +1,4 @@
import QtQuick 2.2
Item {
}

View File

@ -0,0 +1,5 @@
function foo()
{
var hello
returm 0 // Typo
}

View File

@ -0,0 +1,5 @@
import QtQuick 1.0
Item {
id root # // Missing :
}

View File

@ -0,0 +1,5 @@
import "QTBUG-45916.js" as JSTest
Item {
id: root
}

View File

@ -0,0 +1,90 @@
/****************************************************************************
**
** Copyright (C) 2015 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Sergio Martins <sergio.martins@kdab.com>
** Contact: http://www.qt.io/licensing/
**
** This file is part of the plugins 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 <QtTest/QtTest>
#include <QProcess>
#include <QString>
class TestQmllint: public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();
void test();
void test_data();
private:
QString m_qmllintPath;
};
void TestQmllint::initTestCase()
{
m_qmllintPath = QLibraryInfo::location(QLibraryInfo::BinariesPath) + QLatin1String("/qmllint");
#ifdef Q_OS_WIN
m_qmllintPath += QLatin1String(".exe");
#endif
if (!QFileInfo(m_qmllintPath).exists()) {
QString message = QStringLiteral("qmllint executable not found (looked for %0)").arg(m_qmllintPath);
QFAIL(qPrintable(message));
}
}
void TestQmllint::test_data()
{
QTest::addColumn<QString>("filename");
QTest::addColumn<bool>("isValid");
// Valid files:
QTest::newRow("Simple_QML") << QStringLiteral("Simple.qml") << true;
QTest::newRow("QML_importing_JS") << QStringLiteral("importing_js.qml") << true;
QTest::newRow("QTBUG-45916_JS_with_pragma_and_import") << QStringLiteral("QTBUG-45916.js") << true;
// Invalid files:
QTest::newRow("Invalid_syntax_QML") << QStringLiteral("failure1.qml") << false;
QTest::newRow("Invalid_syntax_JS") << QStringLiteral("failure1.js") << false;
}
void TestQmllint::test()
{
QFETCH(QString, filename);
QFETCH(bool, isValid);
filename = QStringLiteral("data/") + filename;
QStringList args;
args << QStringLiteral("--silent") << filename;
bool success = QProcess::execute(m_qmllintPath, args) == 0;
QCOMPARE(success, isValid);
}
QTEST_MAIN(TestQmllint)
#include "main.moc"

View File

@ -0,0 +1,6 @@
TEMPLATE = app
TARGET = testqmllint
INCLUDEPATH += .
SOURCES += main.cpp
QT += testlib

View File

@ -87,6 +87,7 @@ void tst_qmlmin::initTestCase()
excludedDirs << "doc/src/snippets/qtquick1/qtbinding";
excludedDirs << "doc/src/snippets/qtquick1/imports";
excludedDirs << "tests/manual/v4";
excludedDirs << "tests/auto/qml/qmllint";
// Add invalid files (i.e. files with syntax errors)
invalidFiles << "tests/auto/quick/qquickloader/data/InvalidSourceComponent.qml";

View File

@ -0,0 +1,37 @@
import QtQuick 2.0
Column {
width: 50; height: 200
Rectangle {
id: item1
objectName: "item1"
focus: true
width: 50; height: 50
color: focus ? "red" : "lightgray"
KeyNavigation.down: item2
}
Rectangle {
id: item2
objectName: "item2"
enabled: false
width: 50; height: 50
color: focus ? "red" : "lightgray"
KeyNavigation.down: item3
}
Rectangle {
id: item3
objectName: "item3"
enabled: false
width: 50; height: 50
color: focus ? "red" : "lightgray"
KeyNavigation.down: item4
}
Rectangle {
id: item4
objectName: "item4"
enabled: false
width: 50; height: 50
color: focus ? "red" : "lightgray"
KeyNavigation.down: item3
}
}

View File

@ -87,6 +87,7 @@ private slots:
void keyNavigation_skipNotVisible();
void keyNavigation_implicitSetting();
void keyNavigation_focusReason();
void keyNavigation_loop();
void layoutMirroring();
void layoutMirroringIllegalParent();
void smooth();
@ -2102,6 +2103,31 @@ void tst_QQuickItem::keyNavigation_focusReason()
delete window;
}
void tst_QQuickItem::keyNavigation_loop()
{
// QTBUG-47229
QQuickView *window = new QQuickView(0);
window->setBaseSize(QSize(240,320));
window->setSource(testFileUrl("keynavigationtest_loop.qml"));
window->show();
window->requestActivate();
QVERIFY(QTest::qWaitForWindowActive(window));
QCOMPARE(QGuiApplication::focusWindow(), window);
QQuickItem *item = findItem<QQuickItem>(window->rootObject(), "item1");
QVERIFY(item);
QVERIFY(item->hasActiveFocus());
QKeyEvent key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "", false, 1);
QGuiApplication::sendEvent(window, &key);
QVERIFY(key.isAccepted());
QVERIFY(item->hasActiveFocus());
delete window;
}
void tst_QQuickItem::smooth()
{
QQmlComponent component(&engine);

View File

@ -36,6 +36,7 @@
#include <QtQuick/QQuickTextDocument>
#include <QtQuick/QQuickItem>
#include <QtQuick/private/qquicktextedit_p.h>
#include <QtQuick/private/qquicktext_p_p.h>
#include <QtGui/QTextDocument>
#include <QtGui/QTextDocumentWriter>
#include <QtQml/QQmlEngine>
@ -47,6 +48,7 @@ class tst_qquicktextdocument : public QQmlDataTest
Q_OBJECT
private slots:
void textDocumentWriter();
void textDocumentWithImage();
};
QString text = QStringLiteral("foo bar");
@ -74,6 +76,20 @@ void tst_qquicktextdocument::textDocumentWriter()
delete o;
}
void tst_qquicktextdocument::textDocumentWithImage()
{
QQuickTextDocumentWithImageResources document(0);
QImage image(1, 1, QImage::Format_Mono);
image.fill(1);
QString name = "image";
document.addResource(QTextDocument::ImageResource, name, image);
QTextImageFormat format;
format.setName(name);
QCOMPARE(image, document.image(format));
QCOMPARE(image, document.resource(QTextDocument::ImageResource, name).value<QImage>());
}
QTEST_MAIN(tst_qquicktextdocument)
#include "tst_qquicktextdocument.moc"

View File

@ -117,6 +117,7 @@ void QmlProfilerClient::sendRecordingStatus(bool record)
{
QByteArray ba;
QDataStream stream(&ba, QIODevice::WriteOnly);
stream.setVersion(QDataStream::Qt_4_7);
stream << record << -1 << d->features;
sendMessage(ba);
}
@ -146,6 +147,7 @@ void QmlProfilerClient::messageReceived(const QByteArray &data)
{
QByteArray rwData = data;
QDataStream stream(&rwData, QIODevice::ReadOnly);
stream.setVersion(QDataStream::Qt_4_7);
// Force all the 1 << <FLAG> expressions to be done in 64 bit, to silence some warnings
const quint64 one = static_cast<quint64>(1);