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

Change-Id: I06578422b4558feabf7a77426b01e77953ab60e2
This commit is contained in:
Qt Forward Merge Bot 2019-11-14 09:50:23 +01:00
commit 1619b7d207
9 changed files with 120 additions and 55 deletions

View File

@ -401,57 +401,20 @@ void QQmlVMEMetaObject::writeProperty(int id, double v)
void QQmlVMEMetaObject::writeProperty(int id, const QString& v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
md->set(engine, id, engine->newString(v));
}
void QQmlVMEMetaObject::writeProperty(int id, const QUrl& v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
}
void QQmlVMEMetaObject::writeProperty(int id, const QDate& v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
}
void QQmlVMEMetaObject::writeProperty(int id, const QDateTime& v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
}
void QQmlVMEMetaObject::writeProperty(int id, const QPointF& v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
}
void QQmlVMEMetaObject::writeProperty(int id, const QSizeF& v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
}
void QQmlVMEMetaObject::writeProperty(int id, const QRectF& v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
if (md) {
QV4::Scope scope(engine);
QV4::Scoped<QV4::MemberData>(scope, md)->set(engine, id, engine->newString(v));
}
}
void QQmlVMEMetaObject::writeProperty(int id, QObject* v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
md->set(engine, id, QV4::Value::fromReturnedValue(QV4::QObjectWrapper::wrap(engine, v)));
if (md) {
QV4::Scope scope(engine);
QV4::Scoped<QV4::MemberData>(scope, md)->set(engine, id, QV4::Value::fromReturnedValue(
QV4::QObjectWrapper::wrap(engine, v)));
}
QQmlVMEVariantQObjectPtr *guard = getQObjectGuardForProperty(id);
if (v && !guard) {

View File

@ -194,12 +194,18 @@ public:
void writeProperty(int id, bool v);
void writeProperty(int id, double v);
void writeProperty(int id, const QString& v);
void writeProperty(int id, const QPointF& v);
void writeProperty(int id, const QSizeF& v);
void writeProperty(int id, const QUrl& v);
void writeProperty(int id, const QDate& v);
void writeProperty(int id, const QDateTime& v);
void writeProperty(int id, const QRectF& v);
template<typename VariantCompatible>
void writeProperty(int id, const VariantCompatible &v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md) {
QV4::Scope scope(engine);
QV4::Scoped<QV4::MemberData>(scope, md)->set(engine, id, engine->newVariantObject(
QVariant::fromValue(v)));
}
}
void writeProperty(int id, QObject *v);
void ensureQObjectWrapper();

View File

@ -402,6 +402,43 @@ property MyMenu optionsMenu
For information on performance in QML and Qt Quick,
see \l {Performance Considerations And Suggestions}.
\section1 Prefer Declarative Bindings Over Imperative Assignments
In QML, it's possible to use imperative JavaScript code to perform tasks
such as responding to input events, send data over a network, and so on.
Imperative code has an important place in QML, but it's also important
to be aware of when not to use it.
For example, consider the following imperative assignment:
\code
Rectangle {
Component.onCompleted: color = "red"
}
\endcode
This has the following disadvantages:
\list
\li It's slow. The color property will first be evaluated with a
default-constructed value, and then again with "red" later on.
\li It delays errors that could be found at build time to run time, slowing
down the development process.
\li It overwrites any declarative binding that was in place. In most cases this
is intended, but sometimes it can be unintentional.
See \l {Debugging overwriting of bindings} for more information.
\li It interferes with tooling; Qt Quick Designer, for example, doesn't support
JavaScript.
\endlist
The code can be rewritten to be a declarative binding instead:
\code
Rectangle {
color: "red"
}
\endcode
\section1 Tools and Utilities
For information on useful tools and utilies that make working with QML and

View File

@ -433,6 +433,19 @@ void QQuickAccessibleAttached::setRole(QAccessible::Role role)
}
}
bool QQuickAccessibleAttached::wasNameExplicitlySet() const
{
return m_nameExplicitlySet;
}
// Allows types to attach an accessible name to an item as a convenience,
// so long as the user hasn't done so themselves.
void QQuickAccessibleAttached::setNameImplicitly(const QString &name)
{
setName(name);
m_nameExplicitlySet = false;
}
QQuickAccessibleAttached *QQuickAccessibleAttached::qmlAttachedProperties(QObject *obj)
{
return new QQuickAccessibleAttached(obj);

View File

@ -118,7 +118,10 @@ public:
return QString();
return m_name;
}
bool wasNameExplicitlySet() const;
void setName(const QString &name) {
m_nameExplicitlySet = true;
if (name != m_name) {
m_name = name;
Q_EMIT nameChanged();
@ -126,6 +129,7 @@ public:
QAccessible::updateAccessibility(&ev);
}
}
void setNameImplicitly(const QString &name);
QString description() const { return m_description; }
void setDescription(const QString &description)
@ -216,6 +220,7 @@ private:
QAccessible::State m_state;
QAccessible::State m_stateExplicitlySet;
QString m_name;
bool m_nameExplicitlySet = false;
QString m_description;
static QMetaMethod sigPress;

View File

@ -1790,6 +1790,7 @@ void QQuickItemViewPrivate::refill(qreal from, qreal to)
if (prevCount != itemCount)
emit q->countChanged();
} while (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges());
storeFirstVisibleItemPosition();
}
void QQuickItemViewPrivate::regenerate(bool orientationChanged)
@ -1876,6 +1877,7 @@ void QQuickItemViewPrivate::layout()
updateSections();
layoutVisibleItems();
storeFirstVisibleItemPosition();
int lastIndexInView = findLastIndexInView();
refill();
@ -1960,7 +1962,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
prevFirstItemInViewPos = prevFirstItemInView->position();
prevFirstItemInViewIndex = prevFirstItemInView->index;
}
qreal prevVisibleItemsFirstPos = visibleItems.count() ? visibleItems.constFirst()->position() : 0.0;
qreal prevVisibleItemsFirstPos = visibleItems.count() ? firstVisibleItemPosition : 0.0;
totalInsertionResult->visiblePos = prevFirstItemInViewPos;
totalRemovalResult->visiblePos = prevFirstItemInViewPos;
@ -2006,6 +2008,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
if (!insertions.isEmpty()) {
repositionFirstItem(prevVisibleItemsFirst, prevVisibleItemsFirstPos, prevFirstItemInView, &insertionResult, &removalResult);
layoutVisibleItems(removals.first().index);
storeFirstVisibleItemPosition();
}
}
@ -2026,6 +2029,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
if (i < insertions.count() - 1) {
repositionFirstItem(prevVisibleItemsFirst, prevVisibleItemsFirstPos, prevFirstItemInView, &insertionResult, &removalResult);
layoutVisibleItems(insertions[i].index);
storeFirstVisibleItemPosition();
}
itemCount += insertions[i].count;
}

View File

@ -260,6 +260,12 @@ public:
MovementReason moveReason;
QList<FxViewItem *> visibleItems;
qreal firstVisibleItemPosition = 0;
void storeFirstVisibleItemPosition() {
if (!visibleItems.isEmpty()) {
firstVisibleItemPosition = visibleItems.constFirst()->position();
}
}
int visibleIndex;
int currentIndex;
FxViewItem *currentItem;

View File

@ -805,6 +805,7 @@ void QQuickListViewPrivate::layoutVisibleItems(int fromModelIndex)
FxViewItem *firstItem = *visibleItems.constBegin();
bool fixedCurrent = currentItem && firstItem->item == currentItem->item;
firstVisibleItemPosition = firstItem->position();
qreal sum = firstItem->size();
qreal pos = firstItem->position() + firstItem->size() + spacing;
firstItem->setVisible(firstItem->endPosition() >= from && firstItem->position() <= to);

View File

@ -185,7 +185,8 @@ void tst_QQuickAccessible::quickAttachedProperties()
QObject *object = component.create();
QVERIFY(object != nullptr);
QObject *attachedObject = QQuickAccessibleAttached::attachedProperties(object);
const auto attachedObject = qobject_cast<QQuickAccessibleAttached*>(
QQuickAccessibleAttached::attachedProperties(object));
QVERIFY(attachedObject);
if (attachedObject) {
QVariant p = attachedObject->property("role");
@ -195,6 +196,7 @@ void tst_QQuickAccessible::quickAttachedProperties()
QCOMPARE(p.isNull(), true);
p = attachedObject->property("description");
QCOMPARE(p.isNull(), true);
QCOMPARE(attachedObject->wasNameExplicitlySet(), false);
}
delete object;
}
@ -211,7 +213,8 @@ void tst_QQuickAccessible::quickAttachedProperties()
QObject *object = component.create();
QVERIFY(object != nullptr);
QObject *attachedObject = QQuickAccessibleAttached::attachedProperties(object);
const auto attachedObject = qobject_cast<QQuickAccessibleAttached*>(
QQuickAccessibleAttached::attachedProperties(object));
QVERIFY(attachedObject);
if (attachedObject) {
QVariant p = attachedObject->property("role");
@ -223,6 +226,7 @@ void tst_QQuickAccessible::quickAttachedProperties()
p = attachedObject->property("description");
QCOMPARE(p.isNull(), false);
QCOMPARE(p.toString(), QLatin1String("Duck"));
QCOMPARE(attachedObject->wasNameExplicitlySet(), true);
}
delete object;
}
@ -292,6 +296,32 @@ void tst_QQuickAccessible::quickAttachedProperties()
}
delete object;
}
// Check that a name can be implicitly set.
{
QQmlEngine engine;
QQmlComponent component(&engine);
component.setData(R"(
import QtQuick 2.0
Text {
Accessible.role: Accessible.Button
Accessible.description: "Text Button"
})", QUrl());
QScopedPointer<QObject> object(component.create());
QVERIFY(object);
const auto attachedObject = qobject_cast<QQuickAccessibleAttached*>(
QQuickAccessibleAttached::attachedProperties(object.data()));
QVERIFY(attachedObject);
QVERIFY(!attachedObject->wasNameExplicitlySet());
attachedObject->setNameImplicitly(QLatin1String("Implicit"));
QCOMPARE(attachedObject->name(), QLatin1String("Implicit"));
QVERIFY(!attachedObject->wasNameExplicitlySet());
attachedObject->setName(QLatin1String("Explicit"));
QCOMPARE(attachedObject->name(), QLatin1String("Explicit"));
QVERIFY(attachedObject->wasNameExplicitlySet());
}
QTestAccessibility::clearEvents();
}