Merge "Merge remote-tracking branch 'origin/5.15' into dev"

This commit is contained in:
Qt Forward Merge Bot 2020-01-20 01:00:27 +01:00 committed by Fabian Kosmale
commit 649e6b762d
85 changed files with 1202 additions and 336 deletions

View File

@ -271,7 +271,7 @@ QQmlTableModel::ColumnRoleMetadata QQmlTableModel::fetchColumnRoleData(const QSt
if (columnRoleGetter.isString()) {
// The role is set as a string, so we assume the row is a simple object.
if (firstRow.type() != QVariant::Map) {
if (firstRow.userType() != QMetaType::QVariantMap) {
qmlWarning(this).quote() << "expected row for role "
<< roleNameKey << " of TableModelColumn at index "
<< columnIndex << " to be a simple object, but it's "
@ -284,7 +284,7 @@ QQmlTableModel::ColumnRoleMetadata QQmlTableModel::fetchColumnRoleData(const QSt
roleData.isStringRole = true;
roleData.name = rolePropertyName;
roleData.type = roleProperty.type();
roleData.type = roleProperty.userType();
roleData.typeName = QString::fromLatin1(roleProperty.typeName());
} else if (columnRoleGetter.isCallable()) {
// The role is provided via a function, which means the row is complex and
@ -296,7 +296,7 @@ QQmlTableModel::ColumnRoleMetadata QQmlTableModel::fetchColumnRoleData(const QSt
// We don't know the property name since it's provided through the function.
// roleData.name = ???
roleData.isStringRole = false;
roleData.type = cellData.type();
roleData.type = cellData.userType();
roleData.typeName = QString::fromLatin1(cellData.typeName());
} else {
// Invalid role.
@ -326,7 +326,7 @@ void QQmlTableModel::fetchColumnMetadata()
for (const int builtInRoleKey : builtInRoleKeys) {
const QString builtInRoleName = supportedRoleNames.value(builtInRoleKey);
ColumnRoleMetadata roleData = fetchColumnRoleData(builtInRoleName, column, columnIndex);
if (roleData.type == QVariant::Invalid) {
if (roleData.type == QMetaType::UnknownType) {
// This built-in role was not specified in this column.
continue;
}
@ -847,7 +847,7 @@ bool QQmlTableModel::setData(const QModelIndex &index, const QVariant &value, in
// If the value set is not of the expected type, we can try to convert it automatically.
const ColumnRoleMetadata roleData = columnMetadata.roles.value(roleName);
QVariant effectiveValue = value;
if (value.type() != roleData.type) {
if (value.userType() != roleData.type) {
if (!value.canConvert(int(roleData.type))) {
qmlWarning(this).nospace() << "setData(): the value " << value
<< " set at row " << row << " column " << column << " with role " << roleName
@ -933,7 +933,7 @@ QQmlTableModel::ColumnRoleMetadata::ColumnRoleMetadata()
}
QQmlTableModel::ColumnRoleMetadata::ColumnRoleMetadata(
bool isStringRole, const QString &name, QVariant::Type type, const QString &typeName) :
bool isStringRole, const QString &name, int type, const QString &typeName) :
isStringRole(isStringRole),
name(name),
type(type),
@ -995,7 +995,7 @@ bool QQmlTableModel::validateNewRow(const char *functionName, const QVariant &ro
const QVariant rowAsVariant = operation == SetRowsOperation
? row : row.value<QJSValue>().toVariant();
if (rowAsVariant.type() != QVariant::Map) {
if (rowAsVariant.userType() != QMetaType::QVariantMap) {
qmlWarning(this) << functionName << ": row manipulation functions "
<< "do not support complex rows (row index: " << rowIndex << ")";
return false;
@ -1028,7 +1028,7 @@ bool QQmlTableModel::validateNewRow(const char *functionName, const QVariant &ro
}
const QVariant rolePropertyValue = rowAsMap.value(roleData.name);
if (rolePropertyValue.type() != roleData.type) {
if (rolePropertyValue.userType() != roleData.type) {
qmlWarning(this).quote() << functionName << ": expected the property named "
<< roleData.name << " to be of type " << roleData.typeName
<< ", but got " << QString::fromLatin1(rolePropertyValue.typeName()) << " instead";

View File

@ -116,14 +116,14 @@ private:
{
public:
ColumnRoleMetadata();
ColumnRoleMetadata(bool isStringRole, const QString &name, QVariant::Type type, const QString &typeName);
ColumnRoleMetadata(bool isStringRole, const QString &name, int type, const QString &typeName);
bool isValid() const;
// If this is false, it's a function role.
bool isStringRole = false;
QString name;
QVariant::Type type = QVariant::Invalid;
int type = QMetaType::UnknownType;
QString typeName;
};

View File

@ -335,7 +335,7 @@ void QQmlSettingsPrivate::load()
const QVariant currentValue = instance()->value(property.name(), previousValue);
if (!currentValue.isNull() && (!previousValue.isValid()
|| (currentValue.canConvert(previousValue.type()) && previousValue != currentValue))) {
|| (currentValue.canConvert(previousValue.userType()) && previousValue != currentValue))) {
property.write(q, currentValue);
qCDebug(lcSettings) << "QQmlSettings: load" << property.name() << "setting:" << currentValue << "default:" << previousValue;
}

View File

@ -125,7 +125,7 @@ bool QuickTestEvent::keyClickChar(const QString &character, int modifiers, int d
// valueToKeySequence() is copied from qquickshortcut.cpp
static QKeySequence valueToKeySequence(const QVariant &value)
{
if (value.type() == QVariant::Int)
if (value.userType() == QMetaType::Int)
return QKeySequence(static_cast<QKeySequence::StandardKey>(value.toInt()));
return QKeySequence::fromString(value.toString());
}

View File

@ -56,7 +56,7 @@ QQuickCumulativeDirection::QQuickCumulativeDirection(QObject *parent):QQuickDire
QQmlListProperty<QQuickDirection> QQuickCumulativeDirection::directions()
{
return QQmlListProperty<QQuickDirection>(this, m_directions);//TODO: Proper list property
return QQmlListProperty<QQuickDirection>(this, &m_directions);//TODO: Proper list property
}
QPointF QQuickCumulativeDirection::sample(const QPointF &from)

View File

@ -96,7 +96,7 @@ static bool isSaveable(const QVariant &value)
{
NullDevice nullDevice;
QDataStream fakeStream(&nullDevice);
return QMetaType::save(fakeStream, static_cast<int>(value.type()), value.constData());
return QMetaType::save(fakeStream, static_cast<int>(value.userType()), value.constData());
}
QQmlEngineDebugServiceImpl::QQmlEngineDebugServiceImpl(QObject *parent) :
@ -217,7 +217,7 @@ QVariant QQmlEngineDebugServiceImpl::valueContents(QVariant value) const
//QObject * is not streamable.
//Convert all such instances to a String value
if (value.type() == QVariant::List) {
if (value.userType() == QMetaType::QVariantList) {
QVariantList contents;
QVariantList list = value.toList();
int count = list.size();
@ -227,7 +227,7 @@ QVariant QQmlEngineDebugServiceImpl::valueContents(QVariant value) const
return contents;
}
if (value.type() == QVariant::Map) {
if (value.userType() == QMetaType::QVariantMap) {
QVariantMap contents;
const auto map = value.toMap();
for (auto i = map.cbegin(), end = map.cend(); i != end; ++i)

View File

@ -314,7 +314,7 @@ bool QJSValue::isBool() const
if (val)
return val->isBoolean();
QVariant *variant = QJSValuePrivate::getVariant(this);
return variant && variant->type() == QVariant::Bool;
return variant && variant->userType() == QMetaType::Bool;
}
/*!
@ -520,9 +520,9 @@ QString QJSValue::toString() const
if (!val) {
QVariant *variant = QJSValuePrivate::getVariant(this);
Q_ASSERT(variant);
if (variant->type() == QVariant::Map)
if (variant->userType() == QMetaType::QVariantMap)
return QStringLiteral("[object Object]");
else if (variant->type() == QVariant::List) {
else if (variant->userType() == QMetaType::QVariantList) {
const QVariantList list = variant->toList();
QString result;
for (int i = 0; i < list.count(); ++i) {
@ -558,7 +558,7 @@ double QJSValue::toNumber() const
QVariant *variant = QJSValuePrivate::getVariant(this);
Q_ASSERT(variant);
if (variant->type() == QVariant::String)
if (variant->userType() == QMetaType::QString)
return RuntimeHelpers::stringToNumber(variant->toString());
else if (variant->canConvert<double>())
return variant->value<double>();
@ -1040,7 +1040,7 @@ bool QJSValue::equals(const QJSValue& other) const
Q_ASSERT(variant);
if (!ov)
return *variant == *QJSValuePrivate::getVariant(&other);
if (variant->type() == QVariant::Map || variant->type() == QVariant::List)
if (variant->userType() == QMetaType::QVariantMap || variant->userType() == QMetaType::QVariantList)
return false;
return js_equal(variant->toString(), *ov);
}
@ -1083,7 +1083,7 @@ bool QJSValue::strictlyEquals(const QJSValue& other) const
Q_ASSERT(variant);
if (!ov)
return *variant == *QJSValuePrivate::getVariant(&other);
if (variant->type() == QVariant::Map || variant->type() == QVariant::List)
if (variant->userType() == QMetaType::QVariantMap || variant->userType() == QMetaType::QVariantList)
return false;
if (String *s = ov->stringValue())
return variant->toString() == s->toQString();

View File

@ -1461,7 +1461,7 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
if (const QV4::VariantObject *v = value.as<QV4::VariantObject>())
return v->d()->data();
if (typeHint == QVariant::Bool)
if (typeHint == QMetaType::Bool)
return QVariant(value.toBoolean());
if (typeHint == QMetaType::QJsonValue)
@ -1533,7 +1533,7 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
if (String *s = value.stringValue()) {
const QString &str = s->toQString();
// QChars are stored as a strings
if (typeHint == QVariant::Char && str.size() == 1)
if (typeHint == QMetaType::QChar && str.size() == 1)
return str.at(0);
return str;
}
@ -1832,7 +1832,7 @@ QV4::ReturnedValue ExecutionEngine::metaTypeToJS(int type, const void *data)
Q_ASSERT(data != nullptr);
QVariant variant(type, data);
if (QMetaType::Type(variant.type()) == QMetaType::QVariant) {
if (QMetaType::Type(variant.userType()) == QMetaType::QVariant) {
// unwrap it: this is tested in QJSEngine, and makes the most sense for
// end-user code too.
return variantToJS(this, *reinterpret_cast<const QVariant*>(data));

View File

@ -163,7 +163,7 @@ void QV4Include::finished()
QV4::Scope scope(v4);
QV4::ScopedObject resultObj(scope, m_resultObject.value());
QV4::ScopedString status(scope, v4->newString(QStringLiteral("status")));
if (m_reply->error() == QNetworkReply::NoError) {
if (m_reply->networkError() == QNetworkReply::NoError) {
QByteArray data = m_reply->readAll();
QString code = QString::fromUtf8(data);

View File

@ -1654,7 +1654,7 @@ static QV4::ReturnedValue CallOverloaded(const QQmlObjectOrGadget &object, const
}
CallArgument::CallArgument()
: type(QVariant::Invalid)
: type(QMetaType::UnknownType)
{
}

View File

@ -65,8 +65,8 @@ void Heap::VariantObject::init(const QVariant &value)
bool VariantObject::Data::isScarce() const
{
QVariant::Type t = data().type();
return t == QVariant::Pixmap || t == QVariant::Image;
int t = data().userType();
return t == QMetaType::QPixmap || t == QMetaType::QImage;
}
bool VariantObject::virtualIsEqualTo(Managed *m, Managed *other)
@ -139,7 +139,7 @@ ReturnedValue VariantPrototype::method_toString(const FunctionObject *b, const V
RETURN_UNDEFINED();
const QVariant variant = o->d()->data();
QString result = variant.toString();
if (result.isEmpty() && !variant.canConvert(QVariant::String)) {
if (result.isEmpty() && !variant.canConvert(QMetaType::QString)) {
QDebug dbg(&result);
dbg << variant;
// QDebug appends a space, we're not interested in continuing the stream so we chop it off.
@ -154,17 +154,17 @@ ReturnedValue VariantPrototype::method_valueOf(const FunctionObject *b, const Va
const VariantObject *o = thisObject->as<QV4::VariantObject>();
if (o) {
QVariant v = o->d()->data();
switch (v.type()) {
case QVariant::Invalid:
switch (v.userType()) {
case QMetaType::UnknownType:
return Encode::undefined();
case QVariant::String:
case QMetaType::QString:
return Encode(b->engine()->newString(v.toString()));
case QVariant::Int:
case QMetaType::Int:
return Encode(v.toInt());
case QVariant::Double:
case QVariant::UInt:
case QMetaType::Double:
case QMetaType::UInt:
return Encode(v.toDouble());
case QVariant::Bool:
case QMetaType::Bool:
return Encode(v.toBool());
default:
if (QMetaType::typeFlags(v.userType()) & QMetaType::IsEnumeration)

View File

@ -102,6 +102,25 @@ QHashedStringRef QHashedStringRef::mid(int offset, int length) const
(length == -1 || (offset + length) > m_length)?(m_length - offset):length);
}
QVector<QHashedStringRef> QHashedStringRef::split(const QChar sep) const
{
QVector<QHashedStringRef> ret;
auto curLength = 0;
auto curOffset = m_data;
for (int offset = 0; offset < m_length; ++offset) {
if (*(m_data + offset) == sep) {
ret.push_back({curOffset, curLength});
curOffset = m_data + offset + 1;
curLength = 0;
} else {
++curLength;
}
}
if (curLength > 0)
ret.push_back({curOffset, curLength});
return ret;
}
bool QHashedStringRef::endsWith(const QString &s) const
{
return s.length() < m_length &&

View File

@ -125,6 +125,7 @@ public:
bool endsWith(const QString &) const;
int indexOf(const QChar &, int from=0) const;
QHashedStringRef mid(int, int) const;
QVector<QHashedStringRef> split(const QChar sep) const;
inline bool isEmpty() const;
inline int length() const;

View File

@ -479,7 +479,7 @@ Q_NEVER_INLINE bool QQmlBinding::slowWrite(const QQmlPropertyData &core,
if (!propertyMetaObject.isNull())
propertyType = propertyMetaObject.className();
}
} else if (userType != QVariant::Invalid) {
} else if (userType != QMetaType::UnknownType) {
if (userType == QMetaType::Nullptr || userType == QMetaType::VoidStar)
valueType = "null";
else

View File

@ -101,8 +101,6 @@
# endif
#endif // Q_OS_WIN
Q_DECLARE_METATYPE(QQmlProperty)
QT_BEGIN_NAMESPACE
// Declared in qqml.h

View File

@ -187,7 +187,7 @@ void QQmlFileNetworkReply::networkFinished()
}
}
if (m_reply->error()) {
if (m_reply->networkError()) {
m_p->errorString = m_reply->errorString();
m_p->error = QQmlFilePrivate::Network;
} else {

View File

@ -250,10 +250,37 @@ bool QQmlListReference::canCount() const
}
/*!
Return true if at(), count(), append() and clear() are implemented, so you can manipulate
the list.
Returns true if items in the list property can be replaced, otherwise false.
Returns false if the reference is invalid.
\sa isReadable(), at(), count(), append(), clear()
\sa replace()
*/
bool QQmlListReference::canReplace() const
{
return (isValid() && d->property.replace);
}
/*!
Returns true if the last item can be removed from the list property, otherwise false.
Returns false if the reference is invalid.
\sa removeLast()
*/
bool QQmlListReference::canRemoveLast() const
{
return (isValid() && d->property.removeLast);
}
/*!
Return true if at(), count(), append(), and either clear() or removeLast()
are implemented, so you can manipulate the list.
Mind that replace() and removeLast() can be emulated by stashing all
items and rebuilding the list using clear() and append(). Therefore,
they are not required for the list to be manipulable. Furthermore,
clear() can be emulated using removeLast().
\sa isReadable(), at(), count(), append(), clear(), replace(), removeLast()
*/
bool QQmlListReference::isManipulable() const
{
@ -328,6 +355,39 @@ int QQmlListReference::count() const
return d->property.count(&d->property);
}
/*!
Replaces the item at \a index in the list with \a object.
Returns true if the operation succeeded, otherwise false.
\sa canReplace()
*/
bool QQmlListReference::replace(int index, QObject *object) const
{
if (!canReplace())
return false;
if (object && !QQmlMetaObject::canConvert(object, d->elementType))
return false;
d->property.replace(&d->property, index, object);
return true;
}
/*!
Removes the last item in the list.
Returns true if the operation succeeded, otherwise false.
\sa canRemoveLast()
*/
bool QQmlListReference::removeLast() const
{
if (!canRemoveLast())
return false;
d->property.removeLast(&d->property);
return true;
}
/*!
\class QQmlListProperty
\since 5.0
@ -375,14 +435,25 @@ QML list properties are type-safe - in this case \c {Fruit} is a QObject type th
/*!
\fn template<typename T> QQmlListProperty<T>::QQmlListProperty(QObject *object, QList<T *> &list)
\deprecated
Convenience constructor for making a QQmlListProperty value from an existing
QList \a list. The \a list reference must remain valid for as long as \a object
exists. \a object must be provided.
Generally this constructor should not be used in production code, as a
writable QList violates QML's memory management rules. However, this constructor
can be very useful while prototyping.
This constructor synthesizes the removeLast() and replace() methods
introduced in Qt 5.15, using count(), at(), clear(), and append(). This is slow.
If you intend to manipulate the list beyond clearing it, you should explicitly
provide these methods.
*/
/*!
\fn template<typename T> QQmlListProperty<T>::QQmlListProperty(QObject *object, QList<T *> *list)
\since 5.15
Convenience constructor for making a QQmlListProperty value from an existing
QList \a list. The \a list reference must remain valid for as long as \a object
exists. \a object must be provided.
*/
/*!
@ -408,6 +479,39 @@ remains valid while \a object exists.
Null pointers can be passed for any function. If any null pointers are passed in, the list
will be neither designable nor alterable by the debugger. It is recommended to provide valid
pointers for all functions.
\note The resulting QQmlListProperty will synthesize the removeLast() and
replace() methods using \a count, \a at, \a clear, and \a append if all of those
are given. This is slow. If you intend to manipulate the list beyond clearing it,
you should explicitly provide these methods.
*/
/*!
\fn template<typename T> QQmlListProperty<T>::QQmlListProperty(
QObject *object, void *data, AppendFunction append, CountFunction count,
AtFunction at, ClearFunction clear, ReplaceFunction replace,
RemoveLastFunction removeLast)
Construct a QQmlListProperty from a set of operation functions \a append,
\a count, \a at, \a clear, \a replace, and \removeLast. An opaque \a data handle
may be passed which can be accessed from within the operation functions. The
list property remains valid while \a object exists.
Null pointers can be passed for any function, causing the respective function to
be synthesized using the others, if possible. QQmlListProperty can synthesize
\list
\li \a clear using \a count and \a removeLast
\li \a replace using \a count, \a at, \a clear, and \a append
\li \a replace using \a count, \a at, \a removeLast, and \a append
\li \a removeLast using \a count, \a at, \a clear, and \a append
\endlist
if those are given. This is slow, but if your list does not natively provide
faster options for these primitives, you may want to use the synthesized ones.
Furthermore, if either of \a count, \a at, \a append, and \a clear are neither
given explicitly nor synthesized, the list will be neither designable nor
alterable by the debugger. It is recommended to provide enough valid pointers
to avoid this situation.
*/
/*!
@ -448,4 +552,20 @@ Synonym for \c {void (*)(QQmlListProperty<T> *property)}.
Clear the list \a property.
*/
/*!
\typedef QQmlListProperty::ReplaceFunction
Synonym for \c {void (*)(QQmlListProperty<T> *property, int index, T *value)}.
Replace the element at position \a index in the list \a property with \a value.
*/
/*!
\typedef QQmlListProperty::RemoveLastFunction
Synonym for \c {void (*)(QQmlListProperty<T> *property)}.
Remove the last element from the list \a property.
*/
QT_END_NAMESPACE

View File

@ -55,22 +55,28 @@ struct QMetaObject;
template<typename T>
class QQmlListProperty {
public:
typedef void (*AppendFunction)(QQmlListProperty<T> *, T*);
typedef int (*CountFunction)(QQmlListProperty<T> *);
typedef T *(*AtFunction)(QQmlListProperty<T> *, int);
typedef void (*ClearFunction)(QQmlListProperty<T> *);
using AppendFunction = void (*)(QQmlListProperty<T> *, T *);
using CountFunction = int (*)(QQmlListProperty<T> *);
using AtFunction = T *(*)(QQmlListProperty<T> *, int);
using ClearFunction = void (*)(QQmlListProperty<T> *);
using ReplaceFunction = void (*)(QQmlListProperty<T> *, int, T *);
using RemoveLastFunction = void (*)(QQmlListProperty<T> *);
QQmlListProperty()
: append(nullptr),
count(nullptr),
at(nullptr),
clear(nullptr)
{}
QQmlListProperty() = default;
#if QT_DEPRECATED_SINCE(5,15)
QT_DEPRECATED_X("Use constructor taking QList pointer, and gain improved performance")
QQmlListProperty(QObject *o, QList<T *> &list)
: object(o), data(&list), append(qlist_append), count(qlist_count), at(qlist_at),
clear(qlist_clear)
clear(qlist_clear), replace(qslow_replace), removeLast(qslow_removeLast)
{}
#endif
QQmlListProperty(QObject *o, QList<T *> *list)
: object(o), data(list), append(qlist_append), count(qlist_count), at(qlist_at),
clear(qlist_clear), replace(qlist_replace), removeLast(qlist_removeLast)
{}
QQmlListProperty(QObject *o, void *d, AppendFunction a, CountFunction c, AtFunction t,
ClearFunction r )
: object(o),
@ -78,37 +84,47 @@ public:
append(a),
count(c),
at(t),
clear(r)
clear(r),
replace((a && c && t && r) ? qslow_replace : nullptr),
removeLast((a && c && t && r) ? qslow_removeLast : nullptr)
{}
QQmlListProperty(QObject *o, void *d, CountFunction c, AtFunction t)
QQmlListProperty(QObject *o, void *d, AppendFunction a, CountFunction c, AtFunction t,
ClearFunction r, ReplaceFunction s, RemoveLastFunction p)
: object(o),
data(d),
append(nullptr),
count(c), at(t),
clear(nullptr)
append(a),
count(c),
at(t),
clear((!r && p && c) ? qslow_clear : r),
replace((!s && a && c && t && (r || p)) ? qslow_replace : s),
removeLast((!p && a && c && t && r) ? qslow_removeLast : p)
{}
QQmlListProperty(QObject *o, void *d, CountFunction c, AtFunction a)
: object(o), data(d), count(c), at(a)
{}
bool operator==(const QQmlListProperty &o) const {
return object == o.object &&
data == o.data &&
append == o.append &&
count == o.count &&
at == o.at &&
clear == o.clear;
clear == o.clear &&
replace == o.replace &&
removeLast == o.removeLast;
}
QObject *object = nullptr;
void *data = nullptr;
AppendFunction append;
CountFunction count;
AtFunction at;
ClearFunction clear;
void *dummy1 = nullptr;
void *dummy2 = nullptr;
AppendFunction append = nullptr;
CountFunction count = nullptr;
AtFunction at = nullptr;
ClearFunction clear = nullptr;
ReplaceFunction replace = nullptr;
RemoveLastFunction removeLast = nullptr;
private:
static void qlist_append(QQmlListProperty *p, T *v) {
@ -123,6 +139,59 @@ private:
static void qlist_clear(QQmlListProperty *p) {
return reinterpret_cast<QList<T *> *>(p->data)->clear();
}
static void qlist_replace(QQmlListProperty *p, int idx, T *v) {
return reinterpret_cast<QList<T *> *>(p->data)->replace(idx, v);
}
static void qlist_removeLast(QQmlListProperty *p) {
return reinterpret_cast<QList<T *> *>(p->data)->removeLast();
}
static void qslow_replace(QQmlListProperty<T> *list, int idx, T *v)
{
const int length = list->count(list);
if (idx < 0 || idx >= length)
return;
QVector<T *> stash;
if (list->clear != qslow_clear) {
stash.reserve(length);
for (int i = 0; i < length; ++i)
stash.append(i == idx ? v : list->at(list, i));
list->clear(list);
for (T *item : qAsConst(stash))
list->append(list, item);
} else {
stash.reserve(length - idx - 1);
for (int i = length - 1; i > idx; --i) {
stash.append(list->at(list, i));
list->removeLast(list);
}
list->removeLast(list);
list->append(list, v);
while (!stash.isEmpty())
list->append(list, stash.takeLast());
}
}
static void qslow_clear(QQmlListProperty<T> *list)
{
for (int i = 0, end = list->count(list); i < end; ++i)
list->removeLast(list);
}
static void qslow_removeLast(QQmlListProperty<T> *list)
{
const int length = list->count(list) - 1;
if (length < 0)
return;
QVector<T *> stash;
stash.reserve(length);
for (int i = 0; i < length; ++i)
stash.append(list->at(list, i));
list->clear(list);
for (T *item : qAsConst(stash))
list->append(list, item);
}
};
#endif
@ -146,6 +215,8 @@ public:
bool canAt() const;
bool canClear() const;
bool canCount() const;
bool canReplace() const;
bool canRemoveLast() const;
bool isManipulable() const;
bool isReadable() const;
@ -154,6 +225,8 @@ public:
QObject *at(int) const;
bool clear() const;
int count() const;
bool replace(int, QObject *) const;
bool removeLast() const;
private:
friend class QQmlListReferencePrivate;

View File

@ -119,11 +119,13 @@ ReturnedValue QmlListWrapper::virtualGet(const Managed *m, PropertyKey id, const
if (hasProperty)
*hasProperty = false;
return Value::undefinedValue().asReturnedValue();
} else if (id.isString()) {
if (id == v4->id_length()->propertyKey() && !w->d()->object.isNull()) {
quint32 count = w->d()->property().count ? w->d()->property().count(&w->d()->property()) : 0;
return Value::fromUInt32(count).asReturnedValue();
}
}
if (id.isString() && id == v4->id_length()->propertyKey()) {
if (hasProperty)
*hasProperty = true;
quint32 count = w->d()->property().count ? w->d()->property().count(&w->d()->property()) : 0;
return Value::fromUInt32(count).asReturnedValue();
}
return Object::virtualGet(m, id, receiver, hasProperty);
@ -131,12 +133,70 @@ ReturnedValue QmlListWrapper::virtualGet(const Managed *m, PropertyKey id, const
bool QmlListWrapper::virtualPut(Managed *m, PropertyKey id, const Value &value, Value *receiver)
{
// doesn't do anything. Should we throw?
Q_UNUSED(m);
Q_UNUSED(id);
Q_UNUSED(value);
Q_UNUSED(receiver);
return false;
Q_ASSERT(m->as<QmlListWrapper>());
const auto *w = static_cast<const QmlListWrapper *>(m);
QV4::ExecutionEngine *v4 = w->engine();
QQmlListProperty<QObject> *prop = &(w->d()->property());
if (id.isArrayIndex()) {
if (!prop->count || !prop->replace)
return false;
const uint index = id.asArrayIndex();
const int count = prop->count(prop);
if (count < 0 || index >= uint(count))
return false;
QV4::Scope scope(v4);
QV4::ScopedObject so(scope, value.toObject(scope.engine));
if (auto *wrapper = so->as<QV4::QObjectWrapper>()) {
prop->replace(prop, index, wrapper->object());
return true;
}
return false;
}
if (id.isString() && id == v4->id_length()->propertyKey()) {
if (!prop->count)
return false;
const quint32 count = prop->count(prop);
bool ok = false;
const uint newLength = value.asArrayLength(&ok);
if (!ok)
return false;
if (newLength == 0) {
if (!prop->clear)
return false;
prop->clear(prop);
return true;
}
if (newLength < count) {
if (!prop->removeLast)
return false;
for (uint i = newLength; i < count; ++i)
prop->removeLast(prop);
return true;
}
if (!prop->append)
return false;
for (uint i = count; i < newLength; ++i)
prop->append(prop, nullptr);
return true;
}
return Object::virtualPut(m, id, value, receiver);
}
struct QmlListWrapperOwnPropertyKeyIterator : ObjectOwnPropertyKeyIterator

View File

@ -414,25 +414,25 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
}
}
break;
case QVariant::String: {
case QMetaType::QString: {
assertOrNull(binding->evaluatesToString());
QString value = compilationUnit->bindingValueAsString(binding);
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
case QVariant::StringList: {
case QMetaType::QStringList: {
assertOrNull(binding->evaluatesToString());
QStringList value(compilationUnit->bindingValueAsString(binding));
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
case QVariant::ByteArray: {
case QMetaType::QByteArray: {
assertType(QV4::CompiledData::Binding::Type_String);
QByteArray value(compilationUnit->bindingValueAsString(binding).toUtf8());
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
case QVariant::Url: {
case QMetaType::QUrl: {
assertType(QV4::CompiledData::Binding::Type_String);
QString string = compilationUnit->bindingValueAsString(binding);
// Encoded dir-separators defeat QUrl processing - decode them first
@ -444,7 +444,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
case QVariant::UInt: {
case QMetaType::UInt: {
assertType(QV4::CompiledData::Binding::Type_Number);
double d = compilationUnit->bindingValueAsNumber(binding);
uint value = uint(d);
@ -452,7 +452,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
break;
}
break;
case QVariant::Int: {
case QMetaType::Int: {
assertType(QV4::CompiledData::Binding::Type_Number);
double d = compilationUnit->bindingValueAsNumber(binding);
int value = int(d);
@ -466,13 +466,13 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
case QVariant::Double: {
case QMetaType::Double: {
assertType(QV4::CompiledData::Binding::Type_Number);
double value = compilationUnit->bindingValueAsNumber(binding);
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
case QVariant::Color: {
case QMetaType::QColor: {
bool ok = false;
uint colorValue = QQmlStringConverters::rgbaFromString(compilationUnit->bindingValueAsString(binding), &ok);
assertOrNull(ok);
@ -483,21 +483,21 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
}
break;
#if QT_CONFIG(datestring)
case QVariant::Date: {
case QMetaType::QDate: {
bool ok = false;
QDate value = QQmlStringConverters::dateFromString(compilationUnit->bindingValueAsString(binding), &ok);
assertOrNull(ok);
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
case QVariant::Time: {
case QMetaType::QTime: {
bool ok = false;
QTime value = QQmlStringConverters::timeFromString(compilationUnit->bindingValueAsString(binding), &ok);
assertOrNull(ok);
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
case QVariant::DateTime: {
case QMetaType::QDateTime: {
bool ok = false;
QDateTime value = QQmlStringConverters::dateTimeFromString(compilationUnit->bindingValueAsString(binding), &ok);
// ### VME compatibility :(
@ -511,55 +511,55 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
}
break;
#endif // datestring
case QVariant::Point: {
case QMetaType::QPoint: {
bool ok = false;
QPoint value = QQmlStringConverters::pointFFromString(compilationUnit->bindingValueAsString(binding), &ok).toPoint();
assertOrNull(ok);
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
case QVariant::PointF: {
case QMetaType::QPointF: {
bool ok = false;
QPointF value = QQmlStringConverters::pointFFromString(compilationUnit->bindingValueAsString(binding), &ok);
assertOrNull(ok);
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
case QVariant::Size: {
case QMetaType::QSize: {
bool ok = false;
QSize value = QQmlStringConverters::sizeFFromString(compilationUnit->bindingValueAsString(binding), &ok).toSize();
assertOrNull(ok);
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
case QVariant::SizeF: {
case QMetaType::QSizeF: {
bool ok = false;
QSizeF value = QQmlStringConverters::sizeFFromString(compilationUnit->bindingValueAsString(binding), &ok);
assertOrNull(ok);
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
case QVariant::Rect: {
case QMetaType::QRect: {
bool ok = false;
QRect value = QQmlStringConverters::rectFFromString(compilationUnit->bindingValueAsString(binding), &ok).toRect();
assertOrNull(ok);
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
case QVariant::RectF: {
case QMetaType::QRectF: {
bool ok = false;
QRectF value = QQmlStringConverters::rectFFromString(compilationUnit->bindingValueAsString(binding), &ok);
assertOrNull(ok);
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
case QVariant::Bool: {
case QMetaType::Bool: {
assertType(QV4::CompiledData::Binding::Type_Boolean);
bool value = binding->valueAsBoolean();
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
case QVariant::Vector2D: {
case QMetaType::QVector2D: {
struct {
float xp;
float yp;
@ -570,7 +570,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
property->writeProperty(_qobject, &vec, propertyWriteFlags);
}
break;
case QVariant::Vector3D: {
case QMetaType::QVector3D: {
struct {
float xp;
float yp;
@ -582,7 +582,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
property->writeProperty(_qobject, &vec, propertyWriteFlags);
}
break;
case QVariant::Vector4D: {
case QMetaType::QVector4D: {
struct {
float xp;
float yp;
@ -595,7 +595,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
property->writeProperty(_qobject, &vec, propertyWriteFlags);
}
break;
case QVariant::Quaternion: {
case QMetaType::QQuaternion: {
struct {
float wp;
float xp;
@ -608,7 +608,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
property->writeProperty(_qobject, &vec, propertyWriteFlags);
}
break;
case QVariant::RegExp:
case QMetaType::QRegExp:
assertOrNull(!"not possible");
break;
default: {
@ -673,7 +673,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
QVariant value = (*converter)(stringValue);
QMetaProperty metaProperty = _qobject->metaObject()->property(property->coreIndex());
if (value.isNull() || ((int)metaProperty.type() != property->propType() && metaProperty.userType() != property->propType())) {
if (value.isNull() || metaProperty.userType() != property->propType()) {
recordError(binding->location, tr("Cannot assign value %1 to property %2").arg(stringValue).arg(QString::fromUtf8(metaProperty.name())));
break;
}

View File

@ -471,7 +471,7 @@ QQmlPropertyPrivate::propertyTypeCategory() const
return QQmlProperty::Normal;
} else if (type & QQmlProperty::Property) {
int type = propertyType();
if (type == QVariant::Invalid)
if (type == QMetaType::UnknownType)
return QQmlProperty::InvalidCategory;
else if (QQmlValueTypeFactory::isValueType((uint)type))
return QQmlProperty::Normal;
@ -526,7 +526,7 @@ bool QQmlProperty::operator==(const QQmlProperty &other) const
*/
int QQmlProperty::propertyType() const
{
return d ? d->propertyType() : int(QVariant::Invalid);
return d ? d->propertyType() : int(QMetaType::UnknownType);
}
bool QQmlPropertyPrivate::isValueType() const
@ -542,7 +542,7 @@ int QQmlPropertyPrivate::propertyType() const
} else if (type & QQmlProperty::Property) {
return core.propType();
} else {
return QVariant::Invalid;
return QMetaType::UnknownType;
}
}
@ -1133,7 +1133,7 @@ bool QQmlPropertyPrivate::writeEnumProperty(const QMetaProperty &prop, int idx,
QVariant v = value;
if (prop.isEnumType()) {
QMetaEnum menum = prop.enumerator();
if (v.userType() == QVariant::String
if (v.userType() == QMetaType::QString
#ifdef QT3_SUPPORT
|| v.userType() == QVariant::CString
#endif
@ -1145,13 +1145,13 @@ bool QQmlPropertyPrivate::writeEnumProperty(const QMetaProperty &prop, int idx,
v = QVariant(menum.keyToValue(value.toByteArray(), &ok));
if (!ok)
return false;
} else if (v.userType() != QVariant::Int && v.userType() != QVariant::UInt) {
} else if (v.userType() != QMetaType::Int && v.userType() != QMetaType::UInt) {
int enumMetaTypeId = QMetaType::type(QByteArray(menum.scope() + QByteArray("::") + menum.name()));
if ((enumMetaTypeId == QMetaType::UnknownType) || (v.userType() != enumMetaTypeId) || !v.constData())
return false;
v = QVariant(*reinterpret_cast<const int *>(v.constData()));
}
v.convert(QVariant::Int);
v.convert(QMetaType::Int);
}
// the status variable is changed by qt_metacall to indicate what it did
@ -1206,17 +1206,17 @@ bool QQmlPropertyPrivate::write(QObject *object,
QMetaProperty prop = object->metaObject()->property(property.coreIndex());
QVariant v = value;
// Enum values come through the script engine as doubles
if (variantType == QVariant::Double) {
if (variantType == QMetaType::Double) {
double integral;
double fractional = std::modf(value.toDouble(), &integral);
if (qFuzzyIsNull(fractional))
v.convert(QVariant::Int);
v.convert(QMetaType::Int);
}
return writeEnumProperty(prop, property.coreIndex(), object, v, flags);
}
QQmlEnginePrivate *enginePriv = QQmlEnginePrivate::get(context);
const bool isUrl = propertyType == QVariant::Url; // handled separately
const bool isUrl = propertyType == QMetaType::QUrl; // handled separately
// The cases below are in approximate order of likelyhood:
if (propertyType == variantType && !isUrl && propertyType != qMetaTypeId<QList<QUrl>>() && !property.isQList()) {
@ -1249,7 +1249,7 @@ bool QQmlPropertyPrivate::write(QObject *object,
} else {
return false;
}
} else if (value.canConvert(propertyType) && !isUrl && variantType != QVariant::String && propertyType != qMetaTypeId<QList<QUrl>>() && !property.isQList()) {
} else if (value.canConvert(propertyType) && !isUrl && variantType != QMetaType::QString && propertyType != qMetaTypeId<QList<QUrl>>() && !property.isQList()) {
// common cases:
switch (propertyType) {
case QMetaType::Bool: {
@ -1282,14 +1282,14 @@ bool QQmlPropertyPrivate::write(QObject *object,
return property.writeProperty(object, const_cast<QVariant *>(&value), flags);
} else if (isUrl) {
QUrl u;
if (variantType == QVariant::Url) {
if (variantType == QMetaType::QUrl) {
u = value.toUrl();
} else if (variantType == QVariant::ByteArray) {
} else if (variantType == QMetaType::QByteArray) {
QString input(QString::fromUtf8(value.toByteArray()));
// Encoded dir-separators defeat QUrl processing - decode them first
input.replace(QLatin1String("%2f"), QLatin1String("/"), Qt::CaseInsensitive);
u = QUrl(input);
} else if (variantType == QVariant::String) {
} else if (variantType == QMetaType::QString) {
QString input(value.toString());
// Encoded dir-separators defeat QUrl processing - decode them first
input.replace(QLatin1String("%2f"), QLatin1String("/"), Qt::CaseInsensitive);
@ -1355,7 +1355,7 @@ bool QQmlPropertyPrivate::write(QObject *object,
bool ok = false;
QVariant v;
if (variantType == QVariant::String)
if (variantType == QMetaType::QString)
v = QQmlStringConverters::variantFromString(value.toString(), propertyType, &ok);
if (!ok) {
@ -1368,8 +1368,8 @@ bool QQmlPropertyPrivate::write(QObject *object,
// successful conversion.
Q_ASSERT(v.userType() == propertyType);
ok = true;
} else if (static_cast<uint>(propertyType) >= QVariant::UserType &&
variantType == QVariant::String) {
} else if (static_cast<uint>(propertyType) >= QMetaType::User &&
variantType == QMetaType::QString) {
QQmlMetaType::StringConverter con = QQmlMetaType::customStringConverter(propertyType);
if (con) {
v = con(value.toString());
@ -1383,28 +1383,28 @@ bool QQmlPropertyPrivate::write(QObject *object,
// to a sequence type property (eg, an int to a QList<int> property).
// or that we encountered an interface type
// Note that we've already handled single-value assignment to QList<QUrl> properties.
if (variantType == QVariant::Int && propertyType == qMetaTypeId<QList<int> >()) {
if (variantType == QMetaType::Int && propertyType == qMetaTypeId<QList<int> >()) {
QList<int> list;
list << value.toInt();
v = QVariant::fromValue<QList<int> >(list);
ok = true;
} else if ((variantType == QVariant::Double || variantType == QVariant::Int)
} else if ((variantType == QMetaType::Double || variantType == QMetaType::Int)
&& (propertyType == qMetaTypeId<QList<qreal> >())) {
QList<qreal> list;
list << value.toReal();
v = QVariant::fromValue<QList<qreal> >(list);
ok = true;
} else if (variantType == QVariant::Bool && propertyType == qMetaTypeId<QList<bool> >()) {
} else if (variantType == QMetaType::Bool && propertyType == qMetaTypeId<QList<bool> >()) {
QList<bool> list;
list << value.toBool();
v = QVariant::fromValue<QList<bool> >(list);
ok = true;
} else if (variantType == QVariant::String && propertyType == qMetaTypeId<QList<QString> >()) {
} else if (variantType == QMetaType::QString && propertyType == qMetaTypeId<QList<QString> >()) {
QList<QString> list;
list << value.toString();
v = QVariant::fromValue<QList<QString> >(list);
ok = true;
} else if (variantType == QVariant::String && propertyType == qMetaTypeId<QStringList>()) {
} else if (variantType == QMetaType::QString && propertyType == qMetaTypeId<QStringList>()) {
QStringList list;
list << value.toString();
v = QVariant::fromValue<QStringList>(list);

View File

@ -92,7 +92,7 @@ static void flagsForPropertyType(int propType, QQmlPropertyData::Flags &flags)
flags.type = QQmlPropertyData::Flags::QObjectDerivedType;
} else if (propType == QMetaType::QVariant) {
flags.type = QQmlPropertyData::Flags::QVariantType;
} else if (propType < static_cast<int>(QVariant::UserType)) {
} else if (propType < static_cast<int>(QMetaType::User)) {
// nothing to do
} else if (propType == qMetaTypeId<QQmlBinding *>()) {
flags.type = QQmlPropertyData::Flags::QmlBindingType;
@ -136,14 +136,14 @@ static void populate(QQmlPropertyData *data, const QMetaProperty &p)
void QQmlPropertyData::lazyLoad(const QMetaProperty &p)
{
populate(this, p);
int type = static_cast<int>(p.type());
int type = static_cast<int>(p.userType());
if (type == QMetaType::QObjectStar) {
setPropType(type);
m_flags.type = Flags::QObjectDerivedType;
} else if (type == QMetaType::QVariant) {
setPropType(type);
m_flags.type = Flags::QVariantType;
} else if (type == QVariant::UserType || type == -1) {
} else if (type >= QMetaType::User || type == 0) {
m_flags.notFullyResolved = true;
} else {
setPropType(type);
@ -314,7 +314,7 @@ void QQmlPropertyCache::appendSignal(const QString &name, QQmlPropertyData::Flag
const QList<QByteArray> &names)
{
QQmlPropertyData data;
data.setPropType(QVariant::Invalid);
data.setPropType(QMetaType::UnknownType);
data.setCoreIndex(coreIndex);
data.setFlags(flags);
data.setArguments(nullptr);

View File

@ -806,12 +806,12 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>:
if (valueTypeIndex != -1) {
const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(*type);
if (valueTypeMetaObject->property(valueTypeIndex).isEnumType())
*type = QVariant::Int;
*type = QMetaType::Int;
else
*type = valueTypeMetaObject->property(valueTypeIndex).userType();
} else {
if (targetProperty->isEnum()) {
*type = QVariant::Int;
*type = QMetaType::Int;
} else {
// Copy type flags
propertyFlags->copyPropertyTypeFlags(targetProperty->flags());

View File

@ -398,31 +398,31 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
switch (property->propType()) {
case QMetaType::QVariant:
break;
case QVariant::String: {
case QMetaType::QString: {
if (!binding->evaluatesToString()) {
return warnOrError(tr("Invalid property assignment: string expected"));
}
}
break;
case QVariant::StringList: {
case QMetaType::QStringList: {
if (!binding->evaluatesToString()) {
return warnOrError(tr("Invalid property assignment: string or string list expected"));
}
}
break;
case QVariant::ByteArray: {
case QMetaType::QByteArray: {
if (binding->type != QV4::CompiledData::Binding::Type_String) {
return warnOrError(tr("Invalid property assignment: byte array expected"));
}
}
break;
case QVariant::Url: {
case QMetaType::QUrl: {
if (binding->type != QV4::CompiledData::Binding::Type_String) {
return warnOrError(tr("Invalid property assignment: url expected"));
}
}
break;
case QVariant::UInt: {
case QMetaType::UInt: {
if (binding->type == QV4::CompiledData::Binding::Type_Number) {
double d = compilationUnit->bindingValueAsNumber(binding);
if (double(uint(d)) == d)
@ -431,7 +431,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
return warnOrError(tr("Invalid property assignment: unsigned int expected"));
}
break;
case QVariant::Int: {
case QMetaType::Int: {
if (binding->type == QV4::CompiledData::Binding::Type_Number) {
double d = compilationUnit->bindingValueAsNumber(binding);
if (double(int(d)) == d)
@ -446,13 +446,13 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
case QVariant::Double: {
case QMetaType::Double: {
if (binding->type != QV4::CompiledData::Binding::Type_Number) {
return warnOrError(tr("Invalid property assignment: number expected"));
}
}
break;
case QVariant::Color: {
case QMetaType::QColor: {
bool ok = false;
QQmlStringConverters::rgbaFromString(compilationUnit->bindingValueAsString(binding), &ok);
if (!ok) {
@ -461,7 +461,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
break;
#if QT_CONFIG(datestring)
case QVariant::Date: {
case QMetaType::QDate: {
bool ok = false;
QQmlStringConverters::dateFromString(compilationUnit->bindingValueAsString(binding), &ok);
if (!ok) {
@ -469,7 +469,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
case QVariant::Time: {
case QMetaType::QTime: {
bool ok = false;
QQmlStringConverters::timeFromString(compilationUnit->bindingValueAsString(binding), &ok);
if (!ok) {
@ -477,7 +477,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
case QVariant::DateTime: {
case QMetaType::QDateTime: {
bool ok = false;
QQmlStringConverters::dateTimeFromString(compilationUnit->bindingValueAsString(binding), &ok);
if (!ok) {
@ -486,7 +486,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
break;
#endif // datestring
case QVariant::Point: {
case QMetaType::QPoint: {
bool ok = false;
QQmlStringConverters::pointFFromString(compilationUnit->bindingValueAsString(binding), &ok);
if (!ok) {
@ -494,7 +494,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
case QVariant::PointF: {
case QMetaType::QPointF: {
bool ok = false;
QQmlStringConverters::pointFFromString(compilationUnit->bindingValueAsString(binding), &ok);
if (!ok) {
@ -502,7 +502,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
case QVariant::Size: {
case QMetaType::QSize: {
bool ok = false;
QQmlStringConverters::sizeFFromString(compilationUnit->bindingValueAsString(binding), &ok);
if (!ok) {
@ -510,7 +510,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
case QVariant::SizeF: {
case QMetaType::QSizeF: {
bool ok = false;
QQmlStringConverters::sizeFFromString(compilationUnit->bindingValueAsString(binding), &ok);
if (!ok) {
@ -518,7 +518,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
case QVariant::Rect: {
case QMetaType::QRect: {
bool ok = false;
QQmlStringConverters::rectFFromString(compilationUnit->bindingValueAsString(binding), &ok);
if (!ok) {
@ -526,7 +526,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
case QVariant::RectF: {
case QMetaType::QRectF: {
bool ok = false;
QQmlStringConverters::rectFFromString(compilationUnit->bindingValueAsString(binding), &ok);
if (!ok) {
@ -534,13 +534,13 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
case QVariant::Bool: {
case QMetaType::Bool: {
if (binding->type != QV4::CompiledData::Binding::Type_Boolean) {
return warnOrError(tr("Invalid property assignment: boolean expected"));
}
}
break;
case QVariant::Vector2D: {
case QMetaType::QVector2D: {
struct {
float xp;
float yp;
@ -550,7 +550,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
case QVariant::Vector3D: {
case QMetaType::QVector3D: {
struct {
float xp;
float yp;
@ -561,7 +561,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
case QVariant::Vector4D: {
case QMetaType::QVector4D: {
struct {
float xp;
float yp;
@ -573,7 +573,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
case QVariant::Quaternion: {
case QMetaType::QQuaternion: {
struct {
float wp;
float xp;
@ -585,8 +585,8 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
case QVariant::RegExp:
case QVariant::RegularExpression:
case QMetaType::QRegExp:
case QMetaType::QRegularExpression:
return warnOrError(tr("Invalid property assignment: regular expression expected; use /pattern/ syntax"));
default: {
// generate single literal value assignment to a list property if required

View File

@ -357,8 +357,8 @@ void QQmlTypeLoader::networkReplyFinished(QNetworkReply *reply)
}
}
if (reply->error()) {
blob->networkError(reply->error());
if (reply->networkError()) {
blob->networkError(reply->networkError());
} else {
QByteArray data = reply->readAll();
setData(blob, data);

View File

@ -48,6 +48,8 @@
#endif
#include <private/qmetatype_p.h>
Q_DECLARE_METATYPE(QQmlProperty)
QT_BEGIN_NAMESPACE
namespace {
@ -62,7 +64,7 @@ struct QQmlValueTypeFactoryImpl
const QMetaObject *metaObjectForMetaType(int);
QQmlValueType *valueType(int);
QQmlValueType *valueTypes[QVariant::UserType];
QQmlValueType *valueTypes[QMetaType::User];
QHash<int, QQmlValueType *> userTypes;
QMutex mutex;
@ -71,7 +73,7 @@ struct QQmlValueTypeFactoryImpl
QQmlValueTypeFactoryImpl::QQmlValueTypeFactoryImpl()
{
std::fill_n(valueTypes, int(QVariant::UserType), &invalidValueType);
std::fill_n(valueTypes, int(QMetaType::User), &invalidValueType);
#if QT_CONFIG(qml_itemmodel)
// See types wrapped in qqmlmodelindexvaluetype_p.h
@ -118,26 +120,26 @@ bool QQmlValueTypeFactoryImpl::isValueType(int idx)
const QMetaObject *QQmlValueTypeFactoryImpl::metaObjectForMetaType(int t)
{
switch (t) {
case QVariant::Point:
case QMetaType::QPoint:
return &QQmlPointValueType::staticMetaObject;
case QVariant::PointF:
case QMetaType::QPointF:
return &QQmlPointFValueType::staticMetaObject;
case QVariant::Size:
case QMetaType::QSize:
return &QQmlSizeValueType::staticMetaObject;
case QVariant::SizeF:
case QMetaType::QSizeF:
return &QQmlSizeFValueType::staticMetaObject;
case QVariant::Rect:
case QMetaType::QRect:
return &QQmlRectValueType::staticMetaObject;
case QVariant::RectF:
case QMetaType::QRectF:
return &QQmlRectFValueType::staticMetaObject;
#if QT_CONFIG(easingcurve)
case QVariant::EasingCurve:
case QMetaType::QEasingCurve:
return &QQmlEasingValueType::staticMetaObject;
#endif
#if QT_CONFIG(qml_itemmodel)
case QVariant::ModelIndex:
case QMetaType::QModelIndex:
return &QQmlModelIndexValueType::staticMetaObject;
case QVariant::PersistentModelIndex:
case QMetaType::QPersistentModelIndex:
return &QQmlPersistentModelIndexValueType::staticMetaObject;
#endif
default:
@ -145,7 +147,8 @@ const QMetaObject *QQmlValueTypeFactoryImpl::metaObjectForMetaType(int t)
if (t == qMetaTypeId<QItemSelectionRange>())
return &QQmlItemSelectionRangeValueType::staticMetaObject;
#endif
if (t == qMetaTypeId<QQmlProperty>())
return &QQmlPropertyValueType::staticMetaObject;
if (const QMetaObject *mo = QQml_valueTypeProvider()->metaObjectForMetaType(t))
return mo;
break;
@ -159,7 +162,7 @@ const QMetaObject *QQmlValueTypeFactoryImpl::metaObjectForMetaType(int t)
QQmlValueType *QQmlValueTypeFactoryImpl::valueType(int idx)
{
if (idx >= (int)QVariant::UserType) {
if (idx >= (int)QMetaType::User) {
// Protect the hash with a mutex
mutex.lock();
@ -585,6 +588,16 @@ void QQmlEasingValueType::setBezierCurve(const QVariantList &customCurveVariant)
v = newEasingCurve;
}
QObject *QQmlPropertyValueType::object() const
{
return v.object();
}
QString QQmlPropertyValueType::name() const
{
return v.name();
}
QVariantList QQmlEasingValueType::bezierCurve() const
{
QVariantList rv;

View File

@ -268,6 +268,17 @@ public:
};
#endif
struct QQmlPropertyValueType
{
QQmlProperty v;
Q_PROPERTY(QObject *object READ object CONSTANT FINAL)
Q_PROPERTY(QString name READ name CONSTANT FINAL)
Q_GADGET
public:
QObject *object() const;
QString name() const;
};
template<typename T>
int qmlRegisterValueTypeEnums(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
{

View File

@ -601,7 +601,7 @@ bool QQmlValueTypeWrapper::virtualPut(Managed *m, PropertyKey id, const Value &v
QVariant v = v4->toVariant(value, property.userType());
if (property.isEnumType() && (QMetaType::Type)v.type() == QMetaType::Double)
if (property.isEnumType() && (QMetaType::Type)v.userType() == QMetaType::Double)
v = v.toInt();
void *gadget = r->d()->gadgetPtr();

View File

@ -291,7 +291,7 @@ bool QQmlInterceptorMetaObject::intercept(QMetaObject::Call c, int id, void **a)
const int valueIndex = vi->m_propertyIndex.valueTypeIndex();
int type = QQmlData::get(object)->propertyCache->property(id)->propType();
if (type != QVariant::Invalid) {
if (type != QMetaType::UnknownType) {
if (valueIndex != -1) {
QQmlValueType *valueType = QQmlValueTypeFactory::valueType(type);
Q_ASSERT(valueType);
@ -534,7 +534,7 @@ QUrl QQmlVMEMetaObject::readPropertyAsUrl(int id) const
QV4::Scope scope(engine);
QV4::ScopedValue sv(scope, *(md->data() + id));
const QV4::VariantObject *v = sv->as<QV4::VariantObject>();
if (!v || v->d()->data().type() != QVariant::Url)
if (!v || v->d()->data().userType() != QMetaType::QUrl)
return QUrl();
return v->d()->data().value<QUrl>();
}
@ -548,7 +548,7 @@ QDate QQmlVMEMetaObject::readPropertyAsDate(int id) const
QV4::Scope scope(engine);
QV4::ScopedValue sv(scope, *(md->data() + id));
const QV4::VariantObject *v = sv->as<QV4::VariantObject>();
if (!v || v->d()->data().type() != QVariant::Date)
if (!v || v->d()->data().userType() != QMetaType::QDate)
return QDate();
return v->d()->data().value<QDate>();
}
@ -562,7 +562,7 @@ QDateTime QQmlVMEMetaObject::readPropertyAsDateTime(int id)
QV4::Scope scope(engine);
QV4::ScopedValue sv(scope, *(md->data() + id));
const QV4::VariantObject *v = sv->as<QV4::VariantObject>();
if (!v || v->d()->data().type() != QVariant::DateTime)
if (!v || v->d()->data().userType() != QMetaType::QDateTime)
return QDateTime();
return v->d()->data().value<QDateTime>();
}
@ -576,7 +576,7 @@ QSizeF QQmlVMEMetaObject::readPropertyAsSizeF(int id) const
QV4::Scope scope(engine);
QV4::ScopedValue sv(scope, *(md->data() + id));
const QV4::VariantObject *v = sv->as<QV4::VariantObject>();
if (!v || v->d()->data().type() != QVariant::SizeF)
if (!v || v->d()->data().userType() != QMetaType::QSizeF)
return QSizeF();
return v->d()->data().value<QSizeF>();
}
@ -590,7 +590,7 @@ QPointF QQmlVMEMetaObject::readPropertyAsPointF(int id) const
QV4::Scope scope(engine);
QV4::ScopedValue sv(scope, *(md->data() + id));
const QV4::VariantObject *v = sv->as<QV4::VariantObject>();
if (!v || v->d()->data().type() != QVariant::PointF)
if (!v || v->d()->data().userType() != QMetaType::QPointF)
return QPointF();
return v->d()->data().value<QPointF>();
}
@ -634,7 +634,7 @@ QRectF QQmlVMEMetaObject::readPropertyAsRectF(int id) const
QV4::Scope scope(engine);
QV4::ScopedValue sv(scope, *(md->data() + id));
const QV4::VariantObject *v = sv->as<QV4::VariantObject>();
if (!v || v->d()->data().type() != QVariant::RectF)
if (!v || v->d()->data().userType() != QMetaType::QRectF)
return QRectF();
return v->d()->data().value<QRectF>();
}

View File

@ -1291,7 +1291,7 @@ void QQmlXMLHttpRequest::requestFromUrl(const QUrl &url)
if (m_network->bytesAvailable() > 0)
readyRead();
QNetworkReply::NetworkError networkError = m_network->error();
QNetworkReply::NetworkError networkError = m_network->networkError();
if (networkError != QNetworkReply::NoError) {
error(networkError);
} else {

View File

@ -340,22 +340,22 @@ ReturnedValue QtObject::method_colorEqual(const FunctionObject *b, const Value *
bool ok = false;
QVariant lhs = scope.engine->toVariant(argv[0], -1);
if (lhs.userType() == QVariant::String) {
if (lhs.userType() == QMetaType::QString) {
lhs = QQmlStringConverters::colorFromString(lhs.toString(), &ok);
if (!ok) {
THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid color name");
}
} else if (lhs.userType() != QVariant::Color) {
} else if (lhs.userType() != QMetaType::QColor) {
THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid arguments");
}
QVariant rhs = scope.engine->toVariant(argv[1], -1);
if (rhs.userType() == QVariant::String) {
if (rhs.userType() == QMetaType::QString) {
rhs = QQmlStringConverters::colorFromString(rhs.toString(), &ok);
if (!ok) {
THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid color name");
}
} else if (rhs.userType() != QVariant::Color) {
} else if (rhs.userType() != QMetaType::QColor) {
THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid arguments");
}
@ -606,13 +606,13 @@ ReturnedValue QtObject::method_lighter(const FunctionObject *b, const Value *, c
THROW_GENERIC_ERROR("Qt.lighter(): Invalid arguments");
QVariant v = scope.engine->toVariant(argv[0], -1);
if (v.userType() == QVariant::String) {
if (v.userType() == QMetaType::QString) {
bool ok = false;
v = QQmlStringConverters::colorFromString(v.toString(), &ok);
if (!ok) {
return QV4::Encode::null();
}
} else if (v.userType() != QVariant::Color) {
} else if (v.userType() != QMetaType::QColor) {
return QV4::Encode::null();
}
@ -646,13 +646,13 @@ ReturnedValue QtObject::method_darker(const FunctionObject *b, const Value *, co
THROW_GENERIC_ERROR("Qt.darker(): Invalid arguments");
QVariant v = scope.engine->toVariant(argv[0], -1);
if (v.userType() == QVariant::String) {
if (v.userType() == QMetaType::QString) {
bool ok = false;
v = QQmlStringConverters::colorFromString(v.toString(), &ok);
if (!ok) {
return QV4::Encode::null();
}
} else if (v.userType() != QVariant::Color) {
} else if (v.userType() != QMetaType::QColor) {
return QV4::Encode::null();
}
@ -697,25 +697,25 @@ ReturnedValue QtObject::method_tint(const FunctionObject *b, const Value *, cons
// base color
QVariant v1 = scope.engine->toVariant(argv[0], -1);
if (v1.userType() == QVariant::String) {
if (v1.userType() == QMetaType::QString) {
bool ok = false;
v1 = QQmlStringConverters::colorFromString(v1.toString(), &ok);
if (!ok) {
return QV4::Encode::null();
}
} else if (v1.userType() != QVariant::Color) {
} else if (v1.userType() != QMetaType::QColor) {
return QV4::Encode::null();
}
// tint color
QVariant v2 = scope.engine->toVariant(argv[1], -1);
if (v2.userType() == QVariant::String) {
if (v2.userType() == QMetaType::QString) {
bool ok = false;
v2 = QQmlStringConverters::colorFromString(v2.toString(), &ok);
if (!ok) {
return QV4::Encode::null();
}
} else if (v2.userType() != QVariant::Color) {
} else if (v2.userType() != QMetaType::QColor) {
return QV4::Encode::null();
}
@ -789,7 +789,7 @@ ReturnedValue QtObject::method_formatTime(const FunctionObject *b, const Value *
QVariant argVariant = scope.engine->toVariant(argv[0], -1);
QTime time;
if (argv[0].as<DateObject>() || (argVariant.type() == QVariant::String))
if (argv[0].as<DateObject>() || (argVariant.userType() == QMetaType::QString))
time = argVariant.toDateTime().time();
else // if (argVariant.type() == QVariant::Time), or invalid.
time = argVariant.toTime();

View File

@ -367,10 +367,10 @@ QV4::ReturnedValue QQmlDMCachedModelData::set_property(const QV4::FunctionObject
QQmlDMCachedModelData *modelData = static_cast<QQmlDMCachedModelData *>(o->d()->item);
if (!modelData->cachedData.isEmpty()) {
if (modelData->cachedData.count() > 1) {
modelData->cachedData[propertyId] = scope.engine->toVariant(argv[0], QVariant::Invalid);
modelData->cachedData[propertyId] = scope.engine->toVariant(argv[0], QMetaType::UnknownType);
QMetaObject::activate(o->d()->item, o->d()->item->metaObject(), propertyId, nullptr);
} else if (modelData->cachedData.count() == 1) {
modelData->cachedData[0] = scope.engine->toVariant(argv[0], QVariant::Invalid);
modelData->cachedData[0] = scope.engine->toVariant(argv[0], QMetaType::UnknownType);
QMetaObject::activate(o->d()->item, o->d()->item->metaObject(), 0, nullptr);
QMetaObject::activate(o->d()->item, o->d()->item->metaObject(), 1, nullptr);
}
@ -601,7 +601,7 @@ public:
if (!argc)
return v4->throwTypeError();
static_cast<QQmlDMListAccessorData *>(o->d()->item)->setModelData(v4->toVariant(argv[0], QVariant::Invalid));
static_cast<QQmlDMListAccessorData *>(o->d()->item)->setModelData(v4->toVariant(argv[0], QMetaType::UnknownType));
return QV4::Encode::undefined();
}

View File

@ -2011,7 +2011,7 @@ bool QQmlDelegateModelPrivate::insert(Compositor::insert_iterator &before, const
propertyName = it.nextPropertyNameAsString(v);
if (propertyName->isNull())
break;
cacheItem->setValue(propertyName->toQStringNoThrow(), scope.engine->toVariant(v, QVariant::Invalid));
cacheItem->setValue(propertyName->toQStringNoThrow(), scope.engine->toVariant(v, QMetaType::UnknownType));
}
cacheItem->groups = groups | Compositor::UnresolvedFlag | Compositor::CacheFlag;

View File

@ -76,11 +76,11 @@ void QQmlListAccessor::setList(const QVariant &v, QQmlEngine *engine)
if (!d.isValid()) {
m_type = Invalid;
} else if (d.userType() == QVariant::StringList) {
} else if (d.userType() == QMetaType::QStringList) {
m_type = StringList;
} else if (d.userType() == QMetaType::QVariantList) {
m_type = VariantList;
} else if (d.canConvert(QVariant::Int)) {
} else if (d.canConvert(QMetaType::Int)) {
// Here we have to check for an upper limit, because down the line code might (well, will)
// allocate memory depending on the number of elements. The upper limit cannot be INT_MAX:
// QVector<QPointer<QQuickItem>> something;

View File

@ -219,14 +219,14 @@ const ListLayout::Role *ListLayout::getRoleOrCreate(const QString &key, const QV
{
Role::DataType type;
switch (data.type()) {
case QVariant::Double: type = Role::Number; break;
case QVariant::Int: type = Role::Number; break;
case QVariant::Bool: type = Role::Bool; break;
case QVariant::String: type = Role::String; break;
case QVariant::Map: type = Role::VariantMap; break;
case QVariant::DateTime: type = Role::DateTime; break;
case QVariant::UserType: {
switch (data.userType()) {
case QMetaType::Double: type = Role::Number; break;
case QMetaType::Int: type = Role::Number; break;
case QMetaType::Bool: type = Role::Bool; break;
case QMetaType::QString: type = Role::String; break;
case QMetaType::QVariantMap: type = Role::VariantMap; break;
case QMetaType::QDateTime: type = Role::DateTime; break;
default: {
if (data.userType() == qMetaTypeId<QJSValue>() &&
data.value<QJSValue>().isCallable()) {
type = Role::Function;
@ -235,12 +235,14 @@ const ListLayout::Role *ListLayout::getRoleOrCreate(const QString &key, const QV
&& data.value<const QV4::CompiledData::Binding*>()->isTranslationBinding()) {
type = Role::String;
break;
} else {
} else if (data.userType() >= QMetaType::User) {
type = Role::List;
break;
} else {
type = Role::Invalid;
break;
}
}
default: type = Role::Invalid; break;
}
if (type == Role::Invalid) {
@ -1722,7 +1724,7 @@ void DynamicRoleModelNode::updateValues(const QVariantMap &object, QVector<int>
if (value.userType() == qMetaTypeId<QJSValue>())
value = value.value<QJSValue>().toVariant();
if (value.type() == QVariant::List) {
if (value.userType() == QMetaType::QVariantList) {
QQmlListModel *subModel = QQmlListModel::createWithOwner(m_owner);
QVariantList subArray = value.toList();
@ -1785,7 +1787,7 @@ void DynamicRoleModelNodeMetaObject::propertyWritten(int index)
if (v.userType() == qMetaTypeId<QJSValue>())
v= v.value<QJSValue>().toVariant();
if (v.type() == QVariant::List) {
if (v.userType() == QMetaType::QVariantList) {
QQmlListModel *subModel = QQmlListModel::createWithOwner(parentModel);
QVariantList subArray = v.toList();

View File

@ -500,8 +500,8 @@ bool QuickTestResult::verify
bool QuickTestResult::fuzzyCompare(const QVariant &actual, const QVariant &expected, qreal delta)
{
if (actual.type() == QVariant::Color || expected.type() == QVariant::Color) {
if (!actual.canConvert(QVariant::Color) || !expected.canConvert(QVariant::Color))
if (actual.userType() == QMetaType::QColor || expected.userType() == QMetaType::QColor) {
if (!actual.canConvert(QMetaType::QColor) || !expected.canConvert(QMetaType::QColor))
return false;
//fuzzy color comparison
@ -556,20 +556,20 @@ void QuickTestResult::stringify(QQmlV4Function *args)
&& !value->as<QV4::ArrayObject>()) {
QVariant v = scope.engine->toVariant(value, QMetaType::UnknownType);
if (v.isValid()) {
switch (v.type()) {
case QVariant::Vector3D:
switch (v.userType()) {
case QMetaType::QVector3D:
{
QVector3D v3d = v.value<QVector3D>();
result = QString::fromLatin1("Qt.vector3d(%1, %2, %3)").arg(v3d.x()).arg(v3d.y()).arg(v3d.z());
break;
}
case QVariant::Url:
case QMetaType::QUrl:
{
QUrl url = v.value<QUrl>();
result = QString::fromLatin1("Qt.url(%1)").arg(url.toString());
break;
}
case QVariant::DateTime:
case QMetaType::QDateTime:
{
QDateTime dt = v.value<QDateTime>();
result = dt.toString(Qt::ISODateWithMs);

View File

@ -240,7 +240,7 @@ int QQmlDesignerMetaObject::metaCall(QObject *o, QMetaObject::Call call, int id,
if (call == QMetaObject::WriteProperty
&& propertyById.userType() == QMetaType::QVariant
&& reinterpret_cast<QVariant *>(a[0])->type() == QVariant::Double
&& reinterpret_cast<QVariant *>(a[0])->userType() == QMetaType::Double
&& qt_is_nan(reinterpret_cast<QVariant *>(a[0])->toDouble())) {
return -1;
}

View File

@ -278,7 +278,7 @@ void QQuickDesignerCustomObjectData::setPropertyBinding(QQmlContext *context,
//Refcounting is taking take care of deletion
binding->update();
if (binding->hasError()) {
if (property.property().userType() == QVariant::String)
if (property.property().userType() == QMetaType::QString)
property.write(QVariant(QLatin1Char('#') + expression + QLatin1Char('#')));
}

View File

@ -560,7 +560,7 @@ void QQuickBorderImage::sciRequestFinished()
}
d->redirectCount=0;
if (d->sciReply->error() != QNetworkReply::NoError) {
if (d->sciReply->networkError() != QNetworkReply::NoError) {
d->status = Error;
d->sciReply->deleteLater();
d->sciReply = nullptr;

View File

@ -1478,7 +1478,7 @@ QVariant QQuickKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod) && i == d->imeItem) {
//### how robust is i == d->imeItem check?
QVariant v = i->inputMethodQuery(query);
if (v.userType() == QVariant::RectF)
if (v.userType() == QMetaType::QRectF)
v = d->item->mapRectFromItem(i, v.toRectF()); //### cost?
return v;
}

View File

@ -867,7 +867,7 @@ public:
QQmlListProperty<QQuickItem> forwardTo() {
Q_D(QQuickKeysAttached);
return QQmlListProperty<QQuickItem>(this, d->targets);
return QQmlListProperty<QQuickItem>(this, &(d->targets));
}
void componentComplete() override;

View File

@ -456,7 +456,7 @@ QQuickAnchorAnimation::~QQuickAnchorAnimation()
QQmlListProperty<QQuickItem> QQuickAnchorAnimation::targets()
{
Q_D(QQuickAnchorAnimation);
return QQmlListProperty<QQuickItem>(this, d->targets);
return QQmlListProperty<QQuickItem>(this, &(d->targets));
}
/*!

View File

@ -925,7 +925,7 @@ QQuickViewTransitionAttached::QQuickViewTransitionAttached(QObject *parent)
*/
QQmlListProperty<QObject> QQuickViewTransitionAttached::targetItems()
{
return QQmlListProperty<QObject>(this, m_targetItems);
return QQmlListProperty<QObject>(this, &m_targetItems);
}
QQuickViewTransitionAttached *QQuickViewTransitionAttached::qmlAttachedProperties(QObject *obj)

View File

@ -198,7 +198,7 @@ public:
bool wantsGrab() const { return _grab; }
QQmlListProperty<QObject> touchPoints() {
return QQmlListProperty<QObject>(this, _touchPoints);
return QQmlListProperty<QObject>(this, &_touchPoints);
}
qreal dragThreshold() const { return _dragThreshold; }

View File

@ -178,7 +178,7 @@ void QQuickCustomMaterialShader::updateState(const RenderState &state, QSGMateri
if (state.isMatrixDirty())
program()->setUniformValue(loc, state.combinedMatrix());
} else if (d.specialType == UniformData::None) {
switch (int(d.value.type())) {
switch (int(d.value.userType())) {
case QMetaType::QColor:
program()->setUniformValue(loc, qt_premultiply_color(qvariant_cast<QColor>(d.value)));
break;

View File

@ -257,7 +257,7 @@ QQuickGradient::~QQuickGradient()
QQmlListProperty<QQuickGradientStop> QQuickGradient::stops()
{
return QQmlListProperty<QQuickGradientStop>(this, m_stops);
return QQmlListProperty<QQuickGradientStop>(this, &m_stops);
}
/*!

View File

@ -196,7 +196,7 @@ public:
QQmlListProperty<QQuickStochasticState> states()
{
return QQmlListProperty<QQuickStochasticState>(this, m_states);
return QQmlListProperty<QQuickStochasticState>(this, &m_states);
}
QString globalGoal() const
@ -272,7 +272,7 @@ public:
~QQuickSpriteEngine() override;
QQmlListProperty<QQuickSprite> sprites()
{
return QQmlListProperty<QQuickSprite>(this, m_sprites);
return QQmlListProperty<QQuickSprite>(this, &m_sprites);
}
QQuickSprite* sprite(int sprite = 0) const;

View File

@ -60,6 +60,7 @@
#include <QtCore/qloggingcategory.h>
#include <qtextformat.h>
#include <qtransform.h>
#include <qdatetime.h>
#include <qbuffer.h>
#include <qguiapplication.h>
@ -718,12 +719,12 @@ void QQuickTextControl::selectAll()
void QQuickTextControl::processEvent(QEvent *e, const QPointF &coordinateOffset)
{
QMatrix m;
m.translate(coordinateOffset.x(), coordinateOffset.y());
processEvent(e, m);
QTransform t;
t.translate(coordinateOffset.x(), coordinateOffset.y());
processEvent(e, t);
}
void QQuickTextControl::processEvent(QEvent *e, const QMatrix &matrix)
void QQuickTextControl::processEvent(QEvent *e, const QTransform &transform)
{
Q_D(QQuickTextControl);
if (d->interactionFlags == Qt::NoTextInteraction) {
@ -740,25 +741,25 @@ void QQuickTextControl::processEvent(QEvent *e, const QMatrix &matrix)
break;
case QEvent::MouseButtonPress: {
QMouseEvent *ev = static_cast<QMouseEvent *>(e);
d->mousePressEvent(ev, matrix.map(ev->localPos()));
d->mousePressEvent(ev, transform.map(ev->localPos()));
break; }
case QEvent::MouseMove: {
QMouseEvent *ev = static_cast<QMouseEvent *>(e);
d->mouseMoveEvent(ev, matrix.map(ev->localPos()));
d->mouseMoveEvent(ev, transform.map(ev->localPos()));
break; }
case QEvent::MouseButtonRelease: {
QMouseEvent *ev = static_cast<QMouseEvent *>(e);
d->mouseReleaseEvent(ev, matrix.map(ev->localPos()));
d->mouseReleaseEvent(ev, transform.map(ev->localPos()));
break; }
case QEvent::MouseButtonDblClick: {
QMouseEvent *ev = static_cast<QMouseEvent *>(e);
d->mouseDoubleClickEvent(ev, matrix.map(ev->localPos()));
d->mouseDoubleClickEvent(ev, transform.map(ev->localPos()));
break; }
case QEvent::HoverEnter:
case QEvent::HoverMove:
case QEvent::HoverLeave: {
QHoverEvent *ev = static_cast<QHoverEvent *>(e);
d->hoverEvent(ev, matrix.map(ev->posF()));
d->hoverEvent(ev, transform.map(ev->posF()));
break; }
#if QT_CONFIG(im)
case QEvent::InputMethod:

View File

@ -71,6 +71,7 @@ class QQuickTextControlPrivate;
class QAbstractScrollArea;
class QEvent;
class QTimerEvent;
class QTransform;
class Q_AUTOTEST_EXPORT QQuickTextControl : public QInputControl
{
@ -169,7 +170,7 @@ Q_SIGNALS:
void markerHovered(bool marker);
public:
virtual void processEvent(QEvent *e, const QMatrix &matrix);
virtual void processEvent(QEvent *e, const QTransform &transform);
void processEvent(QEvent *e, const QPointF &coordinateOffset = QPointF());
#if QT_CONFIG(im)

View File

@ -532,7 +532,7 @@ void QQuickTextNodeEngine::addGlyphsForRanges(const QVarLengthArray<QTextLayout:
int remainingLength = end - start;
for (int j=0; j<ranges.size(); ++j) {
const QTextLayout::FormatRange &range = ranges.at(j);
if (range.start + range.length >= currentPosition
if (range.start + range.length > currentPosition
&& range.start < currentPosition + remainingLength) {
if (range.start > currentPosition) {

View File

@ -136,7 +136,7 @@ void QSGRhiShaderLinker::linkTextureSubRects()
// texture binding point.
for (Constant &c : m_constants) {
if (c.specialType == QSGShaderEffectNode::VariableData::SubRect) {
if (c.value.type() == QVariant::ByteArray) {
if (c.value.userType() == QMetaType::QByteArray) {
const QByteArray name = c.value.toByteArray();
if (!m_samplerNameMap.contains(name))
qWarning("ShaderEffect: qt_SubRect_%s refers to unknown source texture", name.constData());
@ -270,7 +270,7 @@ bool QSGRhiShaderEffectMaterialShader::updateUniformData(RenderState &state, QSG
memcpy(dst, f, sizeof(f));
} else if (c.specialType == QSGShaderEffectNode::VariableData::None) {
changed = true;
switch (int(c.value.type())) {
switch (int(c.value.userType())) {
case QMetaType::QColor: {
const QColor v = qsg_premultiply_color(qvariant_cast<QColor>(c.value));
const float f[4] = { float(v.redF()), float(v.greenF()), float(v.blueF()), float(v.alphaF()) };

View File

@ -490,7 +490,7 @@ QQuickAnimationGroup *QQuickAbstractAnimation::group() const
return d->group;
}
void QQuickAbstractAnimation::setGroup(QQuickAnimationGroup *g)
void QQuickAbstractAnimation::setGroup(QQuickAnimationGroup *g, int index)
{
Q_D(QQuickAbstractAnimation);
if (d->group == g)
@ -500,8 +500,12 @@ void QQuickAbstractAnimation::setGroup(QQuickAnimationGroup *g)
d->group = g;
if (d->group && !d->group->d_func()->animations.contains(this))
d->group->d_func()->animations.append(this);
if (d->group && !d->group->d_func()->animations.contains(this)) {
if (index >= 0)
d->group->d_func()->animations.insert(index, this);
else
d->group->d_func()->animations.append(this);
}
}
/*!
@ -1170,7 +1174,7 @@ void QQuickPropertyAction::setProperties(const QString &p)
QQmlListProperty<QObject> QQuickPropertyAction::targets()
{
Q_D(QQuickPropertyAction);
return QQmlListProperty<QObject>(this, d->targets);
return QQmlListProperty<QObject>(this, &(d->targets));
}
/*!
@ -1182,7 +1186,7 @@ QQmlListProperty<QObject> QQuickPropertyAction::targets()
QQmlListProperty<QObject> QQuickPropertyAction::exclude()
{
Q_D(QQuickPropertyAction);
return QQmlListProperty<QObject>(this, d->exclude);
return QQmlListProperty<QObject>(this, &(d->exclude));
}
/*!
@ -1722,6 +1726,20 @@ void QQuickAnimationGroupPrivate::append_animation(QQmlListProperty<QQuickAbstra
a->setGroup(q);
}
QQuickAbstractAnimation *QQuickAnimationGroupPrivate::at_animation(QQmlListProperty<QQuickAbstractAnimation> *list, int index)
{
if (auto q = qmlobject_cast<QQuickAnimationGroup *>(list->object))
return q->d_func()->animations.at(index);
return nullptr;
}
int QQuickAnimationGroupPrivate::count_animation(QQmlListProperty<QQuickAbstractAnimation> *list)
{
if (auto q = qmlobject_cast<QQuickAnimationGroup *>(list->object))
return q->d_func()->animations.count();
return 0;
}
void QQuickAnimationGroupPrivate::clear_animation(QQmlListProperty<QQuickAbstractAnimation> *list)
{
QQuickAnimationGroup *q = qobject_cast<QQuickAnimationGroup *>(list->object);
@ -1733,6 +1751,23 @@ void QQuickAnimationGroupPrivate::clear_animation(QQmlListProperty<QQuickAbstrac
}
}
void QQuickAnimationGroupPrivate::replace_animation(QQmlListProperty<QQuickAbstractAnimation> *list,
int i, QQuickAbstractAnimation *a)
{
if (auto *q = qmlobject_cast<QQuickAnimationGroup *>(list->object)) {
if (QQuickAbstractAnimation *anim = q->d_func()->animations.at(i))
anim->setGroup(nullptr);
if (a)
a->setGroup(q, i);
}
}
void QQuickAnimationGroupPrivate::removeLast_animation(QQmlListProperty<QQuickAbstractAnimation> *list)
{
if (auto *q = qobject_cast<QQuickAnimationGroup *>(list->object))
q->d_func()->animations.last()->setGroup(nullptr);
}
QQuickAnimationGroup::~QQuickAnimationGroup()
{
Q_D(QQuickAnimationGroup);
@ -1744,10 +1779,14 @@ QQuickAnimationGroup::~QQuickAnimationGroup()
QQmlListProperty<QQuickAbstractAnimation> QQuickAnimationGroup::animations()
{
Q_D(QQuickAnimationGroup);
QQmlListProperty<QQuickAbstractAnimation> list(this, d->animations);
list.append = &QQuickAnimationGroupPrivate::append_animation;
list.clear = &QQuickAnimationGroupPrivate::clear_animation;
return list;
return QQmlListProperty<QQuickAbstractAnimation>(
this, &(d->animations),
&QQuickAnimationGroupPrivate::append_animation,
&QQuickAnimationGroupPrivate::count_animation,
&QQuickAnimationGroupPrivate::at_animation,
&QQuickAnimationGroupPrivate::clear_animation,
&QQuickAnimationGroupPrivate::replace_animation,
&QQuickAnimationGroupPrivate::removeLast_animation);
}
/*!
@ -1927,20 +1966,20 @@ QAbstractAnimationJob* QQuickParallelAnimation::transition(QQuickStateActions &a
//convert a variant from string type to another animatable type
void QQuickPropertyAnimationPrivate::convertVariant(QVariant &variant, int type)
{
if (variant.userType() != QVariant::String) {
if (variant.userType() != QMetaType::QString) {
variant.convert(type);
return;
}
switch (type) {
case QVariant::Rect:
case QVariant::RectF:
case QVariant::Point:
case QVariant::PointF:
case QVariant::Size:
case QVariant::SizeF:
case QVariant::Color:
case QVariant::Vector3D:
case QMetaType::QRect:
case QMetaType::QRectF:
case QMetaType::QPoint:
case QMetaType::QPointF:
case QMetaType::QSize:
case QMetaType::QSizeF:
case QMetaType::QColor:
case QMetaType::QVector3D:
{
bool ok = false;
variant = QQmlStringConverters::variantFromString(variant.toString(), type, &ok);
@ -2533,7 +2572,7 @@ void QQuickPropertyAnimation::setProperties(const QString &prop)
QQmlListProperty<QObject> QQuickPropertyAnimation::targets()
{
Q_D(QQuickPropertyAnimation);
return QQmlListProperty<QObject>(this, d->targets);
return QQmlListProperty<QObject>(this, &(d->targets));
}
/*!
@ -2544,7 +2583,7 @@ QQmlListProperty<QObject> QQuickPropertyAnimation::targets()
QQmlListProperty<QObject> QQuickPropertyAnimation::exclude()
{
Q_D(QQuickPropertyAnimation);
return QQmlListProperty<QObject>(this, d->exclude);
return QQmlListProperty<QObject>(this, &(d->exclude));
}
void QQuickAnimationPropertyUpdater::setValue(qreal v)

View File

@ -111,7 +111,7 @@ public:
void setCurrentTime(int);
QQuickAnimationGroup *group() const;
void setGroup(QQuickAnimationGroup *);
void setGroup(QQuickAnimationGroup *, int index = -1);
void setDefaultTarget(const QQmlProperty &);
void setDisableUserControl();

View File

@ -256,7 +256,12 @@ public:
: QQuickAbstractAnimationPrivate() {}
static void append_animation(QQmlListProperty<QQuickAbstractAnimation> *list, QQuickAbstractAnimation *role);
static QQuickAbstractAnimation *at_animation(QQmlListProperty<QQuickAbstractAnimation> *list, int index);
static int count_animation(QQmlListProperty<QQuickAbstractAnimation> *list);
static void clear_animation(QQmlListProperty<QQuickAbstractAnimation> *list);
static void replace_animation(QQmlListProperty<QQuickAbstractAnimation> *list, int index,
QQuickAbstractAnimation *role);
static void removeLast_animation(QQmlListProperty<QQuickAbstractAnimation> *list);
QList<QQuickAbstractAnimation *> animations;
};

View File

@ -121,7 +121,7 @@ void QQuickFontObject::replyFinished()
}
redirectCount = 0;
if (!reply->error()) {
if (!reply->networkError()) {
id = QFontDatabase::addApplicationFontFromData(reply->readAll());
if (id != -1)
emit fontDownloaded(QFontDatabase::applicationFontFamilies(id).at(0), QQuickFontLoader::Ready);

View File

@ -719,7 +719,7 @@ public:
bool typedRead(const QVariant& src, int dstType, void *dst)
{
T *dstT = reinterpret_cast<T *>(dst);
if (src.type() == static_cast<uint>(dstType)) {
if (src.userType() == dstType) {
*dstT = src.value<T>();
} else {
*dstT = T();

View File

@ -2415,7 +2415,7 @@ QVariant QQuickPathPolyline::path() const
void QQuickPathPolyline::setPath(const QVariant &path)
{
if (path.type() == QVariant::PolygonF) {
if (path.userType() == QMetaType::QPolygonF) {
setPath(path.value<QPolygonF>());
} else if (path.canConvert<QVector<QPointF>>()) {
setPath(path.value<QVector<QPointF>>());
@ -2431,7 +2431,7 @@ void QQuickPathPolyline::setPath(const QVariant &path)
pathList.append(v.toPointF());
setPath(pathList);
} else {
qWarning() << "PathPolyline: path of type" << path.type() << "not supported";
qWarning() << "PathPolyline: path of type" << path.userType() << "not supported";
}
}
@ -2583,7 +2583,7 @@ void QQuickPathMultiline::setPaths(const QVariant &paths)
}
setPaths(pathsList);
} else {
qWarning() << "PathMultiline: paths of type" << paths.type() << "not supported";
qWarning() << "PathMultiline: paths of type" << paths.userType() << "not supported";
setPaths(QVector<QVector<QPointF>>());
}
}

View File

@ -559,7 +559,7 @@ void QQuickPixmapReader::networkRequestDone(QNetworkReply *reply)
QQuickPixmapReply::ReadError error = QQuickPixmapReply::NoError;
QString errorString;
QSize readSize;
if (reply->error()) {
if (reply->networkError()) {
error = QQuickPixmapReply::Loading;
errorString = reply->errorString();
} else {

View File

@ -130,7 +130,7 @@ QT_BEGIN_NAMESPACE
static QKeySequence valueToKeySequence(const QVariant &value)
{
if (value.type() == QVariant::Int)
if (value.userType() == QMetaType::Int)
return QKeySequence(static_cast<QKeySequence::StandardKey>(value.toInt()));
return QKeySequence::fromString(value.toString());
}

View File

@ -280,11 +280,11 @@ void tst_QQmlEngineDebugService::recursiveObjectTest(
} else {
QCOMPARE(ref.name, QString("<unknown value>"));
}
} else if (pmeta.type() < QVariant::UserType && pmeta.userType() != QMetaType::QVariant) {
} else if (pmeta.userType() < QMetaType::User && pmeta.userType() != QMetaType::QVariant) {
const QVariant expected = pmeta.read(o);
QVERIFY2(p.value == expected, QString::fromLatin1("%1 != %2. Details: %3/%4/%5/%6")
.arg(QTest::toString(p.value)).arg(QTest::toString(expected)).arg(p.name)
.arg(p.valueTypeName).arg(pmeta.type()).arg(pmeta.userType()).toUtf8());
.arg(p.valueTypeName).arg(pmeta.userType()).arg(pmeta.userType()).toUtf8());
}
if (p.name == "parent")

View File

@ -1543,7 +1543,7 @@ void tst_QJSEngine::valueConversion_QVariant()
{
QVariant tmp1;
QVariant tmp2(QMetaType::QVariant, &tmp1);
QCOMPARE(QMetaType::Type(tmp2.type()), QMetaType::QVariant);
QCOMPARE(QMetaType::Type(tmp2.userType()), QMetaType::QVariant);
QJSValue val1 = eng.toScriptValue(tmp1);
QJSValue val2 = eng.toScriptValue(tmp2);
@ -1558,9 +1558,9 @@ void tst_QJSEngine::valueConversion_QVariant()
QVariant tmp1(123);
QVariant tmp2(QMetaType::QVariant, &tmp1);
QVariant tmp3(QMetaType::QVariant, &tmp2);
QCOMPARE(QMetaType::Type(tmp1.type()), QMetaType::Int);
QCOMPARE(QMetaType::Type(tmp2.type()), QMetaType::QVariant);
QCOMPARE(QMetaType::Type(tmp3.type()), QMetaType::QVariant);
QCOMPARE(QMetaType::Type(tmp1.userType()), QMetaType::Int);
QCOMPARE(QMetaType::Type(tmp2.userType()), QMetaType::QVariant);
QCOMPARE(QMetaType::Type(tmp3.userType()), QMetaType::QVariant);
QJSValue val1 = eng.toScriptValue(tmp2);
QJSValue val2 = eng.toScriptValue(tmp3);

View File

@ -1081,7 +1081,7 @@ void tst_QJSValue::toVariant()
// We can't roundtrip a QRegExp this way, as toVariant() has no information on whether we
// want QRegExp or QRegularExpression. It will always create a QRegularExpression.
QCOMPARE(var.type(), QMetaType::QRegularExpression);
QCOMPARE(var.userType(), QMetaType::QRegularExpression);
QRegularExpression result = var.toRegularExpression();
QCOMPARE(result.pattern(), rx.pattern());
QCOMPARE(result.patternOptions() & QRegularExpression::CaseInsensitiveOption, 0);
@ -1134,7 +1134,7 @@ void tst_QJSValue::toVariant()
QVERIFY(array.isArray());
QCOMPARE(array.property("length").toInt(), 2);
QVariant ret = array.toVariant();
QCOMPARE(ret.type(), QVariant::List);
QCOMPARE(ret.userType(), QVariant::List);
QVariantList listOut = ret.toList();
QCOMPARE(listOut.size(), listIn.size());
for (int i = 0; i < listIn.size(); ++i)

View File

@ -91,7 +91,7 @@ SUBDIRS += $$METATYPETESTS
qtConfig(process) {
qtConfig(qml-debug): SUBDIRS += debugger
!boot2qt {
SUBDIRS += qmllint qmlplugindump
SUBDIRS += qmlformat qmllint qmlplugindump
}
}

View File

@ -3,6 +3,7 @@ TARGET = tst_qmlformat
macos:CONFIG -= app_bundle
SOURCES += tst_qmlformat.cpp
DEFINES += SRCDIR=\\\"$$PWD\\\"
include (../../shared/util.pri)

View File

@ -42,11 +42,22 @@ private Q_SLOTS:
void testFormat();
void testFormatNoSort();
#if !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled
void testExample();
void testExample_data();
#endif
private:
QString readTestFile(const QString &path);
QString runQmlformat(const QString &fileToFormat, bool sortImports, bool shouldSucceed);
QString m_qmlformatPath;
QStringList m_excludedDirs;
QStringList m_invalidFiles;
QStringList findFiles(const QDir &);
bool isInvalidFile(const QFileInfo &fileName) const;
};
void TestQmlformat::initTestCase()
@ -60,6 +71,91 @@ void TestQmlformat::initTestCase()
QString message = QStringLiteral("qmlformat executable not found (looked for %0)").arg(m_qmlformatPath);
QFAIL(qPrintable(message));
}
// Add directories you want excluded here
// These snippets are not expected to run on their own.
m_excludedDirs << "doc/src/snippets/qml/visualdatamodel_rootindex";
m_excludedDirs << "doc/src/snippets/qml/qtbinding";
m_excludedDirs << "doc/src/snippets/qml/imports";
m_excludedDirs << "doc/src/snippets/qtquick1/visualdatamodel_rootindex";
m_excludedDirs << "doc/src/snippets/qtquick1/qtbinding";
m_excludedDirs << "doc/src/snippets/qtquick1/imports";
m_excludedDirs << "tests/manual/v4";
m_excludedDirs << "tests/auto/qml/ecmascripttests";
m_excludedDirs << "tests/auto/qml/qmllint";
// Add invalid files (i.e. files with syntax errors)
m_invalidFiles << "tests/auto/quick/qquickloader/data/InvalidSourceComponent.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/signal.2.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/signal.3.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/signal.5.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/property.4.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/empty.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/missingObject.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/insertedSemicolon.1.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/nonexistantProperty.5.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/invalidRoot.1.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.1.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.2.qml";
m_invalidFiles << "tests/auto/qml/qquickfolderlistmodel/data/dummy.qml";
m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/stringParsing_error.1.qml";
m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/stringParsing_error.2.qml";
m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/stringParsing_error.3.qml";
m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/stringParsing_error.4.qml";
m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/stringParsing_error.5.qml";
m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/stringParsing_error.6.qml";
m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/numberParsing_error.1.qml";
m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/numberParsing_error.2.qml";
m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/incrDecrSemicolon_error1.qml";
m_invalidFiles << "tests/auto/qml/debugger/qqmlpreview/data/broken.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/fuzzed.2.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/fuzzed.3.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/requiredProperties.2.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/requiredProperties.3.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/nullishCoalescing_LHS_And.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/nullishCoalescing_LHS_And.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/nullishCoalescing_LHS_Or.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/nullishCoalescing_RHS_And.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/nullishCoalescing_RHS_Or.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/typeAnnotations.2.qml";
m_invalidFiles << "tests/auto/qml/qqmlparser/data/disallowedtypeannotations/qmlnestedfunction.qml";
}
QStringList TestQmlformat::findFiles(const QDir &d)
{
for (int ii = 0; ii < m_excludedDirs.count(); ++ii) {
QString s = m_excludedDirs.at(ii);
if (d.absolutePath().endsWith(s))
return QStringList();
}
QStringList rv;
QStringList files = d.entryList(QStringList() << QLatin1String("*.qml"),
QDir::Files);
foreach (const QString &file, files) {
rv << d.absoluteFilePath(file);
}
QStringList dirs = d.entryList(QDir::Dirs | QDir::NoDotAndDotDot |
QDir::NoSymLinks);
foreach (const QString &dir, dirs) {
QDir sub = d;
sub.cd(dir);
rv << findFiles(sub);
}
return rv;
}
bool TestQmlformat::isInvalidFile(const QFileInfo &fileName) const
{
for (const QString &invalidFile : m_invalidFiles) {
if (fileName.absoluteFilePath().endsWith(invalidFile))
return true;
}
return false;
}
QString TestQmlformat::readTestFile(const QString &path)
@ -74,18 +170,46 @@ QString TestQmlformat::readTestFile(const QString &path)
void TestQmlformat::testFormat()
{
QCOMPARE(runQmlformat("Example1.qml", true, true), readTestFile("Example1.formatted.qml"));
QCOMPARE(runQmlformat(testFile("Example1.qml"), true, true), readTestFile("Example1.formatted.qml"));
}
void TestQmlformat::testFormatNoSort()
{
QCOMPARE(runQmlformat("Example1.qml", false, true), readTestFile("Example1.formatted.nosort.qml"));
QCOMPARE(runQmlformat(testFile("Example1.qml"), false, true), readTestFile("Example1.formatted.nosort.qml"));
}
#if !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled
void TestQmlformat::testExample_data()
{
QTest::addColumn<QString>("file");
QString examples = QLatin1String(SRCDIR) + "/../../../../examples/";
QString tests = QLatin1String(SRCDIR) + "/../../../../tests/";
QStringList files;
files << findFiles(QDir(examples));
files << findFiles(QDir(tests));
for (const QString &file : files)
QTest::newRow(qPrintable(file)) << file;
}
#endif
#if !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled
void TestQmlformat::testExample()
{
QFETCH(QString, file);
QString output = runQmlformat(file, true, !isInvalidFile(file));
if (!isInvalidFile(file))
QVERIFY(!output.isEmpty());
}
#endif
QString TestQmlformat::runQmlformat(const QString &fileToFormat, bool sortImports, bool shouldSucceed)
{
QStringList args;
args << testFile(fileToFormat);
args << fileToFormat;
if (!sortImports)
args << "-n";

View File

@ -36,7 +36,6 @@
#include <QtCore/qregularexpression.h>
#include <QtQml/qqmllist.h>
#include <QtCore/qrect.h>
#include <QtGui/qmatrix.h>
#include <QtGui/qcolor.h>
#include <QtGui/qvector3d.h>
#include <QtGui/QFont>

View File

@ -1 +1 @@
3:13:Invalid property assignment: unsupported type "QMatrix"
3:16:Invalid property assignment: unsupported type "QTransform"

View File

@ -1,4 +1,4 @@
import Test 1.0
MyQmlObject {
matrix: "1,0,0,0,1,0,0,0,1"
transform: "1,0,0,0,1,0,0,0,1"
}

View File

@ -121,6 +121,7 @@ void registerTypes()
qmlRegisterTypesAndRevisions<Extended, Foreign, ForeignExtended>("Test", 1);
qmlRegisterTypesAndRevisions<BareSingleton>("Test", 1);
qmlRegisterTypesAndRevisions<UncreatableSingleton>("Test", 1);
}
QVariant myCustomVariantTypeConverter(const QString &data)
@ -213,3 +214,9 @@ bool MyQmlObject::event(QEvent *event)
m_childAddedEventCount++;
return QObject::event(event);
}
UncreatableSingleton *UncreatableSingleton::instance()
{
static UncreatableSingleton instance;
return &instance;
}

View File

@ -31,7 +31,7 @@
#include <QtCore/qobject.h>
#include <QtCore/qrect.h>
#include <QtCore/qdatetime.h>
#include <QtGui/qmatrix.h>
#include <QtGui/qtransform.h>
#include <QtGui/qcolor.h>
#include <QtGui/qvector2d.h>
#include <QtGui/qvector3d.h>
@ -104,7 +104,7 @@ class MyQmlObject : public QObject, public MyInterface
Q_PROPERTY(QString readOnlyString READ readOnlyString)
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled)
Q_PROPERTY(QRect rect READ rect WRITE setRect)
Q_PROPERTY(QMatrix matrix READ matrix WRITE setMatrix) //assumed to be unsupported by QML
Q_PROPERTY(QTransform transform READ transform WRITE setTransform) //assumed to be unsupported by QML
Q_PROPERTY(MyInterface *interfaceProperty READ interface WRITE setInterface)
Q_PROPERTY(int onLiteralSignal READ onLiteralSignal WRITE setOnLiteralSignal)
Q_PROPERTY(MyCustomVariantType customType READ customType WRITE setCustomType)
@ -129,8 +129,8 @@ public:
QRect rect() const { return QRect(); }
void setRect(const QRect&) {}
QMatrix matrix() const { return QMatrix(); }
void setMatrix(const QMatrix&) {}
QTransform transform() const { return QTransform(); }
void setTransform(const QTransform &) {}
MyInterface *interface() const { return m_interface; }
void setInterface(MyInterface *iface) { m_interface = iface; }
@ -1468,6 +1468,19 @@ public:
}
};
class UncreatableSingleton : public QObject
{
Q_OBJECT
QML_SINGLETON
QML_ELEMENT
public:
static UncreatableSingleton *instance();
private:
UncreatableSingleton() { setObjectName("uncreatable"); }
};
void registerTypes();
#endif // TESTTYPES_H

View File

@ -5378,25 +5378,34 @@ void tst_qqmllanguage::listContainingDeletedObject()
void tst_qqmllanguage::overrideSingleton()
{
auto check = [](const QString &name) {
auto check = [](const QString &name, const QByteArray &singletonElement) {
const QByteArray testQml = "import Test 1.0\n"
"import QtQml 2.0\n"
"QtObject { objectName: BareSingleton.objectName }";
"QtObject { objectName: " + singletonElement + ".objectName }";
QQmlEngine engine;
QQmlComponent component(&engine, nullptr);
component.setData(testQml, QUrl());
component.setData(testQml, QUrl("singleton.qml"));
QVERIFY(component.isReady());
QScopedPointer<QObject> obj(component.create());
QCOMPARE(obj->objectName(), name);
};
check("statically registered");
check("statically registered", "BareSingleton");
BareSingleton singleton;
singleton.setObjectName("dynamically registered");
qmlRegisterSingletonInstance("Test", 1, 0, "BareSingleton", &singleton);
check("dynamically registered");
check("dynamically registered", "BareSingleton");
QTest::ignoreMessage(
QtWarningMsg,
"singleton.qml:3: TypeError: Cannot read property 'objectName' of undefined");
check("", "UncreatableSingleton");
qmlRegisterSingletonInstance("Test", 1, 0, "UncreatableSingleton",
UncreatableSingleton::instance());
check("uncreatable", "UncreatableSingleton");
}
QTEST_MAIN(tst_qqmllanguage)

View File

@ -45,6 +45,9 @@ class tst_qqmllistreference : public QQmlDataTest
public:
tst_qqmllistreference() {}
private:
void modeData();
private slots:
void initTestCase();
void qmllistreference();
@ -56,12 +59,19 @@ private slots:
void canAt();
void canClear();
void canCount();
void canReplace();
void canRemoveLast();
void isReadable();
void isManipulable();
void append();
void at();
void clear_data() { modeData(); }
void clear();
void count();
void replace_data() { modeData(); }
void replace();
void removeLast_data() { modeData(); }
void removeLast();
void copy();
void qmlmetaproperty();
void engineTypes();
@ -76,7 +86,67 @@ class TestType : public QObject
Q_PROPERTY(int intProperty READ intProperty)
public:
TestType() : property(this, data) {}
enum Mode {
SyntheticClear,
SyntheticReplace,
SyntheticClearAndReplace,
SyntheticRemoveLast,
SyntheticRemoveLastAndReplace,
AutomaticReference,
AutomaticPointer
};
static void append(QQmlListProperty<TestType> *p, TestType *v) {
reinterpret_cast<QList<TestType *> *>(p->data)->append(v);
}
static int count(QQmlListProperty<TestType> *p) {
return reinterpret_cast<QList<TestType *> *>(p->data)->count();
}
static TestType *at(QQmlListProperty<TestType> *p, int idx) {
return reinterpret_cast<QList<TestType *> *>(p->data)->at(idx);
}
static void clear(QQmlListProperty<TestType> *p) {
return reinterpret_cast<QList<TestType *> *>(p->data)->clear();
}
static void replace(QQmlListProperty<TestType> *p, int idx, TestType *v) {
return reinterpret_cast<QList<TestType *> *>(p->data)->replace(idx, v);
}
static void removeLast(QQmlListProperty<TestType> *p) {
return reinterpret_cast<QList<TestType *> *>(p->data)->removeLast();
}
TestType(Mode mode = AutomaticReference)
{
switch (mode) {
case SyntheticClear:
property = QQmlListProperty<TestType>(this, &data, append, count, at, nullptr,
replace, removeLast);
break;
case SyntheticReplace:
property = QQmlListProperty<TestType>(this, &data, append, count, at, clear,
nullptr, removeLast);
break;
case SyntheticClearAndReplace:
property = QQmlListProperty<TestType>(this, &data, append, count, at, nullptr,
nullptr, removeLast);
break;
case SyntheticRemoveLast:
property = QQmlListProperty<TestType>(this, &data, append, count, at, clear,
replace, nullptr);
break;
case SyntheticRemoveLastAndReplace:
property = QQmlListProperty<TestType>(this, &data, append, count, at, clear,
nullptr, nullptr);
break;
case AutomaticReference:
property = QQmlListProperty<TestType>(this, data);
break;
case AutomaticPointer:
property = QQmlListProperty<TestType>(this, &data);
break;
}
}
QQmlListProperty<TestType> dataProperty() { return property; }
int intProperty() const { return 10; }
@ -84,6 +154,20 @@ public:
QQmlListProperty<TestType> property;
};
Q_DECLARE_METATYPE(TestType::Mode)
void tst_qqmllistreference::modeData()
{
QTest::addColumn<TestType::Mode>("mode");
QTest::addRow("AutomaticReference") << TestType::AutomaticReference;
QTest::addRow("AutomaticPointer") << TestType::AutomaticPointer;
QTest::addRow("SyntheticClear") << TestType::SyntheticClear;
QTest::addRow("SyntheticReplace") << TestType::SyntheticReplace;
QTest::addRow("SyntheticClearAndReplace") << TestType::SyntheticClearAndReplace;
QTest::addRow("SyntheticRemoveLast") << TestType::SyntheticRemoveLast;
QTest::addRow("SyntheticRemoveLastAndReplace") << TestType::SyntheticRemoveLastAndReplace;
}
void tst_qqmllistreference::initTestCase()
{
QQmlDataTest::initTestCase();
@ -340,6 +424,64 @@ void tst_qqmllistreference::canCount()
}
}
void tst_qqmllistreference::canReplace()
{
QScopedPointer<TestType> tt(new TestType);
{
QQmlListReference ref;
QVERIFY(!ref.canReplace());
}
{
QQmlListReference ref(tt.data(), "blah");
QVERIFY(!ref.canReplace());
}
{
QQmlListReference ref(tt.data(), "data");
QVERIFY(ref.canReplace());
tt.reset();
QVERIFY(!ref.canReplace());
}
{
TestType tt;
tt.property.replace = nullptr;
QQmlListReference ref(&tt, "data");
QVERIFY(!ref.canReplace());
}
}
void tst_qqmllistreference::canRemoveLast()
{
QScopedPointer<TestType> tt(new TestType);
{
QQmlListReference ref;
QVERIFY(!ref.canRemoveLast());
}
{
QQmlListReference ref(tt.data(), "blah");
QVERIFY(!ref.canRemoveLast());
}
{
QQmlListReference ref(tt.data(), "data");
QVERIFY(ref.canRemoveLast());
tt.reset();
QVERIFY(!ref.canRemoveLast());
}
{
TestType tt;
tt.property.removeLast = nullptr;
QQmlListReference ref(&tt, "data");
QVERIFY(!ref.canRemoveLast());
}
}
void tst_qqmllistreference::isReadable()
{
TestType *tt = new TestType;
@ -474,7 +616,8 @@ void tst_qqmllistreference::at()
void tst_qqmllistreference::clear()
{
TestType *tt = new TestType;
QFETCH(TestType::Mode, mode);
TestType *tt = new TestType(mode);
tt->data.append(tt);
tt->data.append(0);
tt->data.append(tt);
@ -540,6 +683,70 @@ void tst_qqmllistreference::count()
}
}
void tst_qqmllistreference::replace()
{
QFETCH(TestType::Mode, mode);
QScopedPointer<TestType> tt(new TestType(mode));
tt->data.append(tt.get());
tt->data.append(nullptr);
tt->data.append(tt.get());
{
QQmlListReference ref(tt.get(), "data");
QVERIFY(ref.replace(1, tt.get()));
QCOMPARE(ref.at(1), tt.get());
QVERIFY(ref.replace(2, nullptr));
QCOMPARE(ref.at(2), nullptr);
QCOMPARE(ref.count(), 3);
tt.reset();
QVERIFY(!ref.replace(0, tt.get()));
}
{
TestType tt;
tt.data.append(&tt);
tt.property.replace = nullptr;
QQmlListReference ref(&tt, "data");
QVERIFY(!ref.replace(0, nullptr));
}
}
void tst_qqmllistreference::removeLast()
{
QFETCH(TestType::Mode, mode);
QScopedPointer<TestType> tt(new TestType(mode));
tt->data.append(tt.get());
tt->data.append(nullptr);
tt->data.append(tt.get());
{
QQmlListReference ref;
QVERIFY(!ref.removeLast());
}
{
QQmlListReference ref(tt.get(), "blah");
QVERIFY(!ref.removeLast());
}
{
QQmlListReference ref(tt.get(), "data");
QCOMPARE(tt->data.count(), 3);
QVERIFY(ref.removeLast());
QCOMPARE(tt->data.count(), 2);
tt.reset();
QVERIFY(!ref.removeLast());
}
{
TestType tt;
tt.property.removeLast = nullptr;
QQmlListReference ref(&tt, "data");
ref.append(&tt);
QVERIFY(!ref.removeLast());
}
}
void tst_qqmllistreference::copy()
{
TestType tt;

View File

@ -449,7 +449,7 @@ void tst_qqmllocale::firstDayOfWeek()
Q_ARG(QVariant, QVariant(locale)));
QVariant val = obj->property("firstDayOfWeek");
QCOMPARE(val.type(), QVariant::Int);
QCOMPARE(val.userType(), QMetaType::Int);
int day = int(QLocale(locale).firstDayOfWeek());
if (day == 7) // JS Date days in range 0(Sunday) to 6(Saturday)

View File

@ -157,7 +157,7 @@ void tst_qqmlmetatype::initTestCase()
void tst_qqmlmetatype::qmlParserStatusCast()
{
QVERIFY(!QQmlMetaType::qmlType(QVariant::Int).isValid());
QVERIFY(!QQmlMetaType::qmlType(QMetaType::Int).isValid());
QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).isValid());
QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).parserStatusCast(), -1);
QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ValueSourceTestType *>()).isValid());
@ -177,7 +177,7 @@ void tst_qqmlmetatype::qmlParserStatusCast()
void tst_qqmlmetatype::qmlPropertyValueSourceCast()
{
QVERIFY(!QQmlMetaType::qmlType(QVariant::Int).isValid());
QVERIFY(!QQmlMetaType::qmlType(QMetaType::Int).isValid());
QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).isValid());
QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).propertyValueSourceCast(), -1);
QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()).isValid());
@ -197,7 +197,7 @@ void tst_qqmlmetatype::qmlPropertyValueSourceCast()
void tst_qqmlmetatype::qmlPropertyValueInterceptorCast()
{
QVERIFY(!QQmlMetaType::qmlType(QVariant::Int).isValid());
QVERIFY(!QQmlMetaType::qmlType(QMetaType::Int).isValid());
QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).isValid());
QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).propertyValueInterceptorCast(), -1);
QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()).isValid());
@ -256,8 +256,8 @@ void tst_qqmlmetatype::prettyTypeName()
void tst_qqmlmetatype::isList()
{
QCOMPARE(QQmlMetaType::isList(QVariant::Invalid), false);
QCOMPARE(QQmlMetaType::isList(QVariant::Int), false);
QCOMPARE(QQmlMetaType::isList(QMetaType::UnknownType), false);
QCOMPARE(QQmlMetaType::isList(QMetaType::Int), false);
QQmlListProperty<TestType> list;
@ -327,10 +327,10 @@ void tst_qqmlmetatype::externalEnums()
QScopedPointer<QObject> obj(c.create());
QVERIFY(obj);
QVariant a = obj->property("a");
QCOMPARE(a.type(), QVariant::Int);
QCOMPARE(a.userType(), QVariant::Int);
QCOMPARE(a.toInt(), int(QStandardPaths::DocumentsLocation));
QVariant b = obj->property("b");
QCOMPARE(b.type(), QVariant::Int);
QCOMPARE(b.userType(), QVariant::Int);
QCOMPARE(b.toInt(), int(QStandardPaths::DocumentsLocation));
}
@ -394,10 +394,10 @@ void tst_qqmlmetatype::unregisterCustomType()
QObject *controller = obj->findChild<QObject *>("controller");
QVERIFY(qobject_cast<Controller1 *>(controller));
QVariant stringVal = controller->property("string");
QCOMPARE(stringVal.type(), QVariant::String);
QCOMPARE(stringVal.userType(), QVariant::String);
QCOMPARE(stringVal.toString(), QStringLiteral("Controller #1"));
QVariant enumVal = controller->property("enumVal");
QCOMPARE(enumVal.type(), QVariant::Int);
QCOMPARE(enumVal.userType(), QVariant::Int);
QCOMPARE(enumVal.toInt(), 1);
}
QQmlMetaType::unregisterType(controllerId);
@ -417,10 +417,10 @@ void tst_qqmlmetatype::unregisterCustomType()
QObject *controller = obj->findChild<QObject *>("controller");
QVERIFY(qobject_cast<Controller2 *>(controller));
QVariant stringVal = controller->property("string");
QCOMPARE(stringVal.type(), QVariant::String);
QCOMPARE(stringVal.userType(), QVariant::String);
QCOMPARE(stringVal.toString(), QStringLiteral("Controller #2"));
QVariant enumVal = controller->property("enumVal");
QCOMPARE(enumVal.type(), QVariant::Int);
QCOMPARE(enumVal.userType(), QVariant::Int);
QCOMPARE(enumVal.toInt(), 111);
}
QQmlMetaType::unregisterType(controllerId);
@ -440,10 +440,10 @@ void tst_qqmlmetatype::unregisterCustomType()
QObject *controller = obj->findChild<QObject *>("controller");
QVERIFY(qobject_cast<Controller1 *>(controller));
QVariant stringVal = controller->property("string");
QCOMPARE(stringVal.type(), QVariant::String);
QCOMPARE(stringVal.userType(), QVariant::String);
QCOMPARE(stringVal.toString(), QStringLiteral("Controller #1"));
QVariant enumVal = controller->property("enumVal");
QCOMPARE(enumVal.type(), QVariant::Int);
QCOMPARE(enumVal.userType(), QVariant::Int);
QCOMPARE(enumVal.toInt(), 1);
}
}
@ -489,7 +489,7 @@ void tst_qqmlmetatype::unregisterCustomSingletonType()
QScopedPointer<QObject> obj(c.create());
QVERIFY(obj.data());
QVariant stringVal = obj->property("text");
QCOMPARE(stringVal.type(), QVariant::String);
QCOMPARE(stringVal.userType(), QVariant::String);
QCOMPARE(stringVal.toString(), QStringLiteral("StaticProvider #1"));
}
QQmlMetaType::unregisterType(staticProviderId);
@ -505,7 +505,7 @@ void tst_qqmlmetatype::unregisterCustomSingletonType()
QScopedPointer<QObject> obj(c.create());
QVERIFY(obj.data());
QVariant stringVal = obj->property("text");
QCOMPARE(stringVal.type(), QVariant::String);
QCOMPARE(stringVal.userType(), QVariant::String);
QCOMPARE(stringVal.toString(), QStringLiteral("StaticProvider #2"));
}
QQmlMetaType::unregisterType(staticProviderId);
@ -521,7 +521,7 @@ void tst_qqmlmetatype::unregisterCustomSingletonType()
QScopedPointer<QObject> obj(c.create());
QVERIFY(obj.data());
QVariant stringVal = obj->property("text");
QCOMPARE(stringVal.type(), QVariant::String);
QCOMPARE(stringVal.userType(), QVariant::String);
QCOMPARE(stringVal.toString(), QStringLiteral("StaticProvider #1"));
}
}

View File

@ -0,0 +1,9 @@
import Test 1.0
import QtQml 2.0
MyTypeObject {
property QtObject colorPropertyObject: colorProperty.object
property string colorPropertyName: colorProperty.name
property QtObject invalidPropertyObject: invalidProperty.object
property string invalidPropertyName: invalidProperty.name
}

View File

@ -71,6 +71,8 @@ class MyTypeObject : public QObject
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)
Q_PROPERTY(QQmlProperty colorProperty READ colorProperty CONSTANT)
Q_PROPERTY(QQmlProperty invalidProperty READ invalidProperty CONSTANT)
public:
MyTypeObject() :
@ -173,6 +175,10 @@ public:
QVariant variant() const { return sizef(); }
QQmlProperty colorProperty() { return QQmlProperty(this, "color"); }
QQmlProperty invalidProperty() const { return QQmlProperty(); }
void emitRunScript() { emit runScript(); }
signals:

View File

@ -67,6 +67,7 @@ private slots:
void color();
void variant();
void locale();
void qmlproperty();
void bindingAssignment();
void bindingRead();
@ -360,6 +361,20 @@ void tst_qqmlvaluetypes::locale()
}
}
void tst_qqmlvaluetypes::qmlproperty()
{
QQmlComponent component(&engine, testFileUrl("qmlproperty_read.qml"));
MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
QVERIFY(object != nullptr);
QCOMPARE(object->property("colorPropertyObject").value<QObject *>(), object);
QCOMPARE(object->property("colorPropertyName").toString(), "color");
QCOMPARE(object->property("invalidPropertyObject").value<QObject *>(), nullptr);
QCOMPARE(object->property("invalidPropertyName").toString(), "");
delete object;
}
void tst_qqmlvaluetypes::sizereadonly()
{
{

View File

@ -0,0 +1,18 @@
import QtQuick 2.0
Rectangle {
width: 200
height: 200
color: "white"
Text {
objectName: "text"
textFormat: Text.RichText
anchors.fill: parent
color: "black"
// display a black rectangle at the top left of the text
text: "<span style=\"background-color:rgba(255,255,255,255);vertical-align:super;\">&#x2588;</span>This is a test"
verticalAlignment: Text.AlignTop
horizontalAlignment: Text.AlignLeft
font.pixelSize: 30
}
}

View File

@ -168,6 +168,8 @@ private slots:
void transparentBackground();
void displaySuperscriptedTag();
private:
QStringList standard;
QStringList richText;
@ -4507,6 +4509,32 @@ void tst_qquicktext::transparentBackground()
QCOMPARE(color.blue(), 255);
QCOMPARE(color.green(), 255);
}
void tst_qquicktext::displaySuperscriptedTag()
{
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
QSKIP("Skipping due to grabToImage not functional on offscreen/minimimal platforms");
QScopedPointer<QQuickView> window(new QQuickView);
window->setSource(testFileUrl("displaySuperscriptedTag.qml"));
QTRY_COMPARE(window->status(), QQuickView::Ready);
window->show();
QVERIFY(QTest::qWaitForWindowExposed(window.data()));
QQuickText *text = window->findChild<QQuickText *>("text");
QVERIFY(text);
QImage img = window->grabWindow();
QCOMPARE(img.isNull(), false);
QColor color = img.pixelColor(1, static_cast<int>(text->contentHeight()) / 4 * 3);
QCOMPARE(color.red(), 255);
QCOMPARE(color.blue(), 255);
QCOMPARE(color.green(), 255);
}
QTEST_MAIN(tst_qquicktext)
#include "tst_qquicktext.moc"

View File

@ -36,7 +36,6 @@
#include <QtQml/qqmllist.h>
#include <QtCore/qrandom.h>
#include <QtCore/qrect.h>
#include <QtGui/qmatrix.h>
#include <QtGui/qcolor.h>
#include <QtGui/qpixmap.h>
#include <QtGui/qvector3d.h>

View File

@ -81,7 +81,7 @@ public:
QQmlListProperty<PartialScene> sceneCompleters()
{
return QQmlListProperty<PartialScene>(this, completers);
return QQmlListProperty<PartialScene>(this, &completers);
}
QList<PartialScene*> completers;

View File

@ -28,6 +28,8 @@
#include "dumpastvisitor.h"
#include <QtQml/private/qqmljslexer_p.h>
DumpAstVisitor::DumpAstVisitor(Node *rootNode, CommentAstVisitor *comment): m_comment(comment)
{
// Add all completely orphaned comments
@ -257,6 +259,22 @@ QString DumpAstVisitor::parseFormalParameterList(FormalParameterList *list)
return result;
}
QString DumpAstVisitor::parsePatternProperty(PatternProperty *property)
{
return escapeString(property->name->asString())+": "+parsePatternElement(property, false);
}
QString DumpAstVisitor::parsePatternPropertyList(PatternPropertyList *list)
{
QString result = "";
for (auto *item = list; item != nullptr; item = item->next) {
result += formatLine(parsePatternProperty(item->property) + (item->next != nullptr ? "," : ""));
}
return result;
}
QString DumpAstVisitor::parseExpression(ExpressionNode *expression)
{
if (expression == nullptr)
@ -288,13 +306,23 @@ QString DumpAstVisitor::parseExpression(ExpressionNode *expression)
auto *functExpr = cast<FunctionExpression *>(expression);
m_indentLevel++;
QString result = "function";
QString result;
if (!functExpr->name.isEmpty())
result += " " + functExpr->name;
if (!functExpr->isArrowFunction) {
result += "function";
result += "("+parseFormalParameterList(functExpr->formals)+") {\n"
+ parseStatementList(functExpr->body);
if (functExpr->isGenerator)
result += "*";
if (!functExpr->name.isEmpty())
result += " " + functExpr->name;
result += "("+parseFormalParameterList(functExpr->formals)+") {\n"
+ parseStatementList(functExpr->body);
} else {
result += "("+parseFormalParameterList(functExpr->formals)+") => {\n";
result += parseStatementList(functExpr->body);
}
m_indentLevel--;
@ -304,6 +332,8 @@ QString DumpAstVisitor::parseExpression(ExpressionNode *expression)
}
case Node::Kind_NullExpression:
return "null";
case Node::Kind_ThisExpression:
return "this";
case Node::Kind_PostIncrementExpression:
return parseExpression(cast<PostIncrementExpression *>(expression)->base)+"++";
case Node::Kind_PreIncrementExpression:
@ -371,6 +401,44 @@ QString DumpAstVisitor::parseExpression(ExpressionNode *expression)
return result;
}
case Node::Kind_ObjectPattern: {
auto *objectPattern = cast<ObjectPattern*>(expression);
QString result = "{\n";
m_indentLevel++;
result += parsePatternPropertyList(objectPattern->properties);
m_indentLevel--;
result += formatLine("}", false);
return result;
}
case Node::Kind_Expression: {
auto* expr = cast<Expression*>(expression);
return parseExpression(expr->left)+", "+parseExpression(expr->right);
}
case Node::Kind_Type: {
auto* type = reinterpret_cast<Type*>(expression);
return parseUiQualifiedId(type->typeId);
}
case Node::Kind_RegExpLiteral: {
auto* regexpLiteral = cast<RegExpLiteral*>(expression);
QString result = "/"+regexpLiteral->pattern+"/";
if (regexpLiteral->flags & QQmlJS::Lexer::RegExp_Unicode)
result += "u";
if (regexpLiteral->flags & QQmlJS::Lexer::RegExp_Global)
result += "g";
if (regexpLiteral->flags & QQmlJS::Lexer::RegExp_Multiline)
result += "m";
if (regexpLiteral->flags & QQmlJS::Lexer::RegExp_Sticky)
result += "y";
if (regexpLiteral->flags & QQmlJS::Lexer::RegExp_IgnoreCase)
result += "i";
return result;
}
default:
m_error = true;
return "unknown_expression_"+QString::number(expression->kind);
@ -383,7 +451,7 @@ QString DumpAstVisitor::parseVariableDeclarationList(VariableDeclarationList *li
for (auto *item = list; item != nullptr; item = item->next) {
result += parsePatternElement(item->declaration, (item == list))
+ (item->next != nullptr ? ", " : "");
+ (item->next != nullptr ? ", " : "");
}
return result;
@ -469,7 +537,7 @@ QString DumpAstVisitor::parseStatement(Statement *statement, bool blockHasNext,
case Node::Kind_VariableStatement:
return parseVariableDeclarationList(cast<VariableStatement *>(statement)->declarations);
case Node::Kind_ReturnStatement:
return "return "+parseExpression(cast<ReturnStatement *>(statement)->expression);
return "return "+parseExpression(cast<ReturnStatement *>(statement)->expression);
case Node::Kind_ContinueStatement:
return "continue";
case Node::Kind_BreakStatement:
@ -705,7 +773,7 @@ bool DumpAstVisitor::visit(UiPublicMember *node) {
addLine("signal "+node->name.toString()+"("+parseUiParameterList(node->parameters) + ")"
+ commentBackInline);
break;
break;
case UiPublicMember::Property: {
if (m_firstProperty) {
if (m_firstOfAll)
@ -912,7 +980,15 @@ bool DumpAstVisitor::visit(FunctionDeclaration *node) {
addNewLine();
addLine(getComment(node, Comment::Location::Front));
addLine("function "+node->name+"("+parseFormalParameterList(node->formals)+") {");
QString head = "function";
if (node->isGenerator)
head += "*";
head += " "+node->name+"("+parseFormalParameterList(node->formals)+") {";
addLine(head);
m_indentLevel++;
m_result += parseStatementList(node->body);
m_indentLevel--;
@ -970,8 +1046,8 @@ bool DumpAstVisitor::visit(UiImport *node) {
result += parseUiQualifiedId(node->importUri);
if (node->version) {
result += " " + QString::number(node->version->majorVersion) + "."
+ QString::number(node->version->minorVersion);
result += " " + QString::number(node->version->majorVersion) + "."
+ QString::number(node->version->minorVersion);
}
if (node->asToken.isValid()) {

View File

@ -89,6 +89,9 @@ private:
QString parsePatternElement(PatternElement *element, bool scope = true);
QString parsePatternElementList(PatternElementList *element);
QString parsePatternProperty(PatternProperty *property);
QString parsePatternPropertyList(PatternPropertyList *list);
QString parseArgumentList(ArgumentList *list);
QString parseUiParameterList(UiParameterList *list);

View File

@ -43,7 +43,7 @@
#include "dumpastvisitor.h"
#include "restructureastvisitor.h"
bool parseFile(const QString& filename, bool inplace, bool verbose, bool sortImports)
bool parseFile(const QString& filename, bool inplace, bool verbose, bool sortImports, bool force)
{
QFile file(filename);
@ -101,8 +101,14 @@ bool parseFile(const QString& filename, bool inplace, bool verbose, bool sortImp
DumpAstVisitor dump(parser.rootNode(), &comment);
if (dump.error())
qWarning().noquote() << "An error has occurred. The output may not be reliable.";
if (dump.error()) {
if (force) {
qWarning().noquote() << "An error has occurred. The output may not be reliable.";
} else {
qWarning().noquote() << "Am error has occurred. Aborting.";
return false;
}
}
if (inplace) {
if (verbose)
@ -145,6 +151,9 @@ int main(int argc, char *argv[])
parser.addOption(QCommandLineOption({"i", "inplace"},
QStringLiteral("Edit file in-place instead of outputting to stdout.")));
parser.addOption(QCommandLineOption({"f", "force"},
QStringLiteral("Continue even if an error has occurred.")));
parser.addPositionalArgument("filenames", "files to be processed by qmlformat");
parser.process(app);
@ -155,7 +164,7 @@ int main(int argc, char *argv[])
parser.showHelp(-1);
for (const QString& file: parser.positionalArguments()) {
if (!parseFile(file, parser.isSet("inplace"), parser.isSet("verbose"), !parser.isSet("no-sort")))
if (!parseFile(file, parser.isSet("inplace"), parser.isSet("verbose"), !parser.isSet("no-sort"), parser.isSet("force")))
success = false;
}
#endif

View File

@ -509,7 +509,7 @@ QString generateCmakeIncludeFileContent(const QVariantList &importList) {
QTextStream s(&content);
int importsCount = 0;
for (const QVariant &importVariant: importList) {
if (static_cast<QMetaType::Type>(importVariant.type()) == QMetaType::QVariantMap) {
if (static_cast<QMetaType::Type>(importVariant.userType()) == QMetaType::QVariantMap) {
s << QStringLiteral("set(qml_import_scanner_import_") << importsCount
<< QStringLiteral(" \"");