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

Change-Id: Iec1b2de53c275996364c4bab0123ccb3e6e9895e
This commit is contained in:
Liang Qi 2016-01-29 13:01:21 +01:00
commit 1e421097f0
49 changed files with 562 additions and 415 deletions

View File

@ -116,6 +116,7 @@
\quotefromfile demos/photosurface/photosurface.qml
\skipto Rectangle
\printuntil Component.onCompleted
\printuntil }
\section1 Handling Pinch Gestures
@ -123,6 +124,7 @@
We use a PinchArea that contains a MouseArea in the photo frames to handle
dragging, rotation and pinch zooming of the frame:
\skipto PinchArea
\printuntil onPinchStarted
We use the \c pinch group property to control how the photo frames react to
@ -137,13 +139,13 @@
frame is controlled in the \c onEntered signal handler to highlight the
selected image:
\skipto MouseArea
\printuntil onEntered
To enable you to test the example on the desktop, we use the MouseArea's
\c onWheel signal handler to simulate pinch gestures by using a mouse:
\printuntil photoFrame.y
\printuntil }
\printuntil photoFrame.scale
\printuntil }
\printuntil }

View File

@ -44,9 +44,28 @@
#include <QtGui/QGuiApplication>
#endif
#include <QtQml/QQmlApplicationEngine>
#include <QtQml/QQmlContext>
#include <QtQuick/QQuickWindow>
#include <QtGui/QImageReader>
#include <QtCore/QCommandLineParser>
#include <QtCore/QCommandLineOption>
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QMimeDatabase>
#include <QtCore/QStandardPaths>
#include <QtCore/QUrl>
static QStringList imageNameFilters()
{
QStringList result;
QMimeDatabase mimeDatabase;
foreach (const QByteArray &m, QImageReader::supportedMimeTypes()) {
foreach (const QString &suffix, mimeDatabase.mimeTypeForName(m).suffixes())
result.append(QStringLiteral("*.") + suffix);
}
return result;
}
int main(int argc, char* argv[])
{
// The reason to use QApplication is that QWidget-based dialogs
@ -58,6 +77,51 @@ int main(int argc, char* argv[])
QGuiApplication app(argc, argv);
#endif
QQuickWindow::setDefaultAlphaBuffer(true);
QQmlApplicationEngine engine(QUrl("qrc:///photosurface.qml"));
QCoreApplication::setApplicationName(QStringLiteral("Photosurface"));
QCoreApplication::setOrganizationName(QStringLiteral("QtProject"));
QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));
QCommandLineParser parser;
parser.setApplicationDescription(QStringLiteral("Qt Quick Demo - Photo Surface"));
parser.addHelpOption();
parser.addVersionOption();
parser.addPositionalArgument(QStringLiteral("directory"),
QStringLiteral("The image directory or URL to show."));
parser.process(app);
QUrl initialUrl;
if (!parser.positionalArguments().isEmpty()) {
initialUrl = QUrl::fromUserInput(parser.positionalArguments().first(),
QDir::currentPath(), QUrl::AssumeLocalFile);
if (!initialUrl.isValid()) {
qWarning().nospace() << "Invalid argument: \""
<< parser.positionalArguments().first() << "\": " << initialUrl.errorString();
return 1;
}
}
const QStringList nameFilters = imageNameFilters();
QQmlApplicationEngine engine;
QQmlContext *context = engine.rootContext();
QUrl picturesLocationUrl = QUrl::fromLocalFile(QDir::homePath());
const QStringList picturesLocations = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation);
if (!picturesLocations.isEmpty()) {
picturesLocationUrl = QUrl::fromLocalFile(picturesLocations.first());
if (initialUrl.isEmpty()
&& !QDir(picturesLocations.first()).entryInfoList(nameFilters, QDir::Files).isEmpty()) {
initialUrl = picturesLocationUrl;
}
}
context->setContextProperty(QStringLiteral("contextPicturesLocation"), picturesLocationUrl);
context->setContextProperty(QStringLiteral("contextInitialUrl"), initialUrl);
context->setContextProperty(QStringLiteral("contextImageNameFilters"), nameFilters);
engine.load(QUrl("qrc:///photosurface.qml"));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}

View File

@ -56,6 +56,7 @@ Window {
id: fileDialog
title: "Choose a folder with some images"
selectFolder: true
folder: picturesLocation
onAccepted: folderModel.folder = fileUrl + "/"
}
@ -69,7 +70,7 @@ Window {
id: folderModel
objectName: "folderModel"
showDirs: false
nameFilters: ["*.png", "*.jpg", "*.gif"]
nameFilters: imageNameFilters
}
Rectangle {
id: photoFrame
@ -255,5 +256,21 @@ Window {
Shortcut { sequence: StandardKey.Quit; onActivated: Qt.quit() }
Component.onCompleted: fileDialog.open()
Component.onCompleted: {
if (typeof contextInitialUrl !== 'undefined') {
// Launched from C++ with context properties set.
imageNameFilters = contextImageNameFilters;
picturesLocation = contextPicturesLocation;
if (contextInitialUrl == "")
fileDialog.open();
else
folderModel.folder = contextInitialUrl + "/";
} else {
// Launched via QML viewer without context properties set.
fileDialog.open();
}
}
property var imageNameFilters : ["*.png", "*.jpg", "*.gif"];
property string picturesLocation : "";
}

View File

@ -0,0 +1,46 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
pragma Singleton
import QtQml 2.0
QtObject {
property string fontFamily: "Arial"
}

View File

@ -39,6 +39,7 @@
****************************************************************************/
import QtQuick 2.0
import "."
Rectangle {
id: button
@ -54,7 +55,7 @@ Rectangle {
}
Text {
anchors.centerIn: parent
font.family: "Open Sans"
font.family: Settings.fontFamily
font.pointSize: 19
font.weight: Font.DemiBold
color: button.buttonEnabled ? "#000000" : "#14aaff"

View File

@ -0,0 +1,46 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
pragma Singleton
import QtQml 2.0
QtObject {
property string fontFamily: "Open Sans"
}

View File

@ -39,6 +39,7 @@
****************************************************************************/
import QtQuick 2.0
import "."
Rectangle {
id: chart
@ -135,7 +136,7 @@ Rectangle {
Text {
id: fromDate
color: "#000000"
font.family: "Open Sans"
font.family: Settings.fontFamily
font.pointSize: 8
anchors.left: parent.left
anchors.bottom: parent.bottom
@ -145,7 +146,7 @@ Rectangle {
Text {
id: toDate
color: "#000000"
font.family: "Open Sans"
font.family: Settings.fontFamily
font.pointSize: 8
anchors.right: parent.right
anchors.rightMargin: canvas.tickMargin

View File

@ -39,6 +39,7 @@
****************************************************************************/
import QtQuick 2.0
import "."
Rectangle {
id: root
@ -60,7 +61,7 @@ Rectangle {
Text {
id: stockIdText
color: "#000000"
font.family: "Open Sans"
font.family: Settings.fontFamily
font.pointSize: 28
font.weight: Font.DemiBold
text: root.stock.stockId
@ -69,7 +70,7 @@ Rectangle {
Text {
id: price
color: "#6d6d6d"
font.family: "Open Sans"
font.family: Settings.fontFamily
font.pointSize: 28
font.weight: Font.DemiBold
text: parseFloat(Math.round(root.stock.stockPrice * 100) / 100).toFixed(2);
@ -79,7 +80,7 @@ Rectangle {
Text {
id: stockNameText
color: "#0c0c0c"
font.family: "Open Sans"
font.family: Settings.fontFamily
font.pointSize: 16
width: stockColumn.width
elide: Text.ElideRight
@ -96,7 +97,7 @@ Rectangle {
id: priceChange
horizontalAlignment: Text.AlignRight
color: root.stock.stockPriceChanged < 0 ? "#d40000" : "#328930"
font.family: "Open Sans"
font.family: Settings.fontFamily
font.pointSize: 18
text: parseFloat(Math.round(root.stock.stockPriceChanged * 100) / 100).toFixed(2);
}
@ -105,7 +106,7 @@ Rectangle {
id: priceChangePercentage
horizontalAlignment: Text.AlignRight
color: root.stock.stockPriceChanged < 0 ? "#d40000" : "#328930"
font.family: "Open Sans"
font.family: Settings.fontFamily
font.pointSize: 18
font.weight: Font.DemiBold
text: "(" +

View File

@ -39,6 +39,7 @@
****************************************************************************/
import QtQuick 2.0
import "."
Rectangle {
id: root
@ -144,7 +145,7 @@ Rectangle {
width: 125
height: 40
color: "#000000"
font.family: "Open Sans"
font.family: Settings.fontFamily
font.pointSize: 20
font.weight: Font.Bold
verticalAlignment: Text.AlignVCenter
@ -160,7 +161,7 @@ Rectangle {
width: 190
height: 40
color: "#000000"
font.family: "Open Sans"
font.family: Settings.fontFamily
font.pointSize: 20
font.bold: true
horizontalAlignment: Text.AlignRight
@ -178,7 +179,7 @@ Rectangle {
width: 135
height: 40
color: "#328930"
font.family: "Open Sans"
font.family: Settings.fontFamily
font.pointSize: 20
font.bold: true
horizontalAlignment: Text.AlignRight
@ -200,7 +201,7 @@ Rectangle {
width: 330
height: 30
color: "#000000"
font.family: "Open Sans"
font.family: Settings.fontFamily
font.pointSize: 16
font.bold: false
elide: Text.ElideRight
@ -217,7 +218,7 @@ Rectangle {
width: 120
height: 30
color: "#328930"
font.family: "Open Sans"
font.family: Settings.fontFamily
font.pointSize: 18
font.bold: false
horizontalAlignment: Text.AlignRight

View File

@ -39,6 +39,7 @@
****************************************************************************/
import QtQuick 2.0
import "."
Rectangle {
id: root
@ -62,7 +63,7 @@ Rectangle {
anchors.left: root.left
anchors.top: root.top
color: "#000000"
font.family: "Open Sans"
font.family: Settings.fontFamily
font.pointSize: 19
text: "Open"
}
@ -73,7 +74,7 @@ Rectangle {
anchors.top: openText.bottom
anchors.topMargin: 10
color: "#000000"
font.family: "Open Sans"
font.family: Settings.fontFamily
font.pointSize: 19
text: "Close"
}
@ -84,7 +85,7 @@ Rectangle {
anchors.top: closeText.bottom
anchors.topMargin: 10
color: "#000000"
font.family: "Open Sans"
font.family: Settings.fontFamily
font.pointSize: 19
text: "High"
}
@ -95,7 +96,7 @@ Rectangle {
anchors.top: highText.bottom
anchors.topMargin: 10
color: "#000000"
font.family: "Open Sans"
font.family: Settings.fontFamily
font.pointSize: 19
text: "Low"
}

View File

@ -0,0 +1,10 @@
singleton Settings 1.0 Settings.qml
Button 1.0 Button.qml
CheckBox 1.0 CheckBox.qml
StockChart 1.0 StockChart.qml
StockInfo 1.0 StockInfo.qml
StockListModel 1.0 StockListModel.qml
StockListView 1.0 StockListView.qml
StockModel 1.0 StockModel.qml
StockSettingsPanel 1.0 StockSettingsPanel.qml
StockView 1.0 StockView.qml

View File

@ -1,6 +1,7 @@
<RCC>
<qresource prefix="/demos/stocqt">
<file>stocqt.qml</file>
<file>content/qmldir</file>
<file>content/Button.qml</file>
<file>content/CheckBox.qml</file>
<file>content/StockChart.qml</file>
@ -13,5 +14,7 @@
<file>content/images/icon-left-arrow.png</file>
<file>content/StockSettingsPanel.qml</file>
<file>content/StockInfo.qml</file>
<file>content/Settings.qml</file>
<file>content/+windows/Settings.qml</file>
</qresource>
</RCC>

View File

@ -1882,17 +1882,17 @@ QV4::IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int
#ifndef V4_BOOTSTRAP
QQmlPropertyData *PropertyResolver::property(const QString &name, bool *notInRevision, QObject *object, QQmlContextData *context)
QQmlPropertyData *PropertyResolver::property(const QString &name, bool *notInRevision, RevisionCheck check)
{
if (notInRevision) *notInRevision = false;
QQmlPropertyData *d = cache->property(name, object, context);
QQmlPropertyData *d = cache->property(name, 0, 0);
// Find the first property
while (d && d->isFunction())
d = cache->overrideData(d);
if (d && !cache->isAllowedInRevision(d)) {
if (check != IgnoreRevision && d && !cache->isAllowedInRevision(d)) {
if (notInRevision) *notInRevision = true;
return 0;
} else {
@ -1901,11 +1901,11 @@ QQmlPropertyData *PropertyResolver::property(const QString &name, bool *notInRev
}
QQmlPropertyData *PropertyResolver::signal(const QString &name, bool *notInRevision, QObject *object, QQmlContextData *context)
QQmlPropertyData *PropertyResolver::signal(const QString &name, bool *notInRevision)
{
if (notInRevision) *notInRevision = false;
QQmlPropertyData *d = cache->property(name, object, context);
QQmlPropertyData *d = cache->property(name, 0, 0);
if (notInRevision) *notInRevision = false;
while (d && !(d->isFunction()))
@ -1921,7 +1921,7 @@ QQmlPropertyData *PropertyResolver::signal(const QString &name, bool *notInRevis
if (name.endsWith(QStringLiteral("Changed"))) {
QString propName = name.mid(0, name.length() - static_cast<int>(strlen("Changed")));
d = property(propName, notInRevision, object, context);
d = property(propName, notInRevision);
if (d)
return cache->signal(d->notifyIndex);
}

View File

@ -466,10 +466,15 @@ struct Q_QML_EXPORT PropertyResolver
return cache->property(index);
}
QQmlPropertyData *property(const QString &name, bool *notInRevision = 0, QObject *object = 0, QQmlContextData *context = 0);
enum RevisionCheck {
CheckRevision,
IgnoreRevision
};
QQmlPropertyData *property(const QString &name, bool *notInRevision = 0, RevisionCheck check = CheckRevision);
// This code must match the semantics of QQmlPropertyPrivate::findSignalByName
QQmlPropertyData *signal(const QString &name, bool *notInRevision, QObject *object = 0, QQmlContextData *context = 0);
QQmlPropertyData *signal(const QString &name, bool *notInRevision);
QQmlPropertyCache *cache;
};

View File

@ -1865,6 +1865,7 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD
}
bool bindingToDefaultProperty = false;
bool isGroupProperty = instantiatingBinding && instantiatingBinding->type == QV4::CompiledData::Binding::Type_GroupProperty;
bool notInRevision = false;
QQmlPropertyData *pd = 0;
@ -1873,7 +1874,7 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD
|| binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject)
pd = propertyResolver.signal(name, &notInRevision);
else
pd = propertyResolver.property(name, &notInRevision);
pd = propertyResolver.property(name, &notInRevision, isGroupProperty ? QmlIR::PropertyResolver::IgnoreRevision : QmlIR::PropertyResolver::CheckRevision);
if (notInRevision) {
QString typeName = stringAt(obj->inheritedTypeNameIndex);
@ -1885,7 +1886,7 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD
}
}
} else {
if (instantiatingBinding && instantiatingBinding->type == QV4::CompiledData::Binding::Type_GroupProperty)
if (isGroupProperty)
COMPILE_EXCEPTION(binding, tr("Cannot assign a value directly to a grouped property"));
pd = defaultProperty;

View File

@ -189,6 +189,8 @@ QV4::ReturnedValue QV4Include::method_include(QV4::CallContext *ctx)
V4THROW_ERROR("Qt.include(): Can only be called from JavaScript files");
QUrl url(scope.engine->resolvedUrl(ctx->args()[0].toQStringNoThrow()));
if (scope.engine->qmlEngine() && scope.engine->qmlEngine()->urlInterceptor())
url = scope.engine->qmlEngine()->urlInterceptor()->intercept(url, QQmlAbstractUrlInterceptor::JavaScriptFile);
QV4::ScopedValue callbackFunction(scope, QV4::Primitive::undefinedValue());
if (ctx->argc() >= 2 && ctx->args()[1].as<QV4::FunctionObject>())

View File

@ -40,6 +40,7 @@
#include "qv4persistent_p.h"
#include <private/qv4mm_p.h>
#include "qv4object_p.h"
#include "qv4qobjectwrapper_p.h"
#include "PageAllocation.h"
using namespace QV4;
@ -387,7 +388,7 @@ WeakValue &WeakValue::operator=(const WeakValue &other)
WeakValue::~WeakValue()
{
PersistentValueStorage::free(val);
free();
}
void WeakValue::set(ExecutionEngine *engine, const Value &value)
@ -418,3 +419,21 @@ void WeakValue::markOnce(ExecutionEngine *e)
val->mark(e);
}
void WeakValue::free()
{
if (!val)
return;
ExecutionEngine *e = engine();
if (e && val->as<QObjectWrapper>()) {
// Some QV4::QObjectWrapper Value will be freed in WeakValue::~WeakValue() before MemoryManager::sweep() is being called,
// in this case we will never have a chance to call detroyObject() on those QV4::QObjectWrapper objects.
// Here we don't free these Value immediately, instead we keep track of them to free them later in MemoryManager::sweep()
e->memoryManager->m_pendingFreedObjectWrapperValue.push_back(val);
} else {
PersistentValueStorage::free(val);
}
val = 0;
}

View File

@ -184,15 +184,15 @@ public:
bool isUndefined() const { return !val || val->isUndefined(); }
bool isNullOrUndefined() const { return !val || val->isNullOrUndefined(); }
void clear() {
PersistentValueStorage::free(val);
val = 0;
}
void clear() { free(); }
void markOnce(ExecutionEngine *e);
private:
Value *val;
private:
void free();
};
} // namespace QV4

View File

@ -47,8 +47,6 @@
#include "StdLibExtras.h"
#include <QTime>
#include <QVector>
#include <QVector>
#include <QMap>
#include <iostream>
@ -443,6 +441,21 @@ void MemoryManager::sweep(bool lastSweep)
(*it) = Primitive::undefinedValue();
}
// Now it is time to free QV4::QObjectWrapper Value, we must check the Value's tag to make sure its object has been destroyed
const int pendingCount = m_pendingFreedObjectWrapperValue.count();
if (pendingCount) {
QVector<Value *> remainingWeakQObjectWrappers;
remainingWeakQObjectWrappers.reserve(pendingCount);
for (int i = 0; i < pendingCount; ++i) {
Value *v = m_pendingFreedObjectWrapperValue.at(i);
if (v->tag() == Value::Undefined_Type)
PersistentValueStorage::free(v);
else
remainingWeakQObjectWrappers.append(v);
}
m_pendingFreedObjectWrapperValue = remainingWeakQObjectWrappers;
}
if (MultiplyWrappedQObjectMap *multiplyWrappedQObjects = engine->m_multiplyWrappedQObjects) {
for (MultiplyWrappedQObjectMap::Iterator it = multiplyWrappedQObjects->begin(); it != multiplyWrappedQObjects->end();) {
if (!it.value().isNullOrUndefined())

View File

@ -55,6 +55,7 @@
#include <private/qv4value_p.h>
#include <private/qv4scopedvalue_p.h>
#include <private/qv4object_p.h>
#include <QVector>
//#define DETAILED_MM_STATS
@ -333,6 +334,7 @@ public:
QScopedPointer<Data> m_d;
PersistentValueStorage *m_persistentValues;
PersistentValueStorage *m_weakValues;
QVector<Value *> m_pendingFreedObjectWrapperValue;
};
}

View File

@ -250,7 +250,7 @@ void QQmlType::SingletonInstanceInfo::destroy(QQmlEngine *e)
QObject *o = qobjectApis.take(e);
if (o) {
QQmlData *ddata = QQmlData::get(o, false);
if (ddata && ddata->indestructible)
if (url.isEmpty() && ddata && ddata->indestructible && ddata->explicitIndestructibleSet)
return;
delete o;
}

View File

@ -363,8 +363,14 @@ ReturnedValue QQmlValueTypeWrapper::get(const Managed *m, String *name, bool *ha
VALUE_TYPE_LOAD(QMetaType::QString, QString, v4->newString);
VALUE_TYPE_LOAD(QMetaType::Bool, bool, bool);
QVariant v(result->propType, (void *)0);
void *args[] = { v.data(), 0 };
QVariant v;
void *args[] = { Q_NULLPTR, Q_NULLPTR };
if (result->propType == QMetaType::QVariant) {
args[0] = &v;
} else {
v = QVariant(result->propType, static_cast<void *>(Q_NULLPTR));
args[0] = v.data();
}
metaObject->d.static_metacall(reinterpret_cast<QObject*>(gadget), QMetaObject::ReadProperty, index, args);
return v4->fromVariant(v);
#undef VALUE_TYPE_ACCESSOR

View File

@ -2276,6 +2276,9 @@ QQmlV4Handle QQmlListModel::get(int index) const
} else {
QObject *object = m_listModel->getOrCreateModelObject(const_cast<QQmlListModel *>(this), index);
result = scope.engine->memoryManager->allocObject<QV4::ModelObject>(object, const_cast<QQmlListModel *>(this), index);
// Keep track of the QObjectWrapper in persistent value storage
QV4::Value *val = scope.engine->memoryManager->m_weakValues->allocate();
*val = result;
}
}

View File

@ -74,7 +74,7 @@ configurations with the \c PropertyChanges type.
\snippet qml/states.qml signal states
The \l PropertyChanges type will change the values of object properties.
Objects are referenced through their
\l{qtqml-syntax-objectattributes.html#the-id-assignment}{id}. Objects outside
\l{qtqml-syntax-objectattributes.html#the-id-attribute}{id}. Objects outside
the component are also referenced using the \c id property, exemplified by the
property change to the external \c flag object.

View File

@ -53,7 +53,7 @@
#include <QtQuick/QQuickItem>
#include <private/qquicksprite_p.h>
#include <QTime>
#include <QtCore/qelapsedtimer.h>
QT_BEGIN_NAMESPACE
@ -372,7 +372,7 @@ private:
QQuickAnimatedSpriteMaterial *m_material;
QQuickSprite* m_sprite;
QQuickSpriteEngine* m_spriteEngine;
QTime m_timestamp;
QElapsedTimer m_timestamp;
int m_curFrame;
bool m_pleaseReset;
bool m_running;

View File

@ -270,6 +270,8 @@ void QQuickDropArea::dragEnterEvent(QDragEnterEvent *event)
QQuickDropEvent dragTargetEvent(d, event);
emit entered(&dragTargetEvent);
if (!event->isAccepted())
return;
d->containsDrag = true;
if (QQuickDragMimeData *dragMime = qobject_cast<QQuickDragMimeData *>(const_cast<QMimeData *>(mimeData)))

View File

@ -4257,7 +4257,7 @@ void QQuickItem::setBaselineOffset(qreal offset)
* The call to QQuickItem::updatePaintNode() will always happen if the
* item is showing in a QQuickWindow.
*
* Only items which specifies QQuickItem::ItemHasContents are allowed
* Only items which specify QQuickItem::ItemHasContents are allowed
* to call QQuickItem::update().
*/
void QQuickItem::update()
@ -4297,7 +4297,7 @@ void QQuickItem::polish()
\qmlmethod object QtQuick::Item::mapFromItem(Item item, real x, real y, real width, real height)
Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in \a
item's coordinate system, to this item's coordinate system, and returns a \l point or \rect
item's coordinate system, to this item's coordinate system, and returns a \l point or \l rect
matching the mapped coordinate.
If \a item is a \c null value, this maps the point or rect from the coordinate system of

View File

@ -1984,6 +1984,7 @@ void QQuickPathView::refill()
break;
}
if (d->items.contains(item)) {
d->releaseItem(item);
break; //Otherwise we'd "re-add" it, and get confused
}
if (d->currentIndex == idx) {
@ -2014,6 +2015,7 @@ void QQuickPathView::refill()
break;
}
if (d->items.contains(item)) {
d->releaseItem(item);
break; //Otherwise we'd "re-add" it, and get confused
}
if (d->currentIndex == idx) {
@ -2055,6 +2057,8 @@ void QQuickPathView::refill()
int lastListIdx = d->items.indexOf(lastItem);
d->items.insert(lastListIdx + 1, item);
d->updateItem(item, nextPos);
} else {
d->releaseItem(item);
}
lastItem = item;

View File

@ -234,7 +234,7 @@ void QQuickTextPrivate::setBottomPadding(qreal value, bool reset)
The default is true.
*/
void QQuickText::q_imagesLoaded()
void QQuickText::q_updateLayout()
{
Q_D(QQuickText);
d->updateLayout();
@ -1180,7 +1180,7 @@ void QQuickTextPrivate::ensureDoc()
extra->doc->setDocumentMargin(0);
extra->doc->setBaseUrl(q->baseUrl());
qmlobject_connect(extra->doc, QQuickTextDocumentWithImageResources, SIGNAL(imagesLoaded()),
q, QQuickText, SLOT(q_imagesLoaded()));
q, QQuickText, SLOT(q_updateLayout()));
}
}

View File

@ -298,7 +298,7 @@ protected:
void invalidateFontCaches();
private Q_SLOTS:
void q_imagesLoaded();
void q_updateLayout();
void triggerPreprocess();
void imageDownloadFinished();

View File

@ -90,50 +90,6 @@ QQuickTextNode::~QQuickTextNode()
qDeleteAll(m_textures);
}
#if 0
void QQuickTextNode::setColor(const QColor &color)
{
if (m_usePixmapCache) {
setUpdateFlag(UpdateNodes);
} else {
for (QSGNode *childNode = firstChild(); childNode; childNode = childNode->nextSibling()) {
if (childNode->subType() == GlyphNodeSubType) {
QSGGlyphNode *glyphNode = static_cast<QSGGlyphNode *>(childNode);
if (glyphNode->color() == m_color)
glyphNode->setColor(color);
} else if (childNode->subType() == SolidRectNodeSubType) {
QSGSimpleRectNode *solidRectNode = static_cast<QSGSimpleRectNode *>(childNode);
if (solidRectNode->color() == m_color)
solidRectNode->setColor(color);
}
}
}
m_color = color;
}
void QQuickTextNode::setStyleColor(const QColor &styleColor)
{
if (m_textStyle != QQuickTextNode::NormalTextStyle) {
if (m_usePixmapCache) {
setUpdateFlag(UpdateNodes);
} else {
for (QSGNode *childNode = firstChild(); childNode; childNode = childNode->nextSibling()) {
if (childNode->subType() == GlyphNodeSubType) {
QSGGlyphNode *glyphNode = static_cast<QSGGlyphNode *>(childNode);
if (glyphNode->color() == m_styleColor)
glyphNode->setColor(styleColor);
} else if (childNode->subType() == SolidRectNodeSubType) {
QSGSimpleRectNode *solidRectNode = static_cast<QSGSimpleRectNode *>(childNode);
if (solidRectNode->color() == m_styleColor)
solidRectNode->setColor(styleColor);
}
}
}
}
m_styleColor = styleColor;
}
#endif
QSGGlyphNode *QQuickTextNode::addGlyphs(const QPointF &position, const QGlyphRun &glyphs, const QColor &color,
QQuickText::TextStyle style, const QColor &styleColor,
QSGNode *parentNode)
@ -318,78 +274,4 @@ void QQuickTextNode::deleteContent()
m_textures.clear();
}
#if 0
void QQuickTextNode::updateNodes()
{
return;
deleteContent();
if (m_text.isEmpty())
return;
if (m_usePixmapCache) {
// ### gunnar: port properly
// QPixmap pixmap = generatedPixmap();
// if (pixmap.isNull())
// return;
// QSGImageNode *pixmapNode = m_context->createImageNode();
// pixmapNode->setRect(pixmap.rect());
// pixmapNode->setSourceRect(pixmap.rect());
// pixmapNode->setOpacity(m_opacity);
// pixmapNode->setClampToEdge(true);
// pixmapNode->setLinearFiltering(m_linearFiltering);
// appendChildNode(pixmapNode);
} else {
if (m_text.isEmpty())
return;
// Implement styling by drawing text several times at slight shifts. shiftForStyle
// contains the sequence of shifted positions at which to draw the text. All except
// the last will be drawn with styleColor.
QList<QPointF> shiftForStyle;
switch (m_textStyle) {
case OutlineTextStyle:
// ### Should be made faster by implementing outline material
shiftForStyle << QPointF(-1, 0);
shiftForStyle << QPointF(0, -1);
shiftForStyle << QPointF(1, 0);
shiftForStyle << QPointF(0, 1);
break;
case SunkenTextStyle:
shiftForStyle << QPointF(0, -1);
break;
case RaisedTextStyle:
shiftForStyle << QPointF(0, 1);
break;
default:
break;
}
shiftForStyle << QPointF(0, 0); // Regular position
while (!shiftForStyle.isEmpty()) {
QPointF shift = shiftForStyle.takeFirst();
// Use styleColor for all but last shift
if (m_richText) {
QColor overrideColor = shiftForStyle.isEmpty() ? QColor() : m_styleColor;
QTextFrame *textFrame = m_textDocument->rootFrame();
QPointF p = m_textDocument->documentLayout()->frameBoundingRect(textFrame).topLeft();
QTextFrame::iterator it = textFrame->begin();
while (!it.atEnd()) {
addTextBlock(shift + p, it.currentBlock(), overrideColor);
++it;
}
} else {
addTextLayout(shift, m_textLayout, shiftForStyle.isEmpty()
? m_color
: m_styleColor);
}
}
}
}
#endif
QT_END_NAMESPACE

View File

@ -294,6 +294,13 @@ void QQuickWindow::update()
QQuickRenderControlPrivate::get(d->renderControl)->update();
}
void QQuickWindow::handleScreenChanged(QScreen *screen)
{
Q_D(QQuickWindow);
Q_UNUSED(screen)
d->forcePolish();
}
void forcePolishHelper(QQuickItem *item)
{
if (item->flags() & QQuickItem::ItemHasContents) {
@ -308,12 +315,12 @@ void forcePolishHelper(QQuickItem *item)
/*!
Schedules polish events on all items in the scene.
*/
void QQuickWindow::forcePolish()
void QQuickWindowPrivate::forcePolish()
{
Q_D(QQuickWindow);
if (!screen())
Q_Q(QQuickWindow);
if (!q->screen())
return;
forcePolishHelper(d->contentItem);
forcePolishHelper(contentItem);
}
void forceUpdate(QQuickItem *item)
@ -484,7 +491,7 @@ void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control)
QObject::connect(context, SIGNAL(invalidated()), q, SLOT(cleanupSceneGraph()), Qt::DirectConnection);
QObject::connect(q, SIGNAL(focusObjectChanged(QObject*)), q, SIGNAL(activeFocusItemChanged()));
QObject::connect(q, SIGNAL(screenChanged(QScreen*)), q, SLOT(forcePolish()));
QObject::connect(q, SIGNAL(screenChanged(QScreen*)), q, SLOT(handleScreenChanged(QScreen*)));
QObject::connect(q, SIGNAL(frameSwapped()), q, SLOT(runJobsAfterSwap()), Qt::DirectConnection);
@ -4012,7 +4019,7 @@ void QQuickWindow::resetOpenGLState()
*/
/*!
\qmlproperty Window::active
\qmlproperty bool Window::active
\since 5.1
The active status of the window.

View File

@ -202,7 +202,7 @@ protected:
private Q_SLOTS:
void maybeUpdate();
void cleanupSceneGraph();
void forcePolish();
void handleScreenChanged(QScreen *screen);
void setTransientParent_helper(QQuickWindow *window);
void runJobsAfterSwap();

View File

@ -196,6 +196,7 @@ public:
void cleanup(QSGNode *);
void polishItems();
void forcePolish();
void syncSceneGraph();
void renderSceneGraph(const QSize &size);

View File

@ -0,0 +1,12 @@
import Qt.test 1.1
import QtQuick 2.0
MyItemUsingRevisionedObject {
property real test
revisioned.prop1: 10
revisioned.prop2: 1
Component.onCompleted: test = revisioned.prop1 + revisioned.prop2
}

View File

@ -447,6 +447,7 @@ void registerTypes()
qmlRegisterType<MyRevisionedSubclass>("Qt.test",1,0,"MyRevisionedSubclass");
// MyRevisionedSubclass 1.1 uses MyRevisionedClass revision 1
qmlRegisterType<MyRevisionedSubclass,1>("Qt.test",1,1,"MyRevisionedSubclass");
qmlRegisterType<MyItemUsingRevisionedObject>("Qt.test", 1, 0, "MyItemUsingRevisionedObject");
#ifndef QT_NO_WIDGETS
qmlRegisterExtendedType<QWidget,QWidgetDeclarativeUI>("Qt.test",1,0,"QWidget");

View File

@ -1079,10 +1079,27 @@ protected:
qreal m_p4;
};
class MyItemUsingRevisionedObject : public QObject
{
Q_OBJECT
Q_PROPERTY(MyRevisionedClass *revisioned READ revisioned)
public:
MyItemUsingRevisionedObject() {
m_revisioned = new MyRevisionedClass;
}
MyRevisionedClass *revisioned() const { return m_revisioned; }
private:
MyRevisionedClass *m_revisioned;
};
QML_DECLARE_TYPE(MyRevisionedBaseClassRegistered)
QML_DECLARE_TYPE(MyRevisionedBaseClassUnregistered)
QML_DECLARE_TYPE(MyRevisionedClass)
QML_DECLARE_TYPE(MyRevisionedSubclass)
QML_DECLARE_TYPE(MyItemUsingRevisionedObject)
Q_DECLARE_METATYPE(MyQmlObject::MyType)

View File

@ -6573,6 +6573,15 @@ void tst_qqmlecmascript::revision()
QCOMPARE(object->property("test").toReal(), 11.);
delete object;
}
{
QQmlComponent component(&engine, testFileUrl("metaobjectRevision5.qml"));
QObject *object = component.create();
QVERIFY(object != 0);
QCOMPARE(object->property("test").toReal(), 11.);
delete object;
}
}
void tst_qqmlecmascript::realToInt()

View File

@ -0,0 +1,5 @@
import QtQml 2.0
QtObject {
property string myStr: "base file"
}

View File

@ -0,0 +1,3 @@
Qt.include("intercepted/included.js")
var myStr = myString()

View File

@ -0,0 +1,3 @@
function myString() {
return "base include file";
}

View File

@ -0,0 +1,3 @@
Qt.include("intercepted/included.js")
var myStr = myString()

View File

@ -0,0 +1,3 @@
function myString() {
return "intercepted include file";
}

View File

@ -0,0 +1,11 @@
import QtQml 2.0
import "intercepted.js" as Script
QtObject {
property url filePath: "doesNotExist.file"
property url resolvedUrl: Qt.resolvedUrl("doesNotExist.file");
property url absoluteUrl: Qt.resolvedUrl("file:///doesNotExist.file");
property string childString: child.myStr
property string scriptString: Script.myStr
property Intercepted child: Intercepted {}
}

View File

@ -741,6 +741,15 @@ void tst_qqmlengine::urlInterceptor_data()
<< QStringLiteral("base file")
<< testFileUrl("interception/strings/intercepted/doesNotExist.file").toString()
<< QStringLiteral("file:///intercepted/doesNotExist.file");
QTest::newRow("InterceptIncludes")
<< testFileUrl("interception/includes/urlInterceptor.qml")
<< (QList<QQmlAbstractUrlInterceptor::DataType>() << QQmlAbstractUrlInterceptor::JavaScriptFile)
<< testFileUrl("interception/includes/doesNotExist.file").toString()
<< QStringLiteral("base file")
<< QStringLiteral("intercepted include file")
<< testFileUrl("interception/includes/doesNotExist.file").toString()
<< QStringLiteral("file:///doesNotExist.file");
}
void tst_qqmlengine::urlInterceptor()

View File

@ -244,6 +244,8 @@ private slots:
void dataAlignment();
void deleteSingletons();
private:
QQmlEngine engine;
QStringList defaultImportPathList;
@ -4082,6 +4084,24 @@ void tst_qqmllanguage::dataAlignment()
QVERIFY(sizeof(QQmlVMEMetaData::MethodData) % sizeof(int) == 0);
}
void tst_qqmllanguage::deleteSingletons()
{
QPointer<QObject> singleton;
{
QQmlEngine tmpEngine;
QQmlComponent component(&tmpEngine, testFile("singletonTest5.qml"));
VERIFY_ERRORS(0);
QObject *o = component.create();
QVERIFY(o != 0);
QObject *s1 = NULL;
getSingletonInstance(o, "singletonInstance", &s1);
QVERIFY(s1 != 0);
singleton = s1;
QVERIFY(singleton.data() != 0);
}
QVERIFY(singleton.data() == 0);
}
QTEST_MAIN(tst_qqmllanguage)
#include "tst_qqmllanguage.moc"

View File

@ -1490,6 +1490,7 @@ struct MyOffice
{
Q_PROPERTY(int chairs MEMBER m_chairs)
Q_PROPERTY(MyDesk desk READ desk WRITE setDesk)
Q_PROPERTY(QVariant myThing READ myThing WRITE setMyThing)
Q_GADGET
public:
MyOffice() : m_chairs(0) {}
@ -1497,8 +1498,12 @@ public:
MyDesk desk() const { return m_desk; }
void setDesk(const MyDesk &d) { m_desk = d; }
QVariant myThing() const { return m_myThing; }
void setMyThing(const QVariant &thingy) { m_myThing = thingy; }
int m_chairs;
MyDesk m_desk;
QVariant m_myThing;
};
Q_DECLARE_METATYPE(MyOffice)
@ -1510,6 +1515,11 @@ void tst_qqmlvaluetypes::customValueType()
MyOffice cppOffice;
cppOffice.m_chairs = 2;
QVariantMap m;
m.insert(QStringLiteral("hasChair"), false);
m.insert(QStringLiteral("textOnWhiteboard"), QStringLiteral("Blah blah"));
cppOffice.m_myThing = m;
QJSValue office = engine.toScriptValue(cppOffice);
QCOMPARE(office.property("chairs").toInt(), 2);
office.setProperty("chairs", 1);
@ -1527,6 +1537,14 @@ void tst_qqmlvaluetypes::customValueType()
cppOffice = engine.fromScriptValue<MyOffice>(office);
QCOMPARE(cppOffice.m_chairs, 1);
QCOMPARE(cppOffice.desk().monitorCount, 2);
QJSValue thingy = office.property("myThing");
QVERIFY(thingy.hasProperty("hasChair"));
QVERIFY(thingy.property("hasChair").isBool());
QCOMPARE(thingy.property("hasChair").toBool(), false);
QVERIFY(thingy.property("textOnWhiteboard").isString());
QVERIFY(thingy.hasProperty("textOnWhiteboard"));
QCOMPARE(thingy.property("textOnWhiteboard").toString(), QStringLiteral("Blah blah"));
}
struct BaseGadget

File diff suppressed because it is too large Load Diff

View File

@ -339,6 +339,24 @@ QVariantList mergeImports(const QVariantList &a, const QVariantList &b)
return merged;
}
// Predicates needed by findQmlImportsInDirectory.
struct isMetainfo {
bool operator() (const QFileInfo &x) const {
return x.suffix() == QLatin1String("metainfo");
}
};
struct pathStartsWith {
pathStartsWith(const QString &path) : _path(path) {}
bool operator() (const QString &x) const {
return _path.startsWith(x);
}
const QString _path;
};
// Scan all qml files in directory for import statements
QVariantList findQmlImportsInDirectory(const QString &qmlDir)
{
@ -348,19 +366,6 @@ QVariantList findQmlImportsInDirectory(const QString &qmlDir)
QDirIterator iterator(qmlDir, QDir::AllDirs | QDir::NoDotDot, QDirIterator::Subdirectories);
QStringList blacklist;
struct isMetainfo {
bool operator() (const QFileInfo &x) const {
return x.suffix() == QLatin1String("metainfo");
}
};
struct pathStartsWith {
pathStartsWith(const QString &path) : _path(path) {}
bool operator() (const QString &x) const {
return _path.startsWith(x);
}
const QString _path;
};
while (iterator.hasNext()) {
iterator.next();