Merge remote-tracking branch 'origin/5.14' into 5.15

Change-Id: I2835748c27616103f275849141fbe5a93e3dfd8c
This commit is contained in:
Qt Forward Merge Bot 2019-10-10 01:00:21 +02:00
commit 1bddf29287
37 changed files with 789 additions and 217 deletions

View File

@ -87,7 +87,9 @@ QSGNode *CustomRenderItem::updatePaintNode(QSGNode *node, UpdatePaintNodeData *)
break;
case QSGRendererInterface::MetalRhi:
#ifdef Q_OS_DARWIN
// Restore when QTBUG-78580 is done and the .pro is updated accordingly
//#ifdef Q_OS_DARWIN
#ifdef Q_OS_MACOS
if (!n) {
MetalRenderNode *metalNode = new MetalRenderNode;
n = metalNode;

View File

@ -54,7 +54,8 @@
#include <qsgrendernode.h>
#include <QQuickItem>
#ifdef Q_OS_DARWIN
//#ifdef Q_OS_DARWIN
#ifdef Q_OS_MACOS
QT_BEGIN_NAMESPACE

View File

@ -490,7 +490,7 @@ void QQmlEngineDebugServiceImpl::processMessage(const QByteArray &message)
QQmlDebugPacket ds(message);
QByteArray type;
int queryId;
qint32 queryId;
ds >> type >> queryId;
QQmlDebugPacket rs;
@ -503,13 +503,13 @@ void QQmlEngineDebugServiceImpl::processMessage(const QByteArray &message)
QJSEngine *engine = m_engines.at(ii);
QString engineName = engine->objectName();
int engineId = QQmlDebugService::idForObject(engine);
qint32 engineId = QQmlDebugService::idForObject(engine);
rs << engineName << engineId;
}
} else if (type == "LIST_OBJECTS") {
int engineId = -1;
qint32 engineId = -1;
ds >> engineId;
QQmlEngine *engine =
@ -532,7 +532,7 @@ void QQmlEngineDebugServiceImpl::processMessage(const QByteArray &message)
}
} else if (type == "FETCH_OBJECT") {
int objectId;
qint32 objectId;
bool recurse;
bool dumpProperties = true;
@ -550,8 +550,8 @@ void QQmlEngineDebugServiceImpl::processMessage(const QByteArray &message)
} else if (type == "FETCH_OBJECTS_FOR_LOCATION") {
QString file;
int lineNumber;
int columnNumber;
qint32 lineNumber;
qint32 columnNumber;
bool recurse;
bool dumpProperties = true;
@ -569,7 +569,7 @@ void QQmlEngineDebugServiceImpl::processMessage(const QByteArray &message)
}
} else if (type == "WATCH_OBJECT") {
int objectId;
qint32 objectId;
ds >> objectId;
bool ok = m_watch->addWatch(queryId, objectId);
@ -577,7 +577,7 @@ void QQmlEngineDebugServiceImpl::processMessage(const QByteArray &message)
rs << QByteArray("WATCH_OBJECT_R") << queryId << ok;
} else if (type == "WATCH_PROPERTY") {
int objectId;
qint32 objectId;
QByteArray property;
ds >> objectId >> property;
@ -586,7 +586,7 @@ void QQmlEngineDebugServiceImpl::processMessage(const QByteArray &message)
rs << QByteArray("WATCH_PROPERTY_R") << queryId << ok;
} else if (type == "WATCH_EXPR_OBJECT") {
int debugId;
qint32 debugId;
QString expr;
ds >> debugId >> expr;
@ -600,11 +600,11 @@ void QQmlEngineDebugServiceImpl::processMessage(const QByteArray &message)
rs << QByteArray("NO_WATCH_R") << queryId << ok;
} else if (type == "EVAL_EXPRESSION") {
int objectId;
qint32 objectId;
QString expr;
ds >> objectId >> expr;
int engineId = -1;
qint32 engineId = -1;
if (!ds.atEnd())
ds >> engineId;
@ -632,12 +632,12 @@ void QQmlEngineDebugServiceImpl::processMessage(const QByteArray &message)
rs << QByteArray("EVAL_EXPRESSION_R") << queryId << result;
} else if (type == "SET_BINDING") {
int objectId;
qint32 objectId;
QString propertyName;
QVariant expr;
bool isLiteralValue;
QString filename;
int line;
qint32 line;
ds >> objectId >> propertyName >> expr >> isLiteralValue >>
filename >> line;
bool ok = setBinding(objectId, propertyName, expr, isLiteralValue,
@ -646,7 +646,7 @@ void QQmlEngineDebugServiceImpl::processMessage(const QByteArray &message)
rs << QByteArray("SET_BINDING_R") << queryId << ok;
} else if (type == "RESET_BINDING") {
int objectId;
qint32 objectId;
QString propertyName;
ds >> objectId >> propertyName;
bool ok = resetBinding(objectId, propertyName);
@ -654,7 +654,7 @@ void QQmlEngineDebugServiceImpl::processMessage(const QByteArray &message)
rs << QByteArray("RESET_BINDING_R") << queryId << ok;
} else if (type == "SET_METHOD_BODY") {
int objectId;
qint32 objectId;
QString methodName;
QString methodBody;
ds >> objectId >> methodName >> methodBody;
@ -817,7 +817,8 @@ bool QQmlEngineDebugServiceImpl::setMethodBody(int objectId, const QString &meth
return true;
}
void QQmlEngineDebugServiceImpl::propertyChanged(int id, int objectId, const QMetaProperty &property, const QVariant &value)
void QQmlEngineDebugServiceImpl::propertyChanged(
qint32 id, qint32 objectId, const QMetaProperty &property, const QVariant &value)
{
QQmlDebugPacket rs;
rs << QByteArray("UPDATE_WATCH") << id << objectId << QByteArray(property.name()) << valueContents(value);
@ -848,14 +849,14 @@ void QQmlEngineDebugServiceImpl::objectCreated(QJSEngine *engine, QObject *objec
if (!m_engines.contains(engine))
return;
int engineId = QQmlDebugService::idForObject(engine);
int objectId = QQmlDebugService::idForObject(object);
int parentId = QQmlDebugService::idForObject(object->parent());
qint32 engineId = QQmlDebugService::idForObject(engine);
qint32 objectId = QQmlDebugService::idForObject(object);
qint32 parentId = QQmlDebugService::idForObject(object->parent());
QQmlDebugPacket rs;
//unique queryId -1
rs << QByteArray("OBJECT_CREATED") << -1 << engineId << objectId << parentId;
rs << QByteArray("OBJECT_CREATED") << qint32(-1) << engineId << objectId << parentId;
emit messageToClient(name(), rs.data());
}

View File

@ -111,7 +111,8 @@ private:
friend class QQmlDebuggerServiceFactory;
void processMessage(const QByteArray &msg);
void propertyChanged(int id, int objectId, const QMetaProperty &property, const QVariant &value);
void propertyChanged(qint32 id, qint32 objectId, const QMetaProperty &property,
const QVariant &value);
void prepareDeferredObjects(QObject *);
void buildObjectList(QDataStream &, QQmlContext *,

View File

@ -91,6 +91,8 @@ QQmlTypePrivate::QQmlTypePrivate(QQmlType::RegistrationType type)
QQmlTypePrivate::~QQmlTypePrivate()
{
qDeleteAll(scopedEnums);
for (const auto &metaObject : metaObjects)
free(metaObject.metaObject);
switch (regType) {
case QQmlType::CppType:
delete extraData.cd->customParser;

View File

@ -54,11 +54,14 @@
#include <QtCore/qfile.h>
#include <QtCore/qdebug.h>
#include <QtCore/qtimer.h>
#include <QtCore/qloggingcategory.h>
#include <private/qobject_p.h>
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcBindingRemoval)
class QQmlBindPrivate : public QObjectPrivate
{
public:
@ -72,6 +75,7 @@ public:
, restoreBinding(true)
, restoreValue(false)
, restoreModeExplicit(false)
, writingProperty(false)
{}
~QQmlBindPrivate() { }
@ -90,6 +94,7 @@ public:
bool restoreBinding:1;
bool restoreValue:1;
bool restoreModeExplicit:1;
bool writingProperty: 1;
void validate(QObject *binding) const;
void clearPrev();
@ -193,6 +198,13 @@ QQmlBind::~QQmlBind()
When the binding becomes inactive again, any direct bindings that were previously
set on the property will be restored.
\note By default, a previously set literal value is not restored when the Binding becomes
inactive. Rather, the last value set by the now inactive Binding is retained. You can customize
the restoration behavior for literal values as well as bindings using the \l restoreMode
property. The default will change in Qt 6.0.
\sa restoreMode
*/
bool QQmlBind::when() const
{
@ -235,7 +247,7 @@ void QQmlBind::setObject(QObject *obj)
}
d->obj = obj;
if (d->componentComplete) {
d->prop = QQmlProperty(d->obj, d->propName, qmlContext(this));
setTarget(QQmlProperty(d->obj, d->propName, qmlContext(this)));
d->validate(this);
}
eval();
@ -281,7 +293,7 @@ void QQmlBind::setProperty(const QString &p)
}
d->propName = p;
if (d->componentComplete) {
d->prop = QQmlProperty(d->obj, d->propName, qmlContext(this));
setTarget(QQmlProperty(d->obj, d->propName, qmlContext(this)));
d->validate(this);
}
eval();
@ -360,7 +372,7 @@ void QQmlBind::setDelayed(bool delayed)
\endlist
\warning The default value is Binding.RestoreBinding. This will change in
Qt 5.15 to Binding.RestoreBindingOrValue.
Qt 6.0 to Binding.RestoreBindingOrValue.
If you rely on any specific behavior regarding the restoration of plain
values when bindings get disabled you should migrate to explicitly set the
@ -394,6 +406,19 @@ void QQmlBind::setRestoreMode(RestorationMode newMode)
void QQmlBind::setTarget(const QQmlProperty &p)
{
Q_D(QQmlBind);
if (Q_UNLIKELY(lcBindingRemoval().isInfoEnabled())) {
if (QObject *oldObject = d->prop.object()) {
QMetaProperty prop = oldObject->metaObject()->property(d->prop.index());
if (prop.hasNotifySignal()) {
QByteArray signal('2' + prop.notifySignal().methodSignature());
QObject::disconnect(oldObject, signal.constData(),
this, SLOT(targetValueChanged()));
}
}
p.connectNotifySignal(this, SLOT(targetValueChanged()));
}
d->prop = p;
}
@ -408,7 +433,7 @@ void QQmlBind::componentComplete()
Q_D(QQmlBind);
d->componentComplete = true;
if (!d->prop.isValid()) {
d->prop = QQmlProperty(d->obj, d->propName, qmlContext(this));
setTarget(QQmlProperty(d->obj, d->propName, qmlContext(this)));
d->validate(this);
}
eval();
@ -461,8 +486,8 @@ void QQmlBind::eval()
qmlWarning(this)
<< "Not restoring previous value because restoreMode has not been set."
<< "This behavior is deprecated."
<< "In Qt < 5.15 the default is Binding.RestoreBinding."
<< "In Qt >= 5.15 the default is Binding.RestoreBindingOrValue.";
<< "In Qt < 6.0 the default is Binding.RestoreBinding."
<< "In Qt >= 6.0 the default is Binding.RestoreBindingOrValue.";
}
} else if (d->prevIsVariant) {
if (d->restoreValue) {
@ -472,8 +497,8 @@ void QQmlBind::eval()
qmlWarning(this)
<< "Not restoring previous value because restoreMode has not been set."
<< "This behavior is deprecated."
<< "In Qt < 5.15 the default is Binding.RestoreBinding."
<< "In Qt >= 5.15 the default is Binding.RestoreBindingOrValue.";
<< "In Qt < 6.0 the default is Binding.RestoreBinding."
<< "In Qt >= 6.0 the default is Binding.RestoreBindingOrValue.";
}
}
return;
@ -502,7 +527,34 @@ void QQmlBind::eval()
QQmlPropertyPrivate::removeBinding(d->prop);
}
d->writingProperty = true;
d->prop.write(d->value.value.toVariant());
d->writingProperty = false;
}
void QQmlBind::targetValueChanged()
{
Q_D(QQmlBind);
if (d->writingProperty)
return;
if (d->when.isValid() && !d->when)
return;
QUrl url;
quint16 line = 0;
const QQmlData *ddata = QQmlData::get(this, false);
if (ddata && ddata->outerContext) {
url = ddata->outerContext->url();
line = ddata->lineNumber;
}
qCInfo(lcBindingRemoval,
"The target property of the Binding element created at %s:%d was changed from "
"elsewhere. This does not overwrite the binding. The target property will still be "
"updated when the value of the Binding element changes.",
qPrintable(url.toString()), line);
}
QT_END_NAMESPACE

View File

@ -116,6 +116,9 @@ protected:
private:
void prepareEval();
void eval();
private Q_SLOTS:
void targetValueChanged();
};
QT_END_NAMESPACE

View File

@ -33,14 +33,14 @@ QT_BEGIN_NAMESPACE
struct QQmlObjectData {
QUrl url;
int lineNumber = -1;
int columnNumber = -1;
qint32 lineNumber = -1;
qint32 columnNumber = -1;
QString idString;
QString objectName;
QString objectType;
int objectId = -1;
int contextId = -1;
int parentId = -1;
qint32 objectId = -1;
qint32 contextId = -1;
qint32 parentId = -1;
};
QPacket &operator>>(QPacket &ds, QQmlObjectData &data)
@ -63,10 +63,10 @@ struct QQmlObjectProperty {
QPacket &operator>>(QPacket &ds, QQmlObjectProperty &data)
{
int type;
qint32 type;
ds >> type >> data.name >> data.value >> data.valueTypeName
>> data.binding >> data.hasNotifySignal;
data.type = (QQmlObjectProperty::Type)type;
data.type = QQmlObjectProperty::Type(type);
return ds;
}
@ -81,10 +81,10 @@ QQmlEngineDebugClientPrivate::QQmlEngineDebugClientPrivate(QQmlDebugConnection *
}
quint32 QQmlEngineDebugClient::addWatch(
qint32 QQmlEngineDebugClient::addWatch(
const QQmlEngineDebugPropertyReference &property, bool *success)
{
quint32 id = -1;
qint32 id = -1;
*success = false;
if (state() == QQmlDebugClient::Enabled) {
id = getId();
@ -97,19 +97,19 @@ quint32 QQmlEngineDebugClient::addWatch(
return id;
}
quint32 QQmlEngineDebugClient::addWatch(
qint32 QQmlEngineDebugClient::addWatch(
const QQmlEngineDebugContextReference &, const QString &, bool *success)
{
*success = false;
qWarning("QQmlEngineDebugClient::addWatch(): Not implemented");
return 0;
return -1;
}
quint32 QQmlEngineDebugClient::addWatch(
qint32 QQmlEngineDebugClient::addWatch(
const QQmlEngineDebugObjectReference &object, const QString &expr,
bool *success)
{
quint32 id = -1;
qint32 id = -1;
*success = false;
if (state() == QQmlDebugClient::Enabled) {
id = getId();
@ -121,10 +121,10 @@ quint32 QQmlEngineDebugClient::addWatch(
return id;
}
quint32 QQmlEngineDebugClient::addWatch(
qint32 QQmlEngineDebugClient::addWatch(
const QQmlEngineDebugObjectReference &object, bool *success)
{
quint32 id = -1;
qint32 id = -1;
*success = false;
if (state() == QQmlDebugClient::Enabled) {
id = getId();
@ -136,15 +136,15 @@ quint32 QQmlEngineDebugClient::addWatch(
return id;
}
quint32 QQmlEngineDebugClient::addWatch(
qint32 QQmlEngineDebugClient::addWatch(
const QQmlEngineDebugFileReference &, bool *success)
{
*success = false;
qWarning("QQmlEngineDebugClient::addWatch(): Not implemented");
return 0;
return -1;
}
void QQmlEngineDebugClient::removeWatch(quint32 id, bool *success)
void QQmlEngineDebugClient::removeWatch(qint32 id, bool *success)
{
*success = false;
if (state() == QQmlDebugClient::Enabled) {
@ -155,11 +155,11 @@ void QQmlEngineDebugClient::removeWatch(quint32 id, bool *success)
}
}
quint32 QQmlEngineDebugClient::queryAvailableEngines(bool *success)
qint32 QQmlEngineDebugClient::queryAvailableEngines(bool *success)
{
Q_D(QQmlEngineDebugClient);
d->engines.clear();
quint32 id = -1;
qint32 id = -1;
*success = false;
if (state() == QQmlDebugClient::Enabled) {
id = getId();
@ -171,12 +171,12 @@ quint32 QQmlEngineDebugClient::queryAvailableEngines(bool *success)
return id;
}
quint32 QQmlEngineDebugClient::queryRootContexts(
qint32 QQmlEngineDebugClient::queryRootContexts(
const QQmlEngineDebugEngineReference &engine, bool *success)
{
Q_D(QQmlEngineDebugClient);
d->rootContext = QQmlEngineDebugContextReference();
quint32 id = -1;
qint32 id = -1;
*success = false;
if (state() == QQmlDebugClient::Enabled && engine.debugId != -1) {
id = getId();
@ -188,12 +188,12 @@ quint32 QQmlEngineDebugClient::queryRootContexts(
return id;
}
quint32 QQmlEngineDebugClient::queryObject(
qint32 QQmlEngineDebugClient::queryObject(
const QQmlEngineDebugObjectReference &object, bool *success)
{
Q_D(QQmlEngineDebugClient);
d->object = QQmlEngineDebugObjectReference();
quint32 id = -1;
qint32 id = -1;
*success = false;
if (state() == QQmlDebugClient::Enabled && object.debugId != -1) {
id = getId();
@ -205,12 +205,12 @@ quint32 QQmlEngineDebugClient::queryObject(
return id;
}
quint32 QQmlEngineDebugClient::queryObjectsForLocation(
const QString &file, int lineNumber, int columnNumber, bool *success)
qint32 QQmlEngineDebugClient::queryObjectsForLocation(
const QString &file, qint32 lineNumber, qint32 columnNumber, bool *success)
{
Q_D(QQmlEngineDebugClient);
d->objects.clear();
quint32 id = -1;
qint32 id = -1;
*success = false;
if (state() == QQmlDebugClient::Enabled) {
id = getId();
@ -223,12 +223,12 @@ quint32 QQmlEngineDebugClient::queryObjectsForLocation(
return id;
}
quint32 QQmlEngineDebugClient::queryObjectRecursive(
qint32 QQmlEngineDebugClient::queryObjectRecursive(
const QQmlEngineDebugObjectReference &object, bool *success)
{
Q_D(QQmlEngineDebugClient);
d->object = QQmlEngineDebugObjectReference();
quint32 id = -1;
qint32 id = -1;
*success = false;
if (state() == QQmlDebugClient::Enabled && object.debugId != -1) {
id = getId();
@ -240,12 +240,12 @@ quint32 QQmlEngineDebugClient::queryObjectRecursive(
return id;
}
quint32 QQmlEngineDebugClient::queryObjectsForLocationRecursive(const QString &file,
int lineNumber, int columnNumber, bool *success)
qint32 QQmlEngineDebugClient::queryObjectsForLocationRecursive(const QString &file,
qint32 lineNumber, qint32 columnNumber, bool *success)
{
Q_D(QQmlEngineDebugClient);
d->objects.clear();
quint32 id = -1;
qint32 id = -1;
*success = false;
if (state() == QQmlDebugClient::Enabled) {
id = getId();
@ -258,12 +258,12 @@ quint32 QQmlEngineDebugClient::queryObjectsForLocationRecursive(const QString &f
return id;
}
quint32 QQmlEngineDebugClient::queryExpressionResult(
int objectDebugId, const QString &expr, bool *success)
qint32 QQmlEngineDebugClient::queryExpressionResult(
qint32 objectDebugId, const QString &expr, bool *success)
{
Q_D(QQmlEngineDebugClient);
d->exprResult = QVariant();
quint32 id = -1;
qint32 id = -1;
*success = false;
if (state() == QQmlDebugClient::Enabled) {
id = getId();
@ -276,12 +276,12 @@ quint32 QQmlEngineDebugClient::queryExpressionResult(
return id;
}
quint32 QQmlEngineDebugClient::queryExpressionResultBC(
int objectDebugId, const QString &expr, bool *success)
qint32 QQmlEngineDebugClient::queryExpressionResultBC(
qint32 objectDebugId, const QString &expr, bool *success)
{
Q_D(QQmlEngineDebugClient);
d->exprResult = QVariant();
quint32 id = -1;
qint32 id = -1;
*success = false;
if (state() == QQmlDebugClient::Enabled) {
id = getId();
@ -293,15 +293,15 @@ quint32 QQmlEngineDebugClient::queryExpressionResultBC(
return id;
}
quint32 QQmlEngineDebugClient::setBindingForObject(
int objectDebugId,
qint32 QQmlEngineDebugClient::setBindingForObject(
qint32 objectDebugId,
const QString &propertyName,
const QVariant &bindingExpression,
bool isLiteralValue,
const QString &source, int line,
const QString &source, qint32 line,
bool *success)
{
quint32 id = -1;
qint32 id = -1;
*success = false;
if (state() == QQmlDebugClient::Enabled && objectDebugId != -1) {
id = getId();
@ -314,12 +314,12 @@ quint32 QQmlEngineDebugClient::setBindingForObject(
return id;
}
quint32 QQmlEngineDebugClient::resetBindingForObject(
int objectDebugId,
qint32 QQmlEngineDebugClient::resetBindingForObject(
qint32 objectDebugId,
const QString &propertyName,
bool *success)
{
quint32 id = -1;
qint32 id = -1;
*success = false;
if (state() == QQmlDebugClient::Enabled && objectDebugId != -1) {
id = getId();
@ -331,11 +331,11 @@ quint32 QQmlEngineDebugClient::resetBindingForObject(
return id;
}
quint32 QQmlEngineDebugClient::setMethodBody(
int objectDebugId, const QString &methodName,
qint32 QQmlEngineDebugClient::setMethodBody(
qint32 objectDebugId, const QString &methodName,
const QString &methodBody, bool *success)
{
quint32 id = -1;
qint32 id = -1;
*success = false;
if (state() == QQmlDebugClient::Enabled && objectDebugId != -1) {
id = getId();
@ -366,19 +366,19 @@ void QQmlEngineDebugClient::decode(QPacket &ds,
if (simple)
return;
int childCount;
qint32 childCount;
bool recur;
ds >> childCount >> recur;
for (int ii = 0; ii < childCount; ++ii) {
for (qint32 ii = 0; ii < childCount; ++ii) {
o.children.append(QQmlEngineDebugObjectReference());
decode(ds, o.children.last(), !recur);
}
int propCount;
qint32 propCount;
ds >> propCount;
for (int ii = 0; ii < propCount; ++ii) {
for (qint32 ii = 0; ii < propCount; ++ii) {
QQmlObjectProperty data;
ds >> data;
QQmlEngineDebugPropertyReference prop;
@ -414,9 +414,9 @@ void QQmlEngineDebugClient::decode(QPacket &ds,
QList<QQmlEngineDebugObjectReference> &o,
bool simple)
{
int count;
qint32 count;
ds >> count;
for (int i = 0; i < count; i++) {
for (qint32 i = 0; i < count; i++) {
QQmlEngineDebugObjectReference obj;
decode(ds, obj, simple);
o << obj;
@ -464,18 +464,18 @@ void QQmlEngineDebugClient::decode(QPacket &ds,
{
ds >> c.name >> c.debugId;
int contextCount;
qint32 contextCount;
ds >> contextCount;
for (int ii = 0; ii < contextCount; ++ii) {
for (qint32 ii = 0; ii < contextCount; ++ii) {
c.contexts.append(QQmlEngineDebugContextReference());
decode(ds, c.contexts.last());
}
int objectCount;
qint32 objectCount;
ds >> objectCount;
for (int ii = 0; ii < objectCount; ++ii) {
for (qint32 ii = 0; ii < objectCount; ++ii) {
QQmlEngineDebugObjectReference obj;
decode(ds, obj, true);
@ -490,18 +490,18 @@ void QQmlEngineDebugClient::messageReceived(const QByteArray &data)
d->valid = false;
QPacket ds(connection()->currentDataStreamVersion(), data);
int queryId;
qint32 queryId;
QByteArray type;
ds >> type >> queryId;
//qDebug() << "QQmlEngineDebugPrivate::message()" << type;
if (type == "LIST_ENGINES_R") {
int count;
qint32 count;
ds >> count;
d->engines.clear();
for (int ii = 0; ii < count; ++ii) {
for (qint32 ii = 0; ii < count; ++ii) {
QQmlEngineDebugEngineReference eng;
ds >> eng.name;
ds >> eng.debugId;
@ -532,7 +532,7 @@ void QQmlEngineDebugClient::messageReceived(const QByteArray &data)
ds >> d->valid;
} else if (type == "UPDATE_WATCH") {
int debugId;
qint32 debugId;
QByteArray name;
QVariant value;
ds >> debugId >> name >> value;
@ -540,7 +540,9 @@ void QQmlEngineDebugClient::messageReceived(const QByteArray &data)
return;
} else if (type == "OBJECT_CREATED") {
int engineId, objectId, parentId;
qint32 engineId;
qint32 objectId;
qint32 parentId;
ds >> engineId >> objectId >> parentId;
emit newObject(objectId);
return;
@ -557,7 +559,7 @@ void QQmlEngineDebugClient::messageReceived(const QByteArray &data)
}
quint32 QQmlEngineDebugClient::getId()
qint32 QQmlEngineDebugClient::getId()
{
Q_D(QQmlEngineDebugClient);
return d->nextId++;

View File

@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE
struct QQmlEngineDebugPropertyReference
{
int objectDebugId = -1;
qint32 objectDebugId = -1;
QString name;
QVariant value;
QString valueTypeName;
@ -61,25 +61,25 @@ struct QQmlEngineDebugPropertyReference
struct QQmlEngineDebugFileReference
{
QUrl url;
int lineNumber = -1;
int columnNumber = -1;
qint32 lineNumber = -1;
qint32 columnNumber = -1;
};
struct QQmlEngineDebugObjectReference
{
int debugId = -1;
qint32 debugId = -1;
QString className;
QString idString;
QString name;
QQmlEngineDebugFileReference source;
int contextDebugId = -1;
qint32 contextDebugId = -1;
QList<QQmlEngineDebugPropertyReference> properties;
QList<QQmlEngineDebugObjectReference> children;
};
struct QQmlEngineDebugContextReference
{
int debugId = -1;
qint32 debugId = -1;
QString name;
QList<QQmlEngineDebugObjectReference> objects;
QList<QQmlEngineDebugContextReference> contexts;
@ -87,7 +87,7 @@ struct QQmlEngineDebugContextReference
struct QQmlEngineDebugEngineReference
{
int debugId = -1;
qint32 debugId = -1;
QString name;
};
@ -100,46 +100,46 @@ class QQmlEngineDebugClient : public QQmlDebugClient
public:
explicit QQmlEngineDebugClient(QQmlDebugConnection *conn);
quint32 addWatch(const QQmlEngineDebugPropertyReference &,
bool *success);
quint32 addWatch(const QQmlEngineDebugContextReference &, const QString &,
bool *success);
quint32 addWatch(const QQmlEngineDebugObjectReference &, const QString &,
bool *success);
quint32 addWatch(const QQmlEngineDebugObjectReference &,
bool *success);
quint32 addWatch(const QQmlEngineDebugFileReference &,
qint32 addWatch(const QQmlEngineDebugPropertyReference &,
bool *success);
qint32 addWatch(const QQmlEngineDebugContextReference &, const QString &,
bool *success);
qint32 addWatch(const QQmlEngineDebugObjectReference &, const QString &,
bool *success);
qint32 addWatch(const QQmlEngineDebugObjectReference &,
bool *success);
qint32 addWatch(const QQmlEngineDebugFileReference &,
bool *success);
void removeWatch(quint32 watch, bool *success);
void removeWatch(qint32 watch, bool *success);
quint32 queryAvailableEngines(bool *success);
quint32 queryRootContexts(const QQmlEngineDebugEngineReference &,
bool *success);
quint32 queryObject(const QQmlEngineDebugObjectReference &,
bool *success);
quint32 queryObjectsForLocation(const QString &file,
int lineNumber, int columnNumber, bool *success);
quint32 queryObjectRecursive(const QQmlEngineDebugObjectReference &,
qint32 queryAvailableEngines(bool *success);
qint32 queryRootContexts(const QQmlEngineDebugEngineReference &,
bool *success);
qint32 queryObject(const QQmlEngineDebugObjectReference &,
bool *success);
qint32 queryObjectsForLocation(const QString &file,
qint32 lineNumber, qint32 columnNumber, bool *success);
qint32 queryObjectRecursive(const QQmlEngineDebugObjectReference &,
bool *success);
qint32 queryObjectsForLocationRecursive(const QString &file,
qint32 lineNumber, qint32 columnNumber, bool *success);
qint32 queryExpressionResult(qint32 objectDebugId,
const QString &expr,
bool *success);
quint32 queryObjectsForLocationRecursive(const QString &file,
int lineNumber, int columnNumber, bool *success);
quint32 queryExpressionResult(int objectDebugId,
const QString &expr,
bool *success);
quint32 queryExpressionResultBC(int objectDebugId,
const QString &expr,
bool *success);
quint32 setBindingForObject(int objectDebugId, const QString &propertyName,
const QVariant &bindingExpression,
bool isLiteralValue,
const QString &source, int line, bool *success);
quint32 resetBindingForObject(int objectDebugId,
const QString &propertyName, bool *success);
quint32 setMethodBody(int objectDebugId, const QString &methodName,
const QString &methodBody, bool *success);
qint32 queryExpressionResultBC(qint32 objectDebugId,
const QString &expr,
bool *success);
qint32 setBindingForObject(qint32 objectDebugId, const QString &propertyName,
const QVariant &bindingExpression,
bool isLiteralValue,
const QString &source, qint32 line, bool *success);
qint32 resetBindingForObject(qint32 objectDebugId,
const QString &propertyName, bool *success);
qint32 setMethodBody(qint32 objectDebugId, const QString &methodName,
const QString &methodBody, bool *success);
quint32 getId();
qint32 getId();
void decode(QPacket &ds, QQmlEngineDebugContextReference &);
void decode(QPacket &ds, QQmlEngineDebugObjectReference &, bool simple);
@ -153,7 +153,7 @@ public:
bool valid() const;
signals:
void newObject(int objectId);
void newObject(qint32 objectId);
void valueChanged(QByteArray,QVariant);
void result();

View File

@ -62,7 +62,7 @@ class QQmlEngineDebugClientPrivate : public QQmlDebugClientPrivate
public:
QQmlEngineDebugClientPrivate(QQmlDebugConnection *connection);
quint32 nextId = 0;
qint32 nextId = 0;
bool valid = false;
QList<QQmlEngineDebugEngineReference> engines;
QQmlEngineDebugContextReference rootContext;

View File

@ -453,7 +453,8 @@ void QQmlDelegateModel::setDelegate(QQmlComponent *delegate)
}
if (d->m_delegate == delegate)
return;
bool wasValid = d->m_delegate != nullptr;
if (d->m_complete)
_q_itemsRemoved(0, d->m_count);
d->m_delegate.setObject(delegate, this);
d->m_delegateValidated = false;
if (d->m_delegateChooser)
@ -469,7 +470,11 @@ void QQmlDelegateModel::setDelegate(QQmlComponent *delegate)
[d](){ d->delegateChanged(); });
}
}
d->delegateChanged(d->m_delegate, wasValid);
if (d->m_complete) {
_q_itemsInserted(0, d->adaptorModelCount());
d->requestMoreIfNecessary();
}
emit delegateChanged();
}
/*!

View File

@ -77,7 +77,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlDelegateModel : public QQmlInstanceModel, p
Q_DECLARE_PRIVATE(QQmlDelegateModel)
Q_PROPERTY(QVariant model READ model WRITE setModel)
Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate)
Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
Q_PROPERTY(QString filterOnGroup READ filterGroup WRITE setFilterGroup NOTIFY filterGroupChanged RESET resetFilterGroup)
Q_PROPERTY(QQmlDelegateModelGroup *items READ items CONSTANT) //TODO : worth renaming?
Q_PROPERTY(QQmlDelegateModelGroup *persistedItems READ persistedItems CONSTANT)
@ -140,6 +140,7 @@ Q_SIGNALS:
void filterGroupChanged();
void defaultGroupsChanged();
void rootIndexChanged();
void delegateChanged();
private Q_SLOTS:
void _q_itemsChanged(int index, int count, const QVector<int> &roles);

View File

@ -1641,8 +1641,18 @@ PropertyKey ModelObjectOwnPropertyKeyIterator::next(const Object *o, Property *p
if (attrs)
*attrs = QV4::Attr_Data;
if (pd) {
QVariant value = that->d()->m_model->data(that->d()->elementIndex(), role.index);
pd->value = v4->fromVariant(value);
if (auto recursiveListModel = qvariant_cast<QQmlListModel*>(value)) {
auto size = recursiveListModel->count();
auto array = ScopedArrayObject{scope, v4->newArrayObject(size)};
for (auto i = 0; i < size; i++) {
array->arrayPut(i, QJSValuePrivate::convertedToValue(v4, recursiveListModel->get(i)));
}
pd->value = array;
} else {
pd->value = v4->fromVariant(value);
}
}
return roleName->toPropertyKey();
}

View File

@ -247,6 +247,8 @@ void QQuickItemView::setModel(const QVariant &m)
connect(d->model, SIGNAL(modelUpdated(QQmlChangeSet,bool)),
this, SLOT(modelUpdated(QQmlChangeSet,bool)));
if (QQmlDelegateModel *dataModel = qobject_cast<QQmlDelegateModel*>(d->model))
QObjectPrivate::connect(dataModel, &QQmlDelegateModel::delegateChanged, d, &QQuickItemViewPrivate::applyDelegateChange);
emit countChanged();
}
emit modelChanged();
@ -277,22 +279,8 @@ void QQuickItemView::setDelegate(QQmlComponent *delegate)
if (QQmlDelegateModel *dataModel = qobject_cast<QQmlDelegateModel*>(d->model)) {
int oldCount = dataModel->count();
dataModel->setDelegate(delegate);
if (isComponentComplete()) {
d->releaseVisibleItems();
d->releaseItem(d->currentItem);
d->currentItem = nullptr;
d->updateSectionCriteria();
d->refill();
d->moveReason = QQuickItemViewPrivate::SetIndex;
d->updateCurrent(d->currentIndex);
if (d->highlight && d->currentItem) {
if (d->autoHighlight)
d->resetHighlightPosition();
d->updateTrackedItem();
}
d->moveReason = QQuickItemViewPrivate::Other;
d->updateViewport();
}
if (isComponentComplete())
d->applyDelegateChange();
if (oldCount != dataModel->count())
emit countChanged();
}
@ -1089,6 +1077,24 @@ qreal QQuickItemViewPrivate::calculatedMaxExtent() const
return maxExtent;
}
void QQuickItemViewPrivate::applyDelegateChange()
{
releaseVisibleItems();
releaseItem(currentItem);
currentItem = nullptr;
updateSectionCriteria();
refill();
moveReason = QQuickItemViewPrivate::SetIndex;
updateCurrent(currentIndex);
if (highlight && currentItem) {
if (autoHighlight)
resetHighlightPosition();
updateTrackedItem();
}
moveReason = QQuickItemViewPrivate::Other;
updateViewport();
}
// for debugging only
void QQuickItemViewPrivate::checkVisible() const
{

View File

@ -191,6 +191,8 @@ public:
qreal calculatedMinExtent() const;
qreal calculatedMaxExtent() const;
void applyDelegateChange();
void applyPendingChanges();
bool applyModelChanges(ChangeResult *insertionResult, ChangeResult *removalResult);
bool applyRemovalChange(const QQmlChangeSet::Change &removal, ChangeResult *changeResult, int *removedCount);

View File

@ -1212,8 +1212,8 @@ void QQuickTextControlPrivate::mouseReleaseEvent(QMouseEvent *e, const QPointF &
QTextBlock block = q->blockWithMarkerAt(pos);
if (block == blockWithMarkerUnderMousePress) {
auto fmt = block.blockFormat();
fmt.setMarker(fmt.marker() == QTextBlockFormat::Unchecked ?
QTextBlockFormat::Checked : QTextBlockFormat::Unchecked);
fmt.setMarker(fmt.marker() == QTextBlockFormat::MarkerType::Unchecked ?
QTextBlockFormat::MarkerType::Checked : QTextBlockFormat::MarkerType::Unchecked);
cursor.setBlockFormat(fmt);
}
}
@ -1507,7 +1507,7 @@ void QQuickTextControlPrivate::hoverEvent(QHoverEvent *e, const QPointF &pos)
emit q->markerHovered(block.isValid());
hoveredMarker = block.isValid();
if (hoveredMarker)
qCDebug(DBG_HOVER_TRACE) << q << e->type() << pos << "hovered marker" << block.blockFormat().marker() << block.text();
qCDebug(DBG_HOVER_TRACE) << q << e->type() << pos << "hovered marker" << int(block.blockFormat().marker()) << block.text();
}
}

View File

@ -1012,13 +1012,13 @@ void QQuickTextNodeEngine::addTextBlock(QTextDocument *textDocument, const QText
};
switch (block.blockFormat().marker()) {
case QTextBlockFormat::Checked:
case QTextBlockFormat::MarkerType::Checked:
listItemBullet = QChar(0x2612); // Checked checkbox
break;
case QTextBlockFormat::Unchecked:
case QTextBlockFormat::MarkerType::Unchecked:
listItemBullet = QChar(0x2610); // Unchecked checkbox
break;
case QTextBlockFormat::NoMarker:
case QTextBlockFormat::MarkerType::NoMarker:
break;
}

View File

@ -102,6 +102,7 @@ Q_LOGGING_CATEGORY(DBG_DIRTY, "qt.quick.dirty")
Q_LOGGING_CATEGORY(lcTransient, "qt.quick.window.transient")
extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha);
extern Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1);
bool QQuickWindowPrivate::defaultAlphaBuffer = false;
@ -1794,6 +1795,13 @@ void QQuickWindowPrivate::deliverKeyEvent(QKeyEvent *e)
{
if (activeFocusItem) {
QQuickItem *item = activeFocusItem;
// In case of generated event, trigger ShortcutOverride event
if (e->type() == QEvent::KeyPress && e->spontaneous() == false)
qt_sendShortcutOverrideEvent(item, e->timestamp(),
e->key(), e->modifiers(), e->text(),
e->isAutoRepeat(), e->count());
e->accept();
QCoreApplication::sendEvent(item, e);
while (!e->isAccepted() && (item = item->parentItem())) {
@ -2820,32 +2828,49 @@ void QQuickWindowPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QEvent *e
for (; grabItem != grabber->end(); grabItem = grabber->release(grabItem))
QCoreApplication::sendEvent(**grabItem, &leaveEvent);
return;
} else for (; grabItem != grabber->end(); grabItem = grabber->release(grabItem)) {
} else {
QDragMoveEvent *moveEvent = static_cast<QDragMoveEvent *>(event);
if (deliverDragEvent(grabber, **grabItem, moveEvent)) {
for (++grabItem; grabItem != grabber->end();) {
QPointF p = (**grabItem)->mapFromScene(moveEvent->pos());
if ((**grabItem)->contains(p)) {
QDragMoveEvent translatedEvent(
p.toPoint(),
moveEvent->possibleActions(),
moveEvent->mimeData(),
moveEvent->mouseButtons(),
moveEvent->keyboardModifiers());
QQuickDropEventEx::copyActions(&translatedEvent, *moveEvent);
QCoreApplication::sendEvent(**grabItem, &translatedEvent);
++grabItem;
} else {
QDragLeaveEvent leaveEvent;
QCoreApplication::sendEvent(**grabItem, &leaveEvent);
grabItem = grabber->release(grabItem);
}
// Used to ensure we don't send DragEnterEvents to current drop targets,
// and to detect which current drop targets we have left
QVarLengthArray<QQuickItem*, 64> currentGrabItems;
for (; grabItem != grabber->end(); grabItem = grabber->release(grabItem))
currentGrabItems.append(**grabItem);
// Look for any other potential drop targets that are higher than the current ones
QDragEnterEvent enterEvent(
moveEvent->pos(),
moveEvent->possibleActions(),
moveEvent->mimeData(),
moveEvent->mouseButtons(),
moveEvent->keyboardModifiers());
QQuickDropEventEx::copyActions(&enterEvent, *moveEvent);
event->setAccepted(deliverDragEvent(grabber, contentItem, &enterEvent, &currentGrabItems));
for (grabItem = grabber->begin(); grabItem != grabber->end(); ++grabItem) {
int i = currentGrabItems.indexOf(**grabItem);
if (i >= 0) {
currentGrabItems.remove(i);
// Still grabbed: send move event
QDragMoveEvent translatedEvent(
(**grabItem)->mapFromScene(moveEvent->pos()).toPoint(),
moveEvent->possibleActions(),
moveEvent->mimeData(),
moveEvent->mouseButtons(),
moveEvent->keyboardModifiers());
QQuickDropEventEx::copyActions(&translatedEvent, *moveEvent);
QCoreApplication::sendEvent(**grabItem, &translatedEvent);
event->setAccepted(translatedEvent.isAccepted());
QQuickDropEventEx::copyActions(moveEvent, translatedEvent);
}
return;
} else {
QDragLeaveEvent leaveEvent;
QCoreApplication::sendEvent(**grabItem, &leaveEvent);
}
// Anything left in currentGrabItems is no longer a drop target and should be sent a DragLeaveEvent
QDragLeaveEvent leaveEvent;
for (QQuickItem *i : currentGrabItems)
QCoreApplication::sendEvent(i, &leaveEvent);
return;
}
}
if (event->type() == QEvent::DragEnter || event->type() == QEvent::DragMove) {
@ -2861,9 +2886,8 @@ void QQuickWindowPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QEvent *e
}
}
bool QQuickWindowPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QQuickItem *item, QDragMoveEvent *event)
bool QQuickWindowPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QQuickItem *item, QDragMoveEvent *event, QVarLengthArray<QQuickItem*, 64> *currentGrabItems)
{
bool accepted = false;
QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
if (!item->isVisible() || !item->isEnabled() || QQuickItemPrivate::get(item)->culled)
return false;
@ -2882,12 +2906,24 @@ bool QQuickWindowPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QQuickIte
event->keyboardModifiers());
QQuickDropEventEx::copyActions(&enterEvent, *event);
QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
// Check children in front of this item first
for (int ii = children.count() - 1; ii >= 0; --ii) {
if (deliverDragEvent(grabber, children.at(ii), &enterEvent))
if (children.at(ii)->z() < 0)
continue;
if (deliverDragEvent(grabber, children.at(ii), &enterEvent, currentGrabItems))
return true;
}
if (itemContained) {
// If this item is currently grabbed, don't send it another DragEnter,
// just grab it again if it's still contained.
if (currentGrabItems && currentGrabItems->contains(item)) {
grabber->grab(item);
grabber->setTarget(item);
return true;
}
if (event->type() == QEvent::DragMove || itemPrivate->flags & QQuickItem::ItemAcceptsDrops) {
QDragMoveEvent translatedEvent(
p.toPoint(),
@ -2904,15 +2940,24 @@ bool QQuickWindowPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QQuickIte
if (event->type() == QEvent::DragEnter) {
if (translatedEvent.isAccepted()) {
grabber->grab(item);
accepted = true;
grabber->setTarget(item);
return true;
}
} else {
accepted = true;
return true;
}
}
}
return accepted;
// Check children behind this item if this item or any higher children have not accepted
for (int ii = children.count() - 1; ii >= 0; --ii) {
if (children.at(ii)->z() >= 0)
continue;
if (deliverDragEvent(grabber, children.at(ii), &enterEvent, currentGrabItems))
return true;
}
return false;
}
#endif // quick_draganddrop

View File

@ -192,7 +192,7 @@ public:
#if QT_CONFIG(quick_draganddrop)
void deliverDragEvent(QQuickDragGrabber *, QEvent *);
bool deliverDragEvent(QQuickDragGrabber *, QQuickItem *, QDragMoveEvent *);
bool deliverDragEvent(QQuickDragGrabber *, QQuickItem *, QDragMoveEvent *, QVarLengthArray<QQuickItem*, 64> *currentGrabItems = nullptr);
#endif
#if QT_CONFIG(cursor)
void updateCursor(const QPointF &scenePos);

View File

@ -619,6 +619,24 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
i++;
}
// Check for context loss.
if (!current && !rhi && !gl->isValid()) {
for (auto it = m_windows.constBegin() ; it != m_windows.constEnd(); it++) {
QQuickWindowPrivate *windowPrivate = QQuickWindowPrivate::get(it.key());
windowPrivate->cleanupNodesOnShutdown();
}
rc->invalidate();
current = gl->create() && gl->makeCurrent(window);
if (current) {
QSGDefaultRenderContext::InitParams rcParams;
rcParams.sampleCount = qMax(1, gl->format().samples());
rcParams.openGLContext = gl;
rcParams.initialSurfacePixelSize = window->size() * window->effectiveDevicePixelRatio();
rcParams.maybeSurface = window;
rc->initialize(&rcParams);
}
}
if (!current)
return;

View File

@ -109,6 +109,11 @@ qreal QQuickColorValueType::hslLightness() const
return v.lightnessF();
}
bool QQuickColorValueType::isValid() const
{
return v.isValid();
}
void QQuickColorValueType::setR(qreal r)
{
v.setRedF(r);

View File

@ -84,6 +84,7 @@ class QQuickColorValueType
Q_PROPERTY(qreal hslHue READ hslHue WRITE setHslHue FINAL)
Q_PROPERTY(qreal hslSaturation READ hslSaturation WRITE setHslSaturation FINAL)
Q_PROPERTY(qreal hslLightness READ hslLightness WRITE setHslLightness FINAL)
Q_PROPERTY(bool valid READ isValid)
Q_GADGET
public:
Q_INVOKABLE QString toString() const;
@ -98,6 +99,7 @@ public:
qreal hslHue() const;
qreal hslSaturation() const;
qreal hslLightness() const;
bool isValid() const;
void setR(qreal);
void setG(qreal);
void setB(qreal);

View File

@ -283,7 +283,16 @@ void QQuickWidgetPrivate::render(bool needsSync)
Q_ASSERT(context);
if (!context->makeCurrent(offscreenSurface)) {
bool current = context->makeCurrent(offscreenSurface);
if (!current && !context->isValid()) {
renderControl->invalidate();
current = context->create() && context->makeCurrent(offscreenSurface);
if (current)
renderControl->initialize(context);
}
if (!current) {
qWarning("QQuickWidget: Cannot render due to failing makeCurrent()");
return;
}

View File

@ -128,6 +128,7 @@ private slots:
void qobjectTrackerForDynamicModelObjects();
void crash_append_empty_array();
void dynamic_roles_crash_QTBUG_38907();
void nestedListModelIteration();
};
bool tst_qqmllistmodel::compareVariantList(const QVariantList &testList, QVariant object)
@ -1667,6 +1668,32 @@ void tst_qqmllistmodel::dynamic_roles_crash_QTBUG_38907()
QVERIFY(retVal.toBool());
}
void tst_qqmllistmodel::nestedListModelIteration()
{
QQmlEngine engine;
QQmlComponent component(&engine);
QTest::ignoreMessage(QtMsgType::QtDebugMsg ,R"({"subItems":[{"a":1,"b":0,"c":0},{"a":0,"b":2,"c":0},{"a":0,"b":0,"c":3}]})");
component.setData(
R"(import QtQuick 2.5
Item {
visible: true
width: 640
height: 480
ListModel {
id : model
}
Component.onCompleted: {
var tempData = {
subItems: [{a: 1}, {b: 2}, {c: 3}]
}
model.insert(0, tempData)
console.log(JSON.stringify(model.get(0)))
}
})",
QUrl());
QScopedPointer<QObject>(component.create());
}
QTEST_MAIN(tst_qqmllistmodel)
#include "tst_qqmllistmodel.moc"

View File

@ -12,4 +12,7 @@ MyTypeObject {
property real hsl_s: color.hslSaturation
property real hsl_l: color.hslLightness
property variant copy: color
property bool valid: color.valid
property bool invalid: invalidColor.valid
}

View File

@ -69,6 +69,7 @@ class MyTypeObject : public QObject
Q_PROPERTY(QMatrix4x4 matrix READ matrix WRITE setMatrix NOTIFY changed)
Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY changed)
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY changed)
Q_PROPERTY(QColor invalidColor READ invalidColor CONSTANT)
Q_PROPERTY(QVariant variant READ variant NOTIFY changed)
public:
@ -168,6 +169,8 @@ public:
QColor color() const { return m_color; }
void setColor(const QColor &v) { m_color = v; emit changed(); }
QColor invalidColor() const { return QColor(); }
QVariant variant() const { return sizef(); }
void emitRunScript() { emit runScript(); }

View File

@ -935,6 +935,11 @@ void tst_qqmlvaluetypes::color()
QCOMPARE(qRound(object->property("hsl_s").toDouble() * 100), 74);
QCOMPARE(qRound(object->property("hsl_l").toDouble() * 100), 54);
QCOMPARE(object->property("valid").userType(), QMetaType::Bool);
QVERIFY(object->property("valid").toBool());
QCOMPARE(object->property("invalid").userType(), QMetaType::Bool);
QVERIFY(!object->property("invalid").toBool());
QColor comparison;
comparison.setRedF(0.2);
comparison.setGreenF(0.88);

View File

@ -598,7 +598,7 @@ void tst_QQuickDrag::move()
QCoreApplication::processEvents();
QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&rightTarget));
QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&rightTarget));
QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 0);
QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 1); QCOMPARE(outerTarget.moveEvents, 0);
QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0);
QCOMPARE(rightTarget.enterEvents, 1); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0);
QCOMPARE(rightTarget.position.x(), qreal(5)); QCOMPARE(rightTarget.position.y(), qreal(15));
@ -620,10 +620,10 @@ void tst_QQuickDrag::move()
QCoreApplication::processEvents();
QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&leftTarget));
QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&leftTarget));
QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1);
QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 0);
QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 1);
QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0);
QCOMPARE(outerTarget.position.x(), qreal(25)); QCOMPARE(outerTarget.position.y(), qreal(40));
QCOMPARE(outerTarget.position.x(), qreal(60)); QCOMPARE(outerTarget.position.y(), qreal(50));
QCOMPARE(leftTarget.position.x(), qreal(25)); QCOMPARE(leftTarget.position.y(), qreal(5));
// Move out of all targets.
@ -632,7 +632,7 @@ void tst_QQuickDrag::move()
QCoreApplication::processEvents();
QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(nullptr));
QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(nullptr));
QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 1); QCOMPARE(outerTarget.moveEvents, 0);
QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 0);
QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 1); QCOMPARE(leftTarget .moveEvents, 0);
QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0);

View File

@ -0,0 +1,93 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** 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 https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, 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$
**
****************************************************************************/
import QtQuick 2.0
Item {
width: 200; height: 200
property int outerEnterEvents: 0
property int outerExitEvents: 0
property int innerEnterEvents: 0
property int innerExitEvents: 0
DropArea {
objectName: "outerDropArea"
x: 75; y: 75
width: 100; height: 100
Rectangle {
anchors.fill: parent
color: "green"
}
onEntered: ++outerEnterEvents
onExited: ++outerExitEvents
DropArea {
objectName: "innerDropArea"
width: 50; height: 50
Rectangle {
anchors.fill: parent
color: "blue"
}
onEntered: ++innerEnterEvents
onExited: ++innerExitEvents
}
}
Rectangle {
width: 20; height: 20
color: dragArea.pressed ? "red" : "brown"
Drag.active: dragArea.drag.active
MouseArea {
id: dragArea
objectName: "dragArea"
anchors.fill: parent
drag.target: parent
}
}
}

View File

@ -0,0 +1,93 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** 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 https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, 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$
**
****************************************************************************/
import QtQuick 2.0
Item {
width: 200; height: 200
property int outerEnterEvents: 0
property int outerExitEvents: 0
property int innerEnterEvents: 0
property int innerExitEvents: 0
Rectangle {
x: 75; y: 75
width: 100; height: 100
color: "green"
DropArea {
objectName: "outerDropArea"
anchors.fill: parent
onEntered: ++outerEnterEvents
onExited: ++outerExitEvents
}
Rectangle {
width: 50; height: 50
color: "blue"
DropArea {
objectName: "innerDropArea"
anchors.fill: parent
onEntered: ++innerEnterEvents
onExited: ++innerExitEvents
}
}
}
Rectangle {
width: 20; height: 20
color: dragArea.pressed ? "red" : "brown"
Drag.active: dragArea.drag.active
MouseArea {
id: dragArea
objectName: "dragArea"
anchors.fill: parent
drag.target: parent
}
}
}

View File

@ -4,4 +4,11 @@ macx:CONFIG -= app_bundle
SOURCES += tst_qquickdroparea.cpp
OTHER_FILES += $$files(data/*.qml)
include (../../shared/util.pri)
include (../shared/util.pri)
TESTDATA = data/*
QT += core-private gui-private qml-private quick-private network testlib

View File

@ -28,6 +28,7 @@
#include <QtTest/QtTest>
#include <QtTest/QSignalSpy>
#include <QtGui/qstylehints.h>
#include <QtQuick/qquickitem.h>
#include <QtQuick/qquickview.h>
#include <QtQml/qqmlcontext.h>
@ -36,6 +37,8 @@
#include <qpa/qplatformdrag.h>
#include <qpa/qwindowsysteminterface.h>
#include "../../shared/util.h"
#include "../shared/viewtestutil.h"
template <typename T> static T evaluate(QObject *scope, const QString &expression)
{
@ -54,13 +57,10 @@ template <> void evaluate<void>(QObject *scope, const QString &expression)
qWarning() << expr.error().toString();
}
class tst_QQuickDropArea: public QObject
class tst_QQuickDropArea: public QQmlDataTest
{
Q_OBJECT
private slots:
void initTestCase();
void cleanupTestCase();
void containsDrag_internal();
void containsDrag_external();
void keys_internal();
@ -74,21 +74,13 @@ private slots:
void competingDrags();
void simultaneousDrags();
void dropStuff();
void nestedDropAreas_data();
void nestedDropAreas();
private:
QQmlEngine engine;
};
void tst_QQuickDropArea::initTestCase()
{
}
void tst_QQuickDropArea::cleanupTestCase()
{
}
void tst_QQuickDropArea::containsDrag_internal()
{
QQuickWindow window;
@ -1224,6 +1216,74 @@ void tst_QQuickDropArea::dropStuff()
QCOMPARE(evaluate<QByteArray>(dropArea, "array"), QByteArray("red"));
}
void tst_QQuickDropArea::nestedDropAreas_data()
{
QTest::addColumn<QString>("qmlFile");
QTest::newRow("dropRectDropRect") << "nested1.qml";
QTest::newRow("rectDropRectDrop") << "nested2.qml";
}
void tst_QQuickDropArea::nestedDropAreas()
{
QFETCH(QString, qmlFile);
const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
QQuickView window;
QByteArray errorMessage;
QVERIFY2(QQuickTest::initView(window, testFileUrl(qmlFile.toLatin1().data()), true, &errorMessage), errorMessage.constData());
window.show();
QVERIFY(QTest::qWaitForWindowExposed(&window));
QVERIFY(window.rootObject() != nullptr);
QQuickItem *dragArea = window.rootObject()->findChild<QQuickItem*>("dragArea");
QVERIFY(dragArea);
QQuickItem *outerDropArea = window.rootObject()->findChild<QQuickItem*>("outerDropArea");
QVERIFY(outerDropArea);
QQuickItem *innerDropArea = window.rootObject()->findChild<QQuickItem*>("innerDropArea");
QVERIFY(innerDropArea);
QPoint p = QPoint(10,10);
QTest::mousePress(&window, Qt::LeftButton, Qt::NoModifier, p);
// move the minimum distance to activate drag
p += QPoint(dragThreshold + 1, dragThreshold + 1);
QTest::mouseMove(&window, p);
// drag the red rectangle into the inner DropArea
p += QPoint(100, 100);
QTest::mouseMove(&window, p);
QCOMPARE(window.rootObject()->property("outerEnterEvents"), 0);
QCOMPARE(window.rootObject()->property("outerExitEvents"), 0);
QCOMPARE(window.rootObject()->property("innerEnterEvents"), 1);
QCOMPARE(window.rootObject()->property("innerExitEvents"), 0);
// drag the red rectangle into the outer DropArea
p += QPoint(0, 50);
QTest::mouseMove(&window, p);
QCOMPARE(window.rootObject()->property("outerEnterEvents"), 1);
QCOMPARE(window.rootObject()->property("outerExitEvents"), 0);
QCOMPARE(window.rootObject()->property("innerEnterEvents"), 1);
QCOMPARE(window.rootObject()->property("innerExitEvents"), 1);
// drag the red rectangle into the inner DropArea
p -= QPoint(0, 50);
QTest::mouseMove(&window, p);
QCOMPARE(window.rootObject()->property("outerEnterEvents"), 1);
QCOMPARE(window.rootObject()->property("outerExitEvents"), 1);
QCOMPARE(window.rootObject()->property("innerEnterEvents"), 2);
QCOMPARE(window.rootObject()->property("innerExitEvents"), 1);
// drag the red rectangle back out of both
p -= QPoint(100, 100);
QTest::mouseMove(&window, p);
QCOMPARE(window.rootObject()->property("outerEnterEvents"), 1);
QCOMPARE(window.rootObject()->property("outerExitEvents"), 1);
QCOMPARE(window.rootObject()->property("innerEnterEvents"), 2);
QCOMPARE(window.rootObject()->property("innerExitEvents"), 2);
}
QTEST_MAIN(tst_QQuickDropArea)
#include "tst_qquickdroparea.moc"

View File

@ -432,6 +432,7 @@ private slots:
void asynchronousCancel();
void invalidContext();
void externalManagedModel();
void delegateModelChangeDelegate();
private:
template <int N> void groups_verify(
@ -4302,6 +4303,45 @@ void tst_qquickvisualdatamodel::externalManagedModel()
QTRY_VERIFY(!object->property("running").toBool());
}
void tst_qquickvisualdatamodel::delegateModelChangeDelegate()
{
// Verify that QTBUG-63477 is fixed.
// Changing the delegate would not update existing items.
QQmlEngine engine;
QScopedPointer<QQmlContext> context(new QQmlContext(engine.rootContext()));
QQmlComponent c(&engine);
c.setData("import QtQml.Models 2.2\nDelegateModel {}\n", QUrl());
QCOMPARE(c.status(), QQmlComponent::Ready);
QQmlDelegateModel *visualModel = qobject_cast<QQmlDelegateModel*>(c.create(context.data()));
QVERIFY(visualModel);
visualModel->setModel(QVariant(3));
QQmlComponent first(&engine);
first.setData("import QtQuick 2.0\nItem { objectName: \"old\" }\n", QUrl());
QCOMPARE(first.status(), QQmlComponent::Ready);
// Without delegate, claim to have an item count of 0
QCOMPARE(visualModel->count(), 0);
visualModel->setDelegate(&first);
// The first delegate has been set, verify we get it
QObject* old = visualModel->object(0, QQmlIncubator::Synchronous);
QVERIFY(old);
QCOMPARE(visualModel->object(0, QQmlIncubator::Synchronous)->objectName(), QStringLiteral("old"));
QCOMPARE(visualModel->count(), 3);
QQmlComponent second(&engine);
second.setData("import QtQuick 2.0\nItem { objectName: \"new\" }\n", QUrl());
QCOMPARE(second.status(), QQmlComponent::Ready);
visualModel->setDelegate(&second);
// After changing the delegate, expect the existing item to have the new delegate
QCOMPARE(visualModel->object(0, QQmlIncubator::Synchronous)->objectName(), QStringLiteral("new"));
QCOMPARE(visualModel->count(), 3);
}
QTEST_MAIN(tst_qquickvisualdatamodel)
#include "tst_qquickvisualdatamodel.moc"

View File

@ -0,0 +1,47 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** 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 https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.9
import QtQuick.Window 2.2
Window {
id: root
visible: true
width: 200
height: 200
property bool received: false
Item {
focus: true
Shortcut {
sequence: "B"
onActivated: {
root.received = true
}
}
}
}

View File

@ -482,6 +482,10 @@ private slots:
void testChildMouseEventFilter_data();
void cleanupGrabsOnRelease();
#if QT_CONFIG(shortcut)
void testShortCut();
#endif
private:
QTouchDevice *touchDevice;
QTouchDevice *touchDeviceWithVelocity;
@ -3579,6 +3583,30 @@ void tst_qquickwindow::cleanupGrabsOnRelease()
QCOMPARE(parent->mouseUngrabEventCount, 1);
}
#if QT_CONFIG(shortcut)
void tst_qquickwindow::testShortCut()
{
QQmlEngine engine;
QQmlComponent component(&engine);
component.loadUrl(testFileUrl("shortcut.qml"));
QObject *created = component.create();
QScopedPointer<QObject> cleanup(created);
QVERIFY(created);
QQuickWindow *window = qobject_cast<QQuickWindow *>(created);
QVERIFY(QTest::qWaitForWindowActive(window));
EventFilter eventFilter;
window->activeFocusItem()->installEventFilter(&eventFilter);
//Send non-spontaneous key press event
QKeyEvent keyEvent(QEvent::KeyPress, Qt::Key_B, Qt::NoModifier);
QCoreApplication::sendEvent(window, &keyEvent);
QVERIFY(eventFilter.events.contains(int(QEvent::ShortcutOverride)));
QVERIFY(window->property("received").value<bool>());
}
#endif
QTEST_MAIN(tst_qquickwindow)
#include "tst_qquickwindow.moc"

View File

@ -302,7 +302,7 @@ void QmlProfilerApplication::flush()
{
if (m_recording) {
m_pendingRequest = REQUEST_FLUSH;
m_qmlProfilerClient->sendRecordingStatus(false);
m_qmlProfilerClient->setRecording(false);
} else {
if (m_profilerData->save(m_interactiveOutputFile)) {
m_profilerData->clear();
@ -392,7 +392,7 @@ void QmlProfilerApplication::userCommand(const QString &command)
if (cmd == Constants::CMD_RECORD || cmd == Constants::CMD_RECORD2) {
m_pendingRequest = REQUEST_TOGGLE_RECORDING;
m_qmlProfilerClient->sendRecordingStatus(!m_recording);
m_qmlProfilerClient->setRecording(!m_recording);
} else if (cmd == Constants::CMD_QUIT || cmd == Constants::CMD_QUIT2) {
m_pendingRequest = REQUEST_QUIT;
if (m_recording) {

View File

@ -101,7 +101,6 @@ QmlProfilerData::~QmlProfilerData()
void QmlProfilerData::clear()
{
d->eventTypes.clear();
d->events.clear();
d->traceEndTime = std::numeric_limits<qint64>::min();