aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick')
-rw-r--r--src/quick/designer/designer.pri25
-rw-r--r--src/quick/designer/qqmldesignermetaobject.cpp340
-rw-r--r--src/quick/designer/qqmldesignermetaobject_p.h105
-rw-r--r--src/quick/designer/qquickdesignercustomobjectdata.cpp282
-rw-r--r--src/quick/designer/qquickdesignercustomobjectdata_p.h100
-rw-r--r--src/quick/designer/qquickdesignersupport.cpp (renamed from src/quick/designer/designersupport.cpp)96
-rw-r--r--src/quick/designer/qquickdesignersupport_p.h (renamed from src/quick/designer/designersupport.h)22
-rw-r--r--src/quick/designer/qquickdesignersupportitems.cpp320
-rw-r--r--src/quick/designer/qquickdesignersupportitems_p.h77
-rw-r--r--src/quick/designer/qquickdesignersupportmetainfo.cpp68
-rw-r--r--src/quick/designer/qquickdesignersupportmetainfo_p.h64
-rw-r--r--src/quick/designer/qquickdesignersupportproperties.cpp233
-rw-r--r--src/quick/designer/qquickdesignersupportproperties_p.h98
-rw-r--r--src/quick/designer/qquickdesignersupportpropertychanges.cpp135
-rw-r--r--src/quick/designer/qquickdesignersupportpropertychanges_p.h70
-rw-r--r--src/quick/designer/qquickdesignersupportstates.cpp119
-rw-r--r--src/quick/designer/qquickdesignersupportstates_p.h76
-rw-r--r--src/quick/designer/qquickdesignerwindowmanager.cpp (renamed from src/quick/designer/designerwindowmanager.cpp)25
-rw-r--r--src/quick/designer/qquickdesignerwindowmanager_p.h (renamed from src/quick/designer/designerwindowmanager_p.h)4
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp4
-rw-r--r--src/quick/items/context2d/qquickcanvasitem_p.h4
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp28
-rw-r--r--src/quick/items/context2d/qquickcontext2d_p.h2
-rw-r--r--src/quick/items/qquickanchors.cpp28
-rw-r--r--src/quick/items/qquickanimatedsprite_p.h2
-rw-r--r--src/quick/items/qquickborderimage_p.h2
-rw-r--r--src/quick/items/qquickdrag_p.h3
-rw-r--r--src/quick/items/qquickflickable.cpp19
-rw-r--r--src/quick/items/qquickflickable_p.h2
-rw-r--r--src/quick/items/qquickflipable_p.h2
-rw-r--r--src/quick/items/qquickframebufferobject.cpp31
-rw-r--r--src/quick/items/qquickframebufferobject.h5
-rw-r--r--src/quick/items/qquickgridview.cpp14
-rw-r--r--src/quick/items/qquickgridview_p.h4
-rw-r--r--src/quick/items/qquickimage_p.h8
-rw-r--r--src/quick/items/qquickimagebase.cpp30
-rw-r--r--src/quick/items/qquickimagebase_p.h2
-rw-r--r--src/quick/items/qquickimplicitsizeitem_p_p.h2
-rw-r--r--src/quick/items/qquickitem.cpp93
-rw-r--r--src/quick/items/qquickitem.h2
-rw-r--r--src/quick/items/qquickitem_p.h31
-rw-r--r--src/quick/items/qquickitemanimation_p.h2
-rw-r--r--src/quick/items/qquickitemsmodule.cpp20
-rw-r--r--src/quick/items/qquickitemview.cpp112
-rw-r--r--src/quick/items/qquickitemview_p.h9
-rw-r--r--src/quick/items/qquickitemview_p_p.h6
-rw-r--r--src/quick/items/qquickitemviewtransition.cpp1
-rw-r--r--src/quick/items/qquickitemviewtransition_p.h12
-rw-r--r--src/quick/items/qquicklistview.cpp64
-rw-r--r--src/quick/items/qquicklistview_p.h12
-rw-r--r--src/quick/items/qquickloader.cpp7
-rw-r--r--src/quick/items/qquickloader_p.h2
-rw-r--r--src/quick/items/qquickloader_p_p.h3
-rw-r--r--src/quick/items/qquickopenglinfo_p.h3
-rw-r--r--src/quick/items/qquickpainteditem.h2
-rw-r--r--src/quick/items/qquickpainteditem_p.h2
-rw-r--r--src/quick/items/qquickpathview.cpp159
-rw-r--r--src/quick/items/qquickpathview_p.h7
-rw-r--r--src/quick/items/qquickpathview_p_p.h1
-rw-r--r--src/quick/items/qquickpincharea_p.h2
-rw-r--r--src/quick/items/qquickpositioners.cpp319
-rw-r--r--src/quick/items/qquickpositioners_p.h46
-rw-r--r--src/quick/items/qquickpositioners_p_p.h23
-rw-r--r--src/quick/items/qquickrectangle_p.h2
-rw-r--r--src/quick/items/qquickrendercontrol.cpp1
-rw-r--r--src/quick/items/qquickrepeater.cpp25
-rw-r--r--src/quick/items/qquickscalegrid_p_p.h1
-rw-r--r--src/quick/items/qquickshadereffect_p.h4
-rw-r--r--src/quick/items/qquickshadereffectnode.cpp4
-rw-r--r--src/quick/items/qquickshadereffectsource_p.h3
-rw-r--r--src/quick/items/qquickstateoperations.cpp201
-rw-r--r--src/quick/items/qquickstateoperations_p.h8
-rw-r--r--src/quick/items/qquicktext.cpp284
-rw-r--r--src/quick/items/qquicktext_p.h49
-rw-r--r--src/quick/items/qquicktext_p_p.h20
-rw-r--r--src/quick/items/qquicktextcontrol.cpp4
-rw-r--r--src/quick/items/qquicktextedit.cpp278
-rw-r--r--src/quick/items/qquicktextedit_p.h47
-rw-r--r--src/quick/items/qquicktextedit_p_p.h31
-rw-r--r--src/quick/items/qquicktextinput.cpp447
-rw-r--r--src/quick/items/qquicktextinput_p.h85
-rw-r--r--src/quick/items/qquicktextinput_p_p.h24
-rw-r--r--src/quick/items/qquicktextnode.cpp45
-rw-r--r--src/quick/items/qquicktextnode_p.h4
-rw-r--r--src/quick/items/qquicktextnodeengine.cpp2
-rw-r--r--src/quick/items/qquicktextnodeengine_p.h2
-rw-r--r--src/quick/items/qquickview.cpp31
-rw-r--r--src/quick/items/qquickview.h3
-rw-r--r--src/quick/items/qquickwindow.cpp123
-rw-r--r--src/quick/items/qquickwindow.h8
-rw-r--r--src/quick/items/qquickwindow_p.h2
-rw-r--r--src/quick/qtquick2.cpp16
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp47
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h18
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer.cpp4
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp70
-rw-r--r--src/quick/scenegraph/qsgcontext_p.h10
-rw-r--r--src/quick/scenegraph/qsgdefaultglyphnode_p.cpp11
-rw-r--r--src/quick/scenegraph/qsgdistancefieldglyphnode.cpp6
-rw-r--r--src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp11
-rw-r--r--src/quick/scenegraph/qsgrenderloop.cpp16
-rw-r--r--src/quick/scenegraph/qsgrenderloop_p.h2
-rw-r--r--src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp655
-rw-r--r--src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h124
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp64
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop_p.h1
-rw-r--r--src/quick/scenegraph/scenegraph.pri2
-rw-r--r--src/quick/scenegraph/util/qsgatlastexture.cpp6
-rw-r--r--src/quick/scenegraph/util/qsgatlastexture_p.h3
-rw-r--r--src/quick/scenegraph/util/qsgengine.cpp15
-rw-r--r--src/quick/scenegraph/util/qsgengine.h3
-rw-r--r--src/quick/util/qquickanimation_p.h4
-rw-r--r--src/quick/util/qquickanimation_p_p.h2
-rw-r--r--src/quick/util/qquickanimator_p.h3
-rw-r--r--src/quick/util/qquickanimatorjob.cpp5
-rw-r--r--src/quick/util/qquickanimatorjob_p.h1
-rw-r--r--src/quick/util/qquickfontloader_p.h2
-rw-r--r--src/quick/util/qquickglobal.cpp5
-rw-r--r--src/quick/util/qquickimageprovider.cpp126
-rw-r--r--src/quick/util/qquickimageprovider.h32
-rw-r--r--src/quick/util/qquickpath_p.h2
-rw-r--r--src/quick/util/qquickpixmapcache.cpp242
-rw-r--r--src/quick/util/qquickprofiler.cpp24
-rw-r--r--src/quick/util/qquickprofiler_p.h2
-rw-r--r--src/quick/util/qquickpropertychanges.cpp32
-rw-r--r--src/quick/util/qquicksmoothedanimation_p.h2
-rw-r--r--src/quick/util/qquickstate.cpp49
-rw-r--r--src/quick/util/qquickstate_p.h12
-rw-r--r--src/quick/util/qquickstate_p_p.h10
-rw-r--r--src/quick/util/qquickstatechangescript.cpp2
-rw-r--r--src/quick/util/qquickstatechangescript_p.h2
-rw-r--r--src/quick/util/qquickstyledtext.cpp4
-rw-r--r--src/quick/util/qquicksystempalette_p.h2
-rw-r--r--src/quick/util/qquicktimeline.cpp2
-rw-r--r--src/quick/util/qquicktransitionmanager.cpp28
-rw-r--r--src/quick/util/qquickutilmodule.cpp8
-rw-r--r--src/quick/util/qquickvalidator.cpp221
-rw-r--r--src/quick/util/qquickvalidator_p.h83
-rw-r--r--src/quick/util/qquickvaluetypes.cpp10
-rw-r--r--src/quick/util/qquickvaluetypes_p.h8
-rw-r--r--src/quick/util/util.pri6
141 files changed, 5148 insertions, 1996 deletions
diff --git a/src/quick/designer/designer.pri b/src/quick/designer/designer.pri
index 9f3f7e8be6..eb2141134d 100644
--- a/src/quick/designer/designer.pri
+++ b/src/quick/designer/designer.pri
@@ -1,4 +1,21 @@
-HEADERS += designer/designersupport.h \
- designer/designerwindowmanager_p.h
-SOURCES += designer/designersupport.cpp \
- designer/designerwindowmanager.cpp
+HEADERS += \
+ designer/qquickdesignercustomobjectdata_p.h \
+ designer/qquickdesignersupportitems_p.h \
+ designer/qquickdesignerwindowmanager_p.h \
+ designer/qquickdesignersupportstates_p.h \
+ designer/qquickdesignersupportpropertychanges_p.h \
+ designer/qquickdesignersupportproperties_p.h \
+ designer/qquickdesignersupportmetainfo_p.h \
+ designer/qqmldesignermetaobject_p.h \
+ designer/qquickdesignersupport_p.h
+
+SOURCES += \
+ designer/qquickdesignercustomobjectdata.cpp \
+ designer/qquickdesignersupport.cpp \
+ designer/qquickdesignersupportitems.cpp \
+ designer/qquickdesignersupportmetainfo.cpp \
+ designer/qquickdesignersupportproperties.cpp \
+ designer/qquickdesignersupportpropertychanges.cpp \
+ designer/qquickdesignersupportstates.cpp \
+ designer/qquickdesignerwindowmanager.cpp \
+ designer/qqmldesignermetaobject.cpp
diff --git a/src/quick/designer/qqmldesignermetaobject.cpp b/src/quick/designer/qqmldesignermetaobject.cpp
new file mode 100644
index 0000000000..4273c0fbc2
--- /dev/null
+++ b/src/quick/designer/qqmldesignermetaobject.cpp
@@ -0,0 +1,340 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmldesignermetaobject_p.h"
+
+#include <QSharedPointer>
+#include <QMetaProperty>
+#include <qnumeric.h>
+#include <QDebug>
+
+#include <private/qqmlengine_p.h>
+#include <private/qqmlpropertycache_p.h>
+
+QT_BEGIN_NAMESPACE
+
+static QHash<QDynamicMetaObjectData *, bool> nodeInstanceMetaObjectList;
+static void (*notifyPropertyChangeCallBack)(QObject*, const QQuickDesignerSupport::PropertyName &propertyName) = 0;
+
+struct MetaPropertyData {
+ inline QPair<QVariant, bool> &getDataRef(int idx) {
+ while (m_data.count() <= idx)
+ m_data << QPair<QVariant, bool>(QVariant(), false);
+ return m_data[idx];
+ }
+
+ inline QVariant &getData(int idx) {
+ QPair<QVariant, bool> &prop = getDataRef(idx);
+ if (!prop.second) {
+ prop.first = QVariant();
+ prop.second = true;
+ }
+ return prop.first;
+ }
+
+ inline bool hasData(int idx) const {
+ if (idx >= m_data.count())
+ return false;
+ return m_data[idx].second;
+ }
+
+ inline int count() { return m_data.count(); }
+
+ QVector<QPair<QVariant, bool> > m_data;
+};
+
+static bool constructedMetaData(const QQmlVMEMetaData* data)
+{
+ return data->varPropertyCount == 0
+ && data->propertyCount == 0
+ && data->aliasCount == 0
+ && data->signalCount == 0
+ && data->methodCount == 0;
+}
+
+static QQmlVMEMetaData* fakeMetaData()
+{
+ QQmlVMEMetaData* data = new QQmlVMEMetaData;
+ data->varPropertyCount = 0;
+ data->propertyCount = 0;
+ data->aliasCount = 0;
+ data->signalCount = 0;
+ data->methodCount = 0;
+
+ return data;
+}
+
+static const QQmlVMEMetaData* vMEMetaDataForObject(QObject *object)
+{
+ QQmlVMEMetaObject *metaObject = QQmlVMEMetaObject::get(object);
+ if (metaObject)
+ return metaObject->metaData;
+
+ return fakeMetaData();
+}
+
+static QQmlPropertyCache *cacheForObject(QObject *object, QQmlEngine *engine)
+{
+ QQmlVMEMetaObject *metaObject = QQmlVMEMetaObject::get(object);
+ if (metaObject)
+ return metaObject->cache;
+
+ return QQmlEnginePrivate::get(engine)->cache(object);
+}
+
+QQmlDesignerMetaObject* QQmlDesignerMetaObject::getNodeInstanceMetaObject(QObject *object, QQmlEngine *engine)
+{
+ //Avoid setting up multiple MetaObjects on the same QObject
+ QObjectPrivate *op = QObjectPrivate::get(object);
+ QDynamicMetaObjectData *parent = op->metaObject;
+ if (nodeInstanceMetaObjectList.contains(parent))
+ return static_cast<QQmlDesignerMetaObject *>(parent);
+
+ // we just create one and the ownership goes automatically to the object in nodeinstance see init method
+ return new QQmlDesignerMetaObject(object, engine);
+}
+
+void QQmlDesignerMetaObject::init(QObject *object, QQmlEngine *engine)
+{
+ //Creating QQmlOpenMetaObjectType
+ m_type = new QQmlOpenMetaObjectType(metaObjectParent(), engine);
+ m_type->addref();
+ //Assigning type to this
+ copyTypeMetaObject();
+
+ //Assign this to object
+ QObjectPrivate *op = QObjectPrivate::get(object);
+ op->metaObject = this;
+
+ //create cache
+ cache = m_cache = QQmlEnginePrivate::get(engine)->cache(this);
+ cache->addref();
+
+ //If our parent is not a VMEMetaObject we just se the flag to false again
+ if (constructedMetaData(metaData))
+ QQmlData::get(object)->hasVMEMetaObject = false;
+
+ nodeInstanceMetaObjectList.insert(this, true);
+ hasAssignedMetaObjectData = true;
+}
+
+QQmlDesignerMetaObject::QQmlDesignerMetaObject(QObject *object, QQmlEngine *engine)
+ : QQmlVMEMetaObject(object, cacheForObject(object, engine), vMEMetaDataForObject(object)),
+ m_context(engine->contextForObject(object)),
+ m_data(new MetaPropertyData),
+ m_cache(0)
+{
+ init(object, engine);
+
+ QQmlData *ddata = QQmlData::get(object, false);
+
+ //Assign cache to object
+ if (ddata && ddata->propertyCache) {
+ cache->setParent(ddata->propertyCache);
+ cache->invalidate(engine, this);
+ ddata->propertyCache = m_cache;
+ }
+
+}
+
+QQmlDesignerMetaObject::~QQmlDesignerMetaObject()
+{
+ if (cache->count() > 1) // qml is crashing because the property cache is not removed from the engine
+ cache->release();
+ else
+ m_type->release();
+
+ nodeInstanceMetaObjectList.remove(this);
+}
+
+void QQmlDesignerMetaObject::createNewDynamicProperty(const QString &name)
+{
+ int id = m_type->createProperty(name.toUtf8());
+ copyTypeMetaObject();
+ setValue(id, QVariant());
+ Q_ASSERT(id >= 0);
+ Q_UNUSED(id);
+
+ //Updating cache
+ QQmlPropertyCache *oldParent = m_cache->parent();
+ QQmlEnginePrivate::get(m_context->engine())->cache(this)->invalidate(m_context->engine(), this);
+ m_cache->setParent(oldParent);
+
+ QQmlProperty property(myObject(), name, m_context);
+ Q_ASSERT(property.isValid());
+}
+
+void QQmlDesignerMetaObject::setValue(int id, const QVariant &value)
+{
+ QPair<QVariant, bool> &prop = m_data->getDataRef(id);
+ prop.first = propertyWriteValue(id, value);
+ prop.second = true;
+ QMetaObject::activate(myObject(), id + m_type->signalOffset(), 0);
+}
+
+QVariant QQmlDesignerMetaObject::propertyWriteValue(int, const QVariant &value)
+{
+ return value;
+}
+
+const QAbstractDynamicMetaObject *QQmlDesignerMetaObject::dynamicMetaObjectParent() const
+{
+ if (QQmlVMEMetaObject::parent.isT1())
+ return QQmlVMEMetaObject::parent.asT1()->toDynamicMetaObject(QQmlVMEMetaObject::object);
+ else
+ return 0;
+}
+
+const QMetaObject *QQmlDesignerMetaObject::metaObjectParent() const
+{
+ if (QQmlVMEMetaObject::parent.isT1())
+ return QQmlVMEMetaObject::parent.asT1()->toDynamicMetaObject(QQmlVMEMetaObject::object);
+
+ return QQmlVMEMetaObject::parent.asT2();
+}
+
+int QQmlDesignerMetaObject::propertyOffset() const
+{
+ return cache->propertyOffset();
+}
+
+int QQmlDesignerMetaObject::openMetaCall(QMetaObject::Call call, int id, void **a)
+{
+ if ((call == QMetaObject::ReadProperty || call == QMetaObject::WriteProperty)
+ && id >= m_type->propertyOffset()) {
+ int propId = id - m_type->propertyOffset();
+ if (call == QMetaObject::ReadProperty) {
+ //propertyRead(propId);
+ *reinterpret_cast<QVariant *>(a[0]) = m_data->getData(propId);
+ } else if (call == QMetaObject::WriteProperty) {
+ if (propId <= m_data->count() || m_data->m_data[propId].first != *reinterpret_cast<QVariant *>(a[0])) {
+ //propertyWrite(propId);
+ QPair<QVariant, bool> &prop = m_data->getDataRef(propId);
+ prop.first = propertyWriteValue(propId, *reinterpret_cast<QVariant *>(a[0]));
+ prop.second = true;
+ //propertyWritten(propId);
+ activate(myObject(), m_type->signalOffset() + propId, 0);
+ }
+ }
+ return -1;
+ } else {
+ QAbstractDynamicMetaObject *directParent = parent();
+ if (directParent)
+ return directParent->metaCall(call, id, a);
+ else
+ return myObject()->qt_metacall(call, id, a);
+ }
+}
+
+int QQmlDesignerMetaObject::metaCall(QMetaObject::Call call, int id, void **a)
+{
+ int metaCallReturnValue = -1;
+
+ const QMetaProperty propertyById = QQmlVMEMetaObject::property(id);
+
+ if (call == QMetaObject::WriteProperty
+ && propertyById.userType() == QMetaType::QVariant
+ && reinterpret_cast<QVariant *>(a[0])->type() == QVariant::Double
+ && qIsNaN(reinterpret_cast<QVariant *>(a[0])->toDouble())) {
+ return -1;
+ }
+
+ if (call == QMetaObject::WriteProperty
+ && propertyById.userType() == QMetaType::Double
+ && qIsNaN(*reinterpret_cast<double*>(a[0]))) {
+ return -1;
+ }
+
+ if (call == QMetaObject::WriteProperty
+ && propertyById.userType() == QMetaType::Float
+ && qIsNaN(*reinterpret_cast<float*>(a[0]))) {
+ return -1;
+ }
+
+ QVariant oldValue;
+
+ if (call == QMetaObject::WriteProperty && !propertyById.hasNotifySignal())
+ {
+ oldValue = propertyById.read(myObject());
+ }
+
+ QAbstractDynamicMetaObject *directParent = parent();
+ if (directParent && id < directParent->propertyOffset()) {
+ metaCallReturnValue = directParent->metaCall(call, id, a);
+ } else {
+ openMetaCall(call, id, a);
+ }
+
+
+ if (call == QMetaObject::WriteProperty
+ && !propertyById.hasNotifySignal()
+ && oldValue != propertyById.read(myObject()))
+ notifyPropertyChange(id);
+
+ return metaCallReturnValue;
+}
+
+void QQmlDesignerMetaObject::notifyPropertyChange(int id)
+{
+ const QMetaProperty propertyById = property(id);
+
+ if (id < propertyOffset()) {
+ if (notifyPropertyChangeCallBack)
+ notifyPropertyChangeCallBack(myObject(), propertyById.name());
+ } else {
+ if (notifyPropertyChangeCallBack)
+ notifyPropertyChangeCallBack(myObject(), name(id - propertyOffset()));
+ }
+}
+
+int QQmlDesignerMetaObject::count() const
+{
+ return m_type->propertyCount();
+}
+
+QByteArray QQmlDesignerMetaObject::name(int idx) const
+{
+ return m_type->propertyName(idx);
+}
+
+void QQmlDesignerMetaObject::copyTypeMetaObject()
+{
+ *static_cast<QMetaObject *>(this) = *m_type->metaObject();
+}
+
+void QQmlDesignerMetaObject::registerNotifyPropertyChangeCallBack(void (*callback)(QObject *, const QQuickDesignerSupport::PropertyName &))
+{
+ notifyPropertyChangeCallBack = callback;
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/designer/qqmldesignermetaobject_p.h b/src/quick/designer/qqmldesignermetaobject_p.h
new file mode 100644
index 0000000000..eca4fb6a99
--- /dev/null
+++ b/src/quick/designer/qqmldesignermetaobject_p.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef NODEINSTANCEMETAOBJECT_H
+#define NODEINSTANCEMETAOBJECT_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qquickdesignersupport_p.h"
+
+#include <QQmlContext>
+#include <QScopedPointer>
+#include <private/qqmlopenmetaobject_p.h>
+#include <private/qqmlvmemetaobject_p.h>
+
+QT_BEGIN_NAMESPACE
+
+struct MetaPropertyData;
+
+class QQmlDesignerMetaObject : public QQmlVMEMetaObject
+{
+public:
+ ~QQmlDesignerMetaObject();
+
+ static void registerNotifyPropertyChangeCallBack(void (*callback)(QObject*, const QQuickDesignerSupport::PropertyName &propertyName));
+
+protected:
+ QQmlDesignerMetaObject(QObject *object, QQmlEngine *engine);
+ static QQmlDesignerMetaObject* getNodeInstanceMetaObject(QObject *object, QQmlEngine *engine);
+
+ void createNewDynamicProperty(const QString &name);
+ int openMetaCall(QMetaObject::Call _c, int _id, void **_a);
+ int metaCall(QMetaObject::Call _c, int _id, void **_a);
+ void notifyPropertyChange(int id);
+ void setValue(int id, const QVariant &value);
+ QVariant propertyWriteValue(int, const QVariant &);
+
+ QObject *myObject() const { return QQmlVMEMetaObject::object; }
+ QAbstractDynamicMetaObject *parent() const { return const_cast<QAbstractDynamicMetaObject *>(dynamicMetaObjectParent()); }
+
+ const QAbstractDynamicMetaObject *dynamicMetaObjectParent() const;
+
+ const QMetaObject *metaObjectParent() const;
+
+ int propertyOffset() const;
+
+ int count() const;
+ QByteArray name(int) const;
+
+ void copyTypeMetaObject();
+
+private:
+ void init(QObject *, QQmlEngine *engine);
+
+ QPointer<QQmlContext> m_context;
+ QQmlOpenMetaObjectType *m_type;
+ QScopedPointer<MetaPropertyData> m_data;
+ //QAbstractDynamicMetaObject *m_parent;
+ QQmlPropertyCache *m_cache;
+
+ friend class QQuickDesignerSupportProperties;
+};
+
+QT_END_NAMESPACE
+
+#endif // NODEINSTANCEMETAOBJECT_H
diff --git a/src/quick/designer/qquickdesignercustomobjectdata.cpp b/src/quick/designer/qquickdesignercustomobjectdata.cpp
new file mode 100644
index 0000000000..1666ffb0a5
--- /dev/null
+++ b/src/quick/designer/qquickdesignercustomobjectdata.cpp
@@ -0,0 +1,282 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickdesignersupportmetainfo_p.h"
+#include "qquickdesignersupportproperties_p.h"
+
+#include "qquickdesignercustomobjectdata_p.h"
+
+#include <QGlobalStatic>
+#include <QQmlContext>
+#include <QQmlEngine>
+
+#include <private/qqmlbinding_p.h>
+
+QT_BEGIN_NAMESPACE
+
+typedef QHash<QObject*, QQuickDesignerCustomObjectData*> CustomObjectDataHash;
+Q_GLOBAL_STATIC(CustomObjectDataHash, s_designerObjectToDataHash)
+
+struct HandleDestroyedFunctor {
+ QQuickDesignerCustomObjectData *data;
+ void operator()() { data->handleDestroyed(); }
+};
+
+QQuickDesignerCustomObjectData::QQuickDesignerCustomObjectData(QObject *object)
+ : m_object(object)
+{
+ if (object) {
+ populateResetHashes();
+ s_designerObjectToDataHash()->insert(object, this);
+
+ HandleDestroyedFunctor functor;
+ functor.data = this;
+ QObject::connect(object, &QObject::destroyed, functor);
+ }
+}
+
+void QQuickDesignerCustomObjectData::registerData(QObject *object)
+{
+ new QQuickDesignerCustomObjectData(object);
+}
+
+QQuickDesignerCustomObjectData *QQuickDesignerCustomObjectData::get(QObject *object)
+{
+ return s_designerObjectToDataHash()->value(object);
+}
+
+QVariant QQuickDesignerCustomObjectData::getResetValue(QObject *object, const QQuickDesignerSupport::PropertyName &propertyName)
+{
+ QQuickDesignerCustomObjectData* data = get(object);
+
+ if (data)
+ return data->getResetValue(propertyName);
+
+ return QVariant();
+}
+
+void QQuickDesignerCustomObjectData::doResetProperty(QObject *object, QQmlContext *context, const QQuickDesignerSupport::PropertyName &propertyName)
+{
+ QQuickDesignerCustomObjectData* data = get(object);
+
+ if (data)
+ data->doResetProperty(context, propertyName);
+}
+
+bool QQuickDesignerCustomObjectData::hasValidResetBinding(QObject *object, const QQuickDesignerSupport::PropertyName &propertyName)
+{
+ QQuickDesignerCustomObjectData* data = get(object);
+
+ if (data)
+ return data->hasValidResetBinding(propertyName);
+
+ return false;
+}
+
+bool QQuickDesignerCustomObjectData::hasBindingForProperty(QObject *object,
+ QQmlContext *context,
+ const QQuickDesignerSupport::PropertyName &propertyName,
+ bool *hasChanged)
+{
+ QQuickDesignerCustomObjectData* data = get(object);
+
+ if (data)
+ return data->hasBindingForProperty(context, propertyName, hasChanged);
+
+ return false;
+}
+
+void QQuickDesignerCustomObjectData::setPropertyBinding(QObject *object,
+ QQmlContext *context,
+ const QQuickDesignerSupport::PropertyName &propertyName,
+ const QString &expression)
+{
+ QQuickDesignerCustomObjectData* data = get(object);
+
+ if (data)
+ data->setPropertyBinding(context, propertyName, expression);
+}
+
+void QQuickDesignerCustomObjectData::keepBindingFromGettingDeleted(QObject *object,
+ QQmlContext *context,
+ const QQuickDesignerSupport::PropertyName &propertyName)
+{
+ QQuickDesignerCustomObjectData* data = get(object);
+
+ if (data)
+ data->keepBindingFromGettingDeleted(context, propertyName);
+}
+
+void QQuickDesignerCustomObjectData::populateResetHashes()
+{
+ QQuickDesignerSupport::PropertyNameList propertyNameList =
+ QQuickDesignerSupportProperties::propertyNameListForWritableProperties(object());
+
+ Q_FOREACH (const QQuickDesignerSupport::PropertyName &propertyName, propertyNameList) {
+ QQmlProperty property(object(), QString::fromUtf8(propertyName), QQmlEngine::contextForObject(object()));
+
+ QQmlAbstractBinding::Ptr binding = QQmlAbstractBinding::Ptr(QQmlPropertyPrivate::binding(property));
+
+ if (binding) {
+ m_resetBindingHash.insert(propertyName, binding);
+ } else if (property.isWritable()) {
+ m_resetValueHash.insert(propertyName, property.read());
+ }
+ }
+}
+
+QObject *QQuickDesignerCustomObjectData::object() const
+{
+ return m_object;
+}
+
+QVariant QQuickDesignerCustomObjectData::getResetValue(const QQuickDesignerSupport::PropertyName &propertyName) const
+{
+ return m_resetValueHash.value(propertyName);
+}
+
+void QQuickDesignerCustomObjectData::doResetProperty(QQmlContext *context, const QQuickDesignerSupport::PropertyName &propertyName)
+{
+ QQmlProperty property(object(), QString::fromUtf8(propertyName), context);
+
+ if (!property.isValid())
+ return;
+
+ QQmlAbstractBinding *binding = QQmlPropertyPrivate::binding(property);
+ if (binding && !(hasValidResetBinding(propertyName) && getResetBinding(propertyName) == binding)) {
+ binding->setEnabled(false, 0);
+ }
+
+
+ if (hasValidResetBinding(propertyName)) {
+ QQmlAbstractBinding *binding = getResetBinding(propertyName);
+
+ QQmlBinding *qmlBinding = dynamic_cast<QQmlBinding*>(binding);
+ if (qmlBinding)
+ qmlBinding->setTarget(property);
+ QQmlPropertyPrivate::setBinding(binding, QQmlPropertyPrivate::None, QQmlPropertyPrivate::DontRemoveBinding);
+ if (qmlBinding)
+ qmlBinding->update();
+
+ } else if (property.isResettable()) {
+ property.reset();
+ } else if (property.propertyTypeCategory() == QQmlProperty::List) {
+ QQmlListReference list = qvariant_cast<QQmlListReference>(property.read());
+
+ if (!QQuickDesignerSupportProperties::hasFullImplementedListInterface(list)) {
+ qWarning() << "Property list interface not fully implemented for Class " << property.property().typeName() << " in property " << property.name() << "!";
+ return;
+ }
+
+ list.clear();
+ } else if (property.isWritable()) {
+ if (property.read() == getResetValue(propertyName))
+ return;
+
+ property.write(getResetValue(propertyName));
+ }
+}
+
+bool QQuickDesignerCustomObjectData::hasValidResetBinding(const QQuickDesignerSupport::PropertyName &propertyName) const
+{
+ return m_resetBindingHash.contains(propertyName) && m_resetBindingHash.value(propertyName).data();
+}
+
+QQmlAbstractBinding *QQuickDesignerCustomObjectData::getResetBinding(const QQuickDesignerSupport::PropertyName &propertyName) const
+{
+ return m_resetBindingHash.value(propertyName).data();
+}
+
+bool QQuickDesignerCustomObjectData::hasBindingForProperty(QQmlContext *context,
+ const QQuickDesignerSupport::PropertyName &propertyName,
+ bool *hasChanged) const
+{
+ if (QQuickDesignerSupportProperties::isPropertyBlackListed(propertyName))
+ return false;
+
+ QQmlProperty property(object(), QString::fromUtf8(propertyName), context);
+
+ bool hasBinding = QQmlPropertyPrivate::binding(property);
+
+ if (hasChanged) {
+ *hasChanged = hasBinding != m_hasBindingHash.value(propertyName, false);
+ if (*hasChanged)
+ m_hasBindingHash.insert(propertyName, hasBinding);
+ }
+
+ return QQmlPropertyPrivate::binding(property);
+}
+
+void QQuickDesignerCustomObjectData::setPropertyBinding(QQmlContext *context,
+ const QQuickDesignerSupport::PropertyName &propertyName,
+ const QString &expression)
+{
+ QQmlProperty property(object(), QString::fromUtf8(propertyName), context);
+
+ if (!property.isValid())
+ return;
+
+ if (property.isProperty()) {
+ QQmlBinding *binding = new QQmlBinding(expression, object(), context);
+ binding->setTarget(property);
+ binding->setNotifyOnValueChanged(true);
+
+ QQmlPropertyPrivate::setBinding(binding, QQmlPropertyPrivate::None, QQmlPropertyPrivate::DontRemoveBinding);
+ //Refcounting is taking take care of deletion
+ binding->update();
+ if (binding->hasError()) {
+ if (property.property().userType() == QVariant::String)
+ property.write(QVariant(QLatin1Char('#') + expression + QLatin1Char('#')));
+ }
+
+ } else {
+ qWarning() << Q_FUNC_INFO << ": Cannot set binding for property" << propertyName << ": property is unknown for type";
+ }
+}
+
+void QQuickDesignerCustomObjectData::keepBindingFromGettingDeleted(QQmlContext *context,
+ const QQuickDesignerSupport::PropertyName &propertyName)
+{
+ //Refcounting is taking care
+ Q_UNUSED(context)
+ Q_UNUSED(propertyName)
+}
+
+void QQuickDesignerCustomObjectData::handleDestroyed()
+{
+ s_designerObjectToDataHash()->remove(m_object);
+ delete this;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/quick/designer/qquickdesignercustomobjectdata_p.h b/src/quick/designer/qquickdesignercustomobjectdata_p.h
new file mode 100644
index 0000000000..6734540a54
--- /dev/null
+++ b/src/quick/designer/qquickdesignercustomobjectdata_p.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DESIGNERCUSTOMOBJECTDATA_H
+#define DESIGNERCUSTOMOBJECTDATA_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qquickdesignersupport_p.h"
+
+#include <QHash>
+#include <QObject>
+#include <QVariant>
+
+#include <private/qqmlbinding_p.h>
+
+QT_BEGIN_NAMESPACE
+class QQmlContext;
+
+class QQuickDesignerCustomObjectData
+{
+public:
+ static void registerData(QObject *object);
+ static QQuickDesignerCustomObjectData *get(QObject *object);
+ static QVariant getResetValue(QObject *object, const QQuickDesignerSupport::PropertyName &propertyName);
+ static void doResetProperty(QObject *object, QQmlContext *context, const QQuickDesignerSupport::PropertyName &propertyName);
+ static bool hasValidResetBinding(QObject *object, const QQuickDesignerSupport::PropertyName &propertyName);
+ static bool hasBindingForProperty(QObject *object,
+ QQmlContext *context,
+ const QQuickDesignerSupport::PropertyName &propertyName,
+ bool *hasChanged);
+ static void setPropertyBinding(QObject *object,
+ QQmlContext *context,
+ const QQuickDesignerSupport::PropertyName &propertyName,
+ const QString &expression);
+ static void keepBindingFromGettingDeleted(QObject *object,
+ QQmlContext *context,
+ const QQuickDesignerSupport::PropertyName &propertyName);
+ void handleDestroyed();
+
+private:
+ QQuickDesignerCustomObjectData(QObject *object);
+ void populateResetHashes();
+ QObject *object() const;
+ QVariant getResetValue(const QQuickDesignerSupport::PropertyName &propertyName) const;
+ void doResetProperty(QQmlContext *context, const QQuickDesignerSupport::PropertyName &propertyName);
+ bool hasValidResetBinding(const QQuickDesignerSupport::PropertyName &propertyName) const;
+ QQmlAbstractBinding *getResetBinding(const QQuickDesignerSupport::PropertyName &propertyName) const;
+ bool hasBindingForProperty(QQmlContext *context, const QQuickDesignerSupport::PropertyName &propertyName, bool *hasChanged) const;
+ void setPropertyBinding(QQmlContext *context, const QQuickDesignerSupport::PropertyName &propertyName, const QString &expression);
+ void keepBindingFromGettingDeleted(QQmlContext *context, const QQuickDesignerSupport::PropertyName &propertyName);
+
+ QObject *m_object;
+ QHash<QQuickDesignerSupport::PropertyName, QVariant> m_resetValueHash;
+ QHash<QQuickDesignerSupport::PropertyName, QQmlAbstractBinding::Ptr> m_resetBindingHash;
+ mutable QHash<QQuickDesignerSupport::PropertyName, bool> m_hasBindingHash;
+};
+
+QT_END_NAMESPACE
+
+#endif // DESIGNERCUSTOMOBJECTDATA_H
diff --git a/src/quick/designer/designersupport.cpp b/src/quick/designer/qquickdesignersupport.cpp
index 56d2badb62..bc6352a677 100644
--- a/src/quick/designer/designersupport.cpp
+++ b/src/quick/designer/qquickdesignersupport.cpp
@@ -31,7 +31,7 @@
**
****************************************************************************/
-#include "designersupport.h"
+#include "qquickdesignersupport_p.h"
#include <private/qquickitem_p.h>
#include <QtQuick/private/qquickshadereffectsource_p.h>
@@ -46,16 +46,16 @@
#include <private/qqmlcomponentattached_p.h>
#include <private/qqmldata_p.h>
-#include "designerwindowmanager_p.h"
+#include "qquickdesignerwindowmanager_p.h"
QT_BEGIN_NAMESPACE
-DesignerSupport::DesignerSupport()
+QQuickDesignerSupport::QQuickDesignerSupport()
{
}
-DesignerSupport::~DesignerSupport()
+QQuickDesignerSupport::~QQuickDesignerSupport()
{
typedef QHash<QQuickItem*, QSGLayer*>::iterator ItemTextureHashIt;
@@ -67,7 +67,7 @@ DesignerSupport::~DesignerSupport()
}
}
-void DesignerSupport::refFromEffectItem(QQuickItem *referencedItem, bool hide)
+void QQuickDesignerSupport::refFromEffectItem(QQuickItem *referencedItem, bool hide)
{
if (referencedItem == 0)
return;
@@ -100,7 +100,7 @@ void DesignerSupport::refFromEffectItem(QQuickItem *referencedItem, bool hide)
}
}
-void DesignerSupport::derefFromEffectItem(QQuickItem *referencedItem, bool unhide)
+void QQuickDesignerSupport::derefFromEffectItem(QQuickItem *referencedItem, bool unhide)
{
if (referencedItem == 0)
return;
@@ -109,7 +109,7 @@ void DesignerSupport::derefFromEffectItem(QQuickItem *referencedItem, bool unhid
QQuickItemPrivate::get(referencedItem)->derefFromEffectItem(unhide);
}
-QImage DesignerSupport::renderImageForItem(QQuickItem *referencedItem, const QRectF &boundingRect, const QSize &imageSize)
+QImage QQuickDesignerSupport::renderImageForItem(QQuickItem *referencedItem, const QRectF &boundingRect, const QSize &imageSize)
{
if (referencedItem == 0 || referencedItem->parentItem() == 0) {
qDebug() << __FILE__ << __LINE__ << "Warning: Item can be rendered.";
@@ -136,7 +136,7 @@ QImage DesignerSupport::renderImageForItem(QQuickItem *referencedItem, const QRe
return renderImage;
}
-bool DesignerSupport::isDirty(QQuickItem *referencedItem, DirtyType dirtyType)
+bool QQuickDesignerSupport::isDirty(QQuickItem *referencedItem, DirtyType dirtyType)
{
if (referencedItem == 0)
return false;
@@ -144,7 +144,7 @@ bool DesignerSupport::isDirty(QQuickItem *referencedItem, DirtyType dirtyType)
return QQuickItemPrivate::get(referencedItem)->dirtyAttributes & dirtyType;
}
-void DesignerSupport::addDirty(QQuickItem *referencedItem, DesignerSupport::DirtyType dirtyType)
+void QQuickDesignerSupport::addDirty(QQuickItem *referencedItem, QQuickDesignerSupport::DirtyType dirtyType)
{
if (referencedItem == 0)
return;
@@ -152,7 +152,7 @@ void DesignerSupport::addDirty(QQuickItem *referencedItem, DesignerSupport::Dirt
QQuickItemPrivate::get(referencedItem)->dirtyAttributes |= dirtyType;
}
-void DesignerSupport::resetDirty(QQuickItem *referencedItem)
+void QQuickDesignerSupport::resetDirty(QQuickItem *referencedItem)
{
if (referencedItem == 0)
return;
@@ -161,7 +161,7 @@ void DesignerSupport::resetDirty(QQuickItem *referencedItem)
QQuickItemPrivate::get(referencedItem)->removeFromDirtyList();
}
-QTransform DesignerSupport::windowTransform(QQuickItem *referencedItem)
+QTransform QQuickDesignerSupport::windowTransform(QQuickItem *referencedItem)
{
if (referencedItem == 0)
return QTransform();
@@ -169,7 +169,7 @@ QTransform DesignerSupport::windowTransform(QQuickItem *referencedItem)
return QQuickItemPrivate::get(referencedItem)->itemToWindowTransform();
}
-QTransform DesignerSupport::parentTransform(QQuickItem *referencedItem)
+QTransform QQuickDesignerSupport::parentTransform(QQuickItem *referencedItem)
{
if (referencedItem == 0)
return QTransform();
@@ -211,12 +211,9 @@ bool isValidAnchorName(const QString &name)
return anchorNameList.contains(name);
}
-bool DesignerSupport::isAnchoredTo(QQuickItem *fromItem, QQuickItem *toItem)
+bool QQuickDesignerSupport::isAnchoredTo(QQuickItem *fromItem, QQuickItem *toItem)
{
-#ifndef QT_NO_DYNAMIC_CAST
- Q_ASSERT(dynamic_cast<QQuickItemPrivate*>(QQuickItemPrivate::get(fromItem)));
-#endif
- QQuickItemPrivate *fromItemPrivate = static_cast<QQuickItemPrivate*>(QQuickItemPrivate::get(fromItem));
+ QQuickItemPrivate *fromItemPrivate = QQuickItemPrivate::get(fromItem);
QQuickAnchors *anchors = fromItemPrivate->anchors();
return anchors->fill() == toItem
|| anchors->centerIn() == toItem
@@ -229,9 +226,9 @@ bool DesignerSupport::isAnchoredTo(QQuickItem *fromItem, QQuickItem *toItem)
|| anchors->baseline().item == toItem;
}
-bool DesignerSupport::areChildrenAnchoredTo(QQuickItem *fromItem, QQuickItem *toItem)
+bool QQuickDesignerSupport::areChildrenAnchoredTo(QQuickItem *fromItem, QQuickItem *toItem)
{
- foreach (QQuickItem *childItem, fromItem->childItems()) {
+ Q_FOREACH (QQuickItem *childItem, fromItem->childItems()) {
if (childItem) {
if (isAnchoredTo(childItem, toItem))
return true;
@@ -246,7 +243,7 @@ bool DesignerSupport::areChildrenAnchoredTo(QQuickItem *fromItem, QQuickItem *to
QQuickAnchors *anchors(QQuickItem *item)
{
- QQuickItemPrivate *itemPrivate = static_cast<QQuickItemPrivate*>(QQuickItemPrivate::get(item));
+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
return itemPrivate->anchors();
}
@@ -278,7 +275,7 @@ QQuickAnchors::Anchor anchorLineFlagForName(const QString &name)
return QQuickAnchors::LeftAnchor;
}
-bool DesignerSupport::hasAnchor(QQuickItem *item, const QString &name)
+bool QQuickDesignerSupport::hasAnchor(QQuickItem *item, const QString &name)
{
if (!isValidAnchorName(name))
return false;
@@ -313,19 +310,19 @@ bool DesignerSupport::hasAnchor(QQuickItem *item, const QString &name)
return anchors(item)->usedAnchors().testFlag(anchorLineFlagForName(name));
}
-QQuickItem *DesignerSupport::anchorFillTargetItem(QQuickItem *item)
+QQuickItem *QQuickDesignerSupport::anchorFillTargetItem(QQuickItem *item)
{
return anchors(item)->fill();
}
-QQuickItem *DesignerSupport::anchorCenterInTargetItem(QQuickItem *item)
+QQuickItem *QQuickDesignerSupport::anchorCenterInTargetItem(QQuickItem *item)
{
return anchors(item)->centerIn();
}
-QPair<QString, QObject*> DesignerSupport::anchorLineTarget(QQuickItem *item, const QString &name, QQmlContext *context)
+QPair<QString, QObject*> QQuickDesignerSupport::anchorLineTarget(QQuickItem *item, const QString &name, QQmlContext *context)
{
QObject *targetObject = 0;
QString targetName;
@@ -350,7 +347,7 @@ QPair<QString, QObject*> DesignerSupport::anchorLineTarget(QQuickItem *item, con
return QPair<QString, QObject*>(targetName, targetObject);
}
-void DesignerSupport::resetAnchor(QQuickItem *item, const QString &name)
+void QQuickDesignerSupport::resetAnchor(QQuickItem *item, const QString &name)
{
if (name == QLatin1String("anchors.fill")) {
anchors(item)->resetFill();
@@ -373,7 +370,7 @@ void DesignerSupport::resetAnchor(QQuickItem *item, const QString &name)
}
}
-void DesignerSupport::emitComponentCompleteSignalForAttachedProperty(QQuickItem *item)
+void QQuickDesignerSupport::emitComponentCompleteSignalForAttachedProperty(QQuickItem *item)
{
QQmlData *data = QQmlData::get(item);
if (data && data->context) {
@@ -384,24 +381,24 @@ void DesignerSupport::emitComponentCompleteSignalForAttachedProperty(QQuickItem
}
}
-QList<QObject*> DesignerSupport::statesForItem(QQuickItem *item)
+QList<QObject*> QQuickDesignerSupport::statesForItem(QQuickItem *item)
{
QList<QObject*> objectList;
QList<QQuickState *> stateList = QQuickItemPrivate::get(item)->_states()->states();
objectList.reserve(stateList.size());
- foreach (QQuickState* state, stateList)
+ Q_FOREACH (QQuickState* state, stateList)
objectList.append(state);
return objectList;
}
-bool DesignerSupport::isComponentComplete(QQuickItem *item)
+bool QQuickDesignerSupport::isComponentComplete(QQuickItem *item)
{
- return static_cast<QQuickItemPrivate*>(QQuickItemPrivate::get(item))->componentComplete;
+ return QQuickItemPrivate::get(item)->componentComplete;
}
-int DesignerSupport::borderWidth(QQuickItem *item)
+int QQuickDesignerSupport::borderWidth(QQuickItem *item)
{
QQuickRectangle *rectangle = qobject_cast<QQuickRectangle*>(item);
if (rectangle)
@@ -410,60 +407,71 @@ int DesignerSupport::borderWidth(QQuickItem *item)
return 0;
}
-void DesignerSupport::refreshExpressions(QQmlContext *context)
+void QQuickDesignerSupport::refreshExpressions(QQmlContext *context)
{
QQmlContextPrivate::get(context)->data->refreshExpressions();
}
-void DesignerSupport::setRootItem(QQuickView *view, QQuickItem *item)
+void QQuickDesignerSupport::setRootItem(QQuickView *view, QQuickItem *item)
{
QQuickViewPrivate::get(view)->setRootObject(item);
}
-bool DesignerSupport::isValidWidth(QQuickItem *item)
+bool QQuickDesignerSupport::isValidWidth(QQuickItem *item)
{
return QQuickItemPrivate::get(item)->heightValid;
}
-bool DesignerSupport::isValidHeight(QQuickItem *item)
+bool QQuickDesignerSupport::isValidHeight(QQuickItem *item)
{
return QQuickItemPrivate::get(item)->widthValid;
}
-void DesignerSupport::updateDirtyNode(QQuickItem *item)
+void QQuickDesignerSupport::updateDirtyNode(QQuickItem *item)
{
if (item->window())
QQuickWindowPrivate::get(item->window())->updateDirtyNode(item);
}
-void DesignerSupport::activateDesignerWindowManager()
+void QQuickDesignerSupport::activateDesignerWindowManager()
{
- QSGRenderLoop::setInstance(new DesignerWindowManager);
+ QSGRenderLoop::setInstance(new QQuickDesignerWindowManager);
}
-void DesignerSupport::activateDesignerMode()
+void QQuickDesignerSupport::activateDesignerMode()
{
QQmlEnginePrivate::activateDesignerMode();
}
-void DesignerSupport::disableComponentComplete()
+void QQuickDesignerSupport::disableComponentComplete()
{
QQmlVME::disableComponentComplete();
}
-void DesignerSupport::enableComponentComplete()
+void QQuickDesignerSupport::enableComponentComplete()
{
QQmlVME::enableComponentComplete();
}
-void DesignerSupport::createOpenGLContext(QQuickWindow *window)
+void QQuickDesignerSupport::createOpenGLContext(QQuickWindow *window)
{
- DesignerWindowManager::createOpenGLContext(window);
+ QQuickDesignerWindowManager::createOpenGLContext(window);
}
-void DesignerSupport::polishItems(QQuickWindow *window)
+void QQuickDesignerSupport::polishItems(QQuickWindow *window)
{
QQuickWindowPrivate::get(window)->polishItems();
}
+ComponentCompleteDisabler::ComponentCompleteDisabler()
+{
+ QQuickDesignerSupport::disableComponentComplete();
+}
+
+ComponentCompleteDisabler::~ComponentCompleteDisabler()
+{
+ QQuickDesignerSupport::enableComponentComplete();
+}
+
+
QT_END_NAMESPACE
diff --git a/src/quick/designer/designersupport.h b/src/quick/designer/qquickdesignersupport_p.h
index 51fcef4512..e15c109f7b 100644
--- a/src/quick/designer/designersupport.h
+++ b/src/quick/designer/qquickdesignersupport_p.h
@@ -45,7 +45,6 @@
// We mean it.
//
-
#include <QtQuick/qtquickglobal.h>
#include <QtCore/QtGlobal>
#include <QtCore/QHash>
@@ -62,9 +61,13 @@ class QQuickView;
class QObject;
class QQuickWindow;
-class Q_QUICK_EXPORT DesignerSupport
+class Q_QUICK_EXPORT QQuickDesignerSupport
{
public:
+ typedef QByteArray PropertyName;
+ typedef QList<PropertyName> PropertyNameList;
+ typedef QByteArray TypeName;
+
enum DirtyType {
TransformOrigin = 0x00000001,
Transform = 0x00000002,
@@ -95,8 +98,8 @@ public:
};
- DesignerSupport();
- ~DesignerSupport();
+ QQuickDesignerSupport();
+ ~QQuickDesignerSupport();
void refFromEffectItem(QQuickItem *referencedItem, bool hide = true);
void derefFromEffectItem(QQuickItem *referencedItem, bool unhide = true);
@@ -119,7 +122,6 @@ public:
static void resetAnchor(QQuickItem *item, const QString &name);
static void emitComponentCompleteSignalForAttachedProperty(QQuickItem *item);
-
static QList<QObject*> statesForItem(QQuickItem *item);
static bool isComponentComplete(QQuickItem *item);
@@ -149,6 +151,16 @@ private:
QHash<QQuickItem*, QSGLayer*> m_itemTextureHash;
};
+class Q_QUICK_EXPORT ComponentCompleteDisabler
+{
+public:
+ ComponentCompleteDisabler();
+
+ ~ComponentCompleteDisabler();
+};
+
+typedef QQuickDesignerSupport DesignerSupport;
+
QT_END_NAMESPACE
#endif // DESIGNERSUPPORT_H
diff --git a/src/quick/designer/qquickdesignersupportitems.cpp b/src/quick/designer/qquickdesignersupportitems.cpp
new file mode 100644
index 0000000000..4f23fe6630
--- /dev/null
+++ b/src/quick/designer/qquickdesignersupportitems.cpp
@@ -0,0 +1,320 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickdesignersupportitems_p.h"
+#include "qquickdesignersupportproperties_p.h"
+
+#include <private/qabstractanimation_p.h>
+#include <private/qobject_p.h>
+#include <private/qquickbehavior_p.h>
+#include <private/qquicktext_p.h>
+#include <private/qquicktextinput_p.h>
+#include <private/qquicktextedit_p.h>
+#include <private/qquicktransition_p.h>
+
+#include <private/qquickanimation_p.h>
+#include <private/qqmlmetatype_p.h>
+#include <private/qqmltimer_p.h>
+
+QT_BEGIN_NAMESPACE
+
+static void (*fixResourcePathsForObjectCallBack)(QObject*) = 0;
+
+static void stopAnimation(QObject *object)
+{
+ if (object == 0)
+ return;
+
+ QQuickTransition *transition = qobject_cast<QQuickTransition*>(object);
+ QQuickAbstractAnimation *animation = qobject_cast<QQuickAbstractAnimation*>(object);
+ QQmlTimer *timer = qobject_cast<QQmlTimer*>(object);
+ if (transition) {
+ transition->setFromState(QString());
+ transition->setToState(QString());
+ } else if (animation) {
+// QQuickScriptAction *scriptAimation = qobject_cast<QQuickScriptAction*>(animation);
+// if (scriptAimation) FIXME
+// scriptAimation->setScript(QQmlScriptString());
+ animation->setLoops(1);
+ animation->complete();
+ animation->setDisableUserControl();
+ } else if (timer) {
+ timer->blockSignals(true);
+ }
+}
+
+static void allSubObjects(QObject *object, QObjectList &objectList)
+{
+ // don't add null pointer and stop if the object is already in the list
+ if (!object || objectList.contains(object))
+ return;
+
+ objectList.append(object);
+
+ for (int index = QObject::staticMetaObject.propertyOffset();
+ index < object->metaObject()->propertyCount();
+ index++) {
+ QMetaProperty metaProperty = object->metaObject()->property(index);
+
+ // search recursive in property objects
+ if (metaProperty.isReadable()
+ && metaProperty.isWritable()
+ && QQmlMetaType::isQObject(metaProperty.userType())) {
+ if (qstrcmp(metaProperty.name(), "parent")) {
+ QObject *propertyObject = QQmlMetaType::toQObject(metaProperty.read(object));
+ allSubObjects(propertyObject, objectList);
+ }
+
+ }
+
+ // search recursive in property object lists
+ if (metaProperty.isReadable()
+ && QQmlMetaType::isList(metaProperty.userType())) {
+ QQmlListReference list(object, metaProperty.name());
+ if (list.canCount() && list.canAt()) {
+ for (int i = 0; i < list.count(); i++) {
+ QObject *propertyObject = list.at(i);
+ allSubObjects(propertyObject, objectList);
+
+ }
+ }
+ }
+ }
+
+ // search recursive in object children list
+ Q_FOREACH (QObject *childObject, object->children()) {
+ allSubObjects(childObject, objectList);
+ }
+
+ // search recursive in quick item childItems list
+ QQuickItem *quickItem = qobject_cast<QQuickItem*>(object);
+ if (quickItem) {
+ Q_FOREACH (QQuickItem *childItem, quickItem->childItems()) {
+ allSubObjects(childItem, objectList);
+ }
+ }
+}
+
+void QQuickDesignerSupportItems::tweakObjects(QObject *object)
+{
+ QObjectList objectList;
+ allSubObjects(object, objectList);
+ Q_FOREACH (QObject* childObject, objectList) {
+ stopAnimation(childObject);
+ if (fixResourcePathsForObjectCallBack)
+ fixResourcePathsForObjectCallBack(childObject);
+ }
+}
+
+static QObject *createDummyWindow(QQmlEngine *engine)
+{
+ QQmlComponent component(engine, QUrl(QStringLiteral("qrc:/qtquickplugin/mockfiles/Window.qml")));
+ return component.create();
+}
+
+static bool isWindowMetaObject(const QMetaObject *metaObject)
+{
+ if (metaObject) {
+ if (metaObject->className() == QByteArrayLiteral("QWindow"))
+ return true;
+
+ return isWindowMetaObject(metaObject->superClass());
+ }
+
+ return false;
+}
+
+static bool isWindow(QObject *object) {
+ if (object)
+ return isWindowMetaObject(object->metaObject());
+
+ return false;
+}
+
+static QQmlType *getQmlType(const QString &typeName, int majorNumber, int minorNumber)
+{
+ return QQmlMetaType::qmlType(typeName, majorNumber, minorNumber);
+}
+
+static bool isCrashingType(QQmlType *type)
+{
+ if (type) {
+ if (type->qmlTypeName() == QStringLiteral("QtMultimedia/MediaPlayer"))
+ return true;
+
+ if (type->qmlTypeName() == QStringLiteral("QtMultimedia/Audio"))
+ return true;
+
+ if (type->qmlTypeName() == QStringLiteral("QtQuick.Controls/MenuItem"))
+ return true;
+
+ if (type->qmlTypeName() == QStringLiteral("QtQuick.Controls/Menu"))
+ return true;
+
+ if (type->qmlTypeName() == QStringLiteral("QtQuick/Timer"))
+ return true;
+ }
+
+ return false;
+}
+
+QObject *QQuickDesignerSupportItems::createPrimitive(const QString &typeName, int majorNumber, int minorNumber, QQmlContext *context)
+{
+ ComponentCompleteDisabler disableComponentComplete;
+
+ Q_UNUSED(disableComponentComplete)
+
+ QObject *object = 0;
+ QQmlType *type = getQmlType(typeName, majorNumber, minorNumber);
+
+ if (isCrashingType(type)) {
+ object = new QObject;
+ } else if (type) {
+ if ( type->isComposite()) {
+ object = createComponent(type->sourceUrl(), context);
+ } else
+ {
+ if (type->typeName() == "QQmlComponent") {
+ object = new QQmlComponent(context->engine(), 0);
+ } else {
+ object = type->create();
+ }
+ }
+
+ if (isWindow(object)) {
+ delete object;
+ object = createDummyWindow(context->engine());
+ }
+
+ }
+
+ if (!object) {
+ qWarning() << "QuickDesigner: Cannot create an object of type"
+ << QString::fromLatin1("%1 %2,%3").arg(typeName).arg(majorNumber).arg(minorNumber)
+ << "- type isn't known to declarative meta type system";
+ }
+
+ tweakObjects(object);
+
+ if (object && QQmlEngine::contextForObject(object) == 0)
+ QQmlEngine::setContextForObject(object, context);
+
+ QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership);
+
+ return object;
+}
+
+QObject *QQuickDesignerSupportItems::createComponent(const QUrl &componentUrl, QQmlContext *context)
+{
+ ComponentCompleteDisabler disableComponentComplete;
+ Q_UNUSED(disableComponentComplete)
+
+ QQmlComponent component(context->engine(), componentUrl);
+
+ QObject *object = component.beginCreate(context);
+ tweakObjects(object);
+ component.completeCreate();
+ QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership);
+
+ if (component.isError()) {
+ qWarning() << "Error in:" << Q_FUNC_INFO << componentUrl;
+ Q_FOREACH (const QQmlError &error, component.errors())
+ qWarning() << error;
+ }
+ return object;
+}
+
+bool QQuickDesignerSupportItems::objectWasDeleted(QObject *object)
+{
+ return QObjectPrivate::get(object)->wasDeleted;
+}
+
+void QQuickDesignerSupportItems::disableNativeTextRendering(QQuickItem *item)
+{
+ QQuickText *text = qobject_cast<QQuickText*>(item);
+ if (text)
+ text->setRenderType(QQuickText::QtRendering);
+
+ QQuickTextInput *textInput = qobject_cast<QQuickTextInput*>(item);
+ if (textInput)
+ textInput->setRenderType(QQuickTextInput::QtRendering);
+
+ QQuickTextEdit *textEdit = qobject_cast<QQuickTextEdit*>(item);
+ if (textEdit)
+ textEdit->setRenderType(QQuickTextEdit::QtRendering);
+}
+
+void QQuickDesignerSupportItems::disableTextCursor(QQuickItem *item)
+{
+ Q_FOREACH (QQuickItem *childItem, item->childItems())
+ disableTextCursor(childItem);
+
+ QQuickTextInput *textInput = qobject_cast<QQuickTextInput*>(item);
+ if (textInput)
+ textInput->setCursorVisible(false);
+
+ QQuickTextEdit *textEdit = qobject_cast<QQuickTextEdit*>(item);
+ if (textEdit)
+ textEdit->setCursorVisible(false);
+}
+
+void QQuickDesignerSupportItems::disableTransition(QObject *object)
+{
+ QQuickTransition *transition = qobject_cast<QQuickTransition*>(object);
+ Q_ASSERT(transition);
+ const QString invalidState = QLatin1String("invalidState");
+ transition->setToState(invalidState);
+ transition->setFromState(invalidState);
+}
+
+void QQuickDesignerSupportItems::disableBehaivour(QObject *object)
+{
+ QQuickBehavior* behavior = qobject_cast<QQuickBehavior*>(object);
+ Q_ASSERT(behavior);
+ behavior->setEnabled(false);
+}
+
+void QQuickDesignerSupportItems::stopUnifiedTimer()
+{
+ QUnifiedTimer::instance()->setSlowdownFactor(0.00001);
+ QUnifiedTimer::instance()->setSlowModeEnabled(true);
+}
+
+void QQuickDesignerSupportItems::registerFixResourcePathsForObjectCallBack(void (*callback)(QObject *))
+{
+ fixResourcePathsForObjectCallBack = callback;
+}
+
+QT_END_NAMESPACE
+
+
diff --git a/src/quick/designer/qquickdesignersupportitems_p.h b/src/quick/designer/qquickdesignersupportitems_p.h
new file mode 100644
index 0000000000..c15d651b33
--- /dev/null
+++ b/src/quick/designer/qquickdesignersupportitems_p.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DESIGNERSUPPORTITEM_H
+#define DESIGNERSUPPORTITEM_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qquickdesignersupport_p.h"
+
+#include <QObject>
+#include <QString>
+#include <QVariant>
+#include <QList>
+#include <QByteArray>
+#include <QQmlContext>
+#include <QQmlListReference>
+
+QT_BEGIN_NAMESPACE
+
+class Q_QUICK_EXPORT QQuickDesignerSupportItems
+{
+public:
+ static QObject *createPrimitive(const QString &typeName, int majorNumber, int minorNumber, QQmlContext *context);
+ static QObject *createComponent(const QUrl &componentUrl, QQmlContext *context);
+ static void tweakObjects(QObject *object);
+ static bool objectWasDeleted(QObject *object);
+ static void disableNativeTextRendering(QQuickItem *item);
+ static void disableTextCursor(QQuickItem *item);
+ static void disableTransition(QObject *object);
+ static void disableBehaivour(QObject *object);
+ static void stopUnifiedTimer();
+ static void registerFixResourcePathsForObjectCallBack(void (*callback)(QObject *));
+};
+
+QT_END_NAMESPACE
+
+#endif // DESIGNERSUPPORTITEM_H
diff --git a/src/quick/designer/qquickdesignersupportmetainfo.cpp b/src/quick/designer/qquickdesignersupportmetainfo.cpp
new file mode 100644
index 0000000000..c6c7ed38b9
--- /dev/null
+++ b/src/quick/designer/qquickdesignersupportmetainfo.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickdesignersupportmetainfo_p.h"
+#include "qqmldesignermetaobject_p.h"
+
+#include <private/qqmlmetatype_p.h>
+
+QT_BEGIN_NAMESPACE
+
+bool QQuickDesignerSupportMetaInfo::isSubclassOf(QObject *object, const QByteArray &superTypeName)
+{
+ if (object == 0)
+ return false;
+
+ const QMetaObject *metaObject = object->metaObject();
+
+ while (metaObject) {
+ QQmlType *qmlType = QQmlMetaType::qmlType(metaObject);
+ if (qmlType && qmlType->qmlTypeName() == QLatin1String(superTypeName)) // ignore version numbers
+ return true;
+
+ if (metaObject->className() == superTypeName)
+ return true;
+
+ metaObject = metaObject->superClass();
+ }
+
+ return false;
+}
+
+void QQuickDesignerSupportMetaInfo::registerNotifyPropertyChangeCallBack(void (*callback)(QObject *, const QQuickDesignerSupport::PropertyName &))
+{
+ QQmlDesignerMetaObject::registerNotifyPropertyChangeCallBack(callback);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/quick/designer/qquickdesignersupportmetainfo_p.h b/src/quick/designer/qquickdesignersupportmetainfo_p.h
new file mode 100644
index 0000000000..52bf8e3ac0
--- /dev/null
+++ b/src/quick/designer/qquickdesignersupportmetainfo_p.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DESIGNERSUPPORTMETAINFO_H
+#define DESIGNERSUPPORTMETAINFO_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qquickdesignersupport_p.h"
+
+#include <QObject>
+#include <QByteArray>
+
+QT_BEGIN_NAMESPACE
+
+class Q_QUICK_EXPORT QQuickDesignerSupportMetaInfo
+{
+public:
+ static bool isSubclassOf(QObject *object, const QByteArray &superTypeName);
+ static void registerNotifyPropertyChangeCallBack(void (*callback)(QObject *, const QQuickDesignerSupport::PropertyName &));
+};
+
+QT_END_NAMESPACE
+
+#endif // DESIGNERSUPPORTMETAINFO_H
diff --git a/src/quick/designer/qquickdesignersupportproperties.cpp b/src/quick/designer/qquickdesignersupportproperties.cpp
new file mode 100644
index 0000000000..96f09ada48
--- /dev/null
+++ b/src/quick/designer/qquickdesignersupportproperties.cpp
@@ -0,0 +1,233 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickdesignersupportproperties_p.h"
+
+#include "qqmldesignermetaobject_p.h"
+#include "qquickdesignercustomobjectdata_p.h"
+
+QT_BEGIN_NAMESPACE
+
+static void addToPropertyNameListIfNotBlackListed(QQuickDesignerSupport::PropertyNameList *propertyNameList,
+ const QQuickDesignerSupport::PropertyName &propertyName)
+{
+ if (!QQuickDesignerSupportProperties::isPropertyBlackListed(propertyName))
+ propertyNameList->append(propertyName);
+}
+
+void QQuickDesignerSupportProperties::createNewDynamicProperty(QObject *object, QQmlEngine *engine, const QString &name)
+{
+ QQmlDesignerMetaObject::getNodeInstanceMetaObject(object, engine)->createNewDynamicProperty(name);
+}
+
+void QQuickDesignerSupportProperties::registerNodeInstanceMetaObject(QObject *object, QQmlEngine *engine)
+{
+ // we just create one and the ownership goes automatically to the object in nodeinstance see init method
+ QQmlDesignerMetaObject::getNodeInstanceMetaObject(object, engine);
+}
+
+bool QQuickDesignerSupportProperties::hasFullImplementedListInterface(const QQmlListReference &list)
+{
+ return list.isValid() && list.canCount() && list.canAt() && list.canAppend() && list.canClear();
+}
+
+void QQuickDesignerSupportProperties::registerCustomData(QObject *object)
+{
+ QQuickDesignerCustomObjectData::registerData(object);
+}
+
+QVariant QQuickDesignerSupportProperties::getResetValue(QObject *object, const QQuickDesignerSupport::PropertyName &propertyName)
+{
+ return QQuickDesignerCustomObjectData::getResetValue(object, propertyName);
+}
+
+void QQuickDesignerSupportProperties::doResetProperty(QObject *object, QQmlContext *context, const QQuickDesignerSupport::PropertyName &propertyName)
+{
+ QQuickDesignerCustomObjectData::doResetProperty(object, context, propertyName);
+}
+
+bool QQuickDesignerSupportProperties::hasValidResetBinding(QObject *object, const QQuickDesignerSupport::PropertyName &propertyName)
+{
+ return QQuickDesignerCustomObjectData::hasValidResetBinding(object, propertyName);
+}
+
+bool QQuickDesignerSupportProperties::hasBindingForProperty(QObject *object,
+ QQmlContext *context,
+ const QQuickDesignerSupport::PropertyName &propertyName,
+ bool *hasChanged)
+{
+ return QQuickDesignerCustomObjectData::hasBindingForProperty(object, context, propertyName, hasChanged);
+}
+
+void QQuickDesignerSupportProperties::setPropertyBinding(QObject *object,
+ QQmlContext *context,
+ const QQuickDesignerSupport::PropertyName &propertyName,
+ const QString &expression)
+{
+ QQuickDesignerCustomObjectData::setPropertyBinding(object, context, propertyName, expression);
+}
+
+void QQuickDesignerSupportProperties::keepBindingFromGettingDeleted(QObject *object,
+ QQmlContext *context,
+ const QQuickDesignerSupport::PropertyName &propertyName)
+{
+ QQuickDesignerCustomObjectData::keepBindingFromGettingDeleted(object, context, propertyName);
+}
+
+bool QQuickDesignerSupportProperties::isPropertyQObject(const QMetaProperty &metaProperty)
+{
+ return QQmlMetaType::isQObject(metaProperty.userType());
+}
+
+
+QObject *QQuickDesignerSupportProperties::readQObjectProperty(const QMetaProperty &metaProperty, QObject *object)
+{
+ return QQmlMetaType::toQObject(metaProperty.read(object));
+}
+
+void QQuickDesignerSupportProperties::getPropertyCache(QObject *object, QQmlEngine *engine)
+{
+ QQmlEnginePrivate::get(engine)->cache(object->metaObject());
+}
+
+QQuickDesignerSupport::PropertyNameList QQuickDesignerSupportProperties::propertyNameListForWritableProperties(QObject *object,
+ const QQuickDesignerSupport::PropertyName &baseName,
+ QObjectList *inspectedObjects)
+{
+ QQuickDesignerSupport::PropertyNameList propertyNameList;
+
+ QObjectList localObjectList;
+
+ if (inspectedObjects == 0)
+ inspectedObjects = &localObjectList;
+
+
+ if (inspectedObjects->contains(object))
+ return propertyNameList;
+
+ inspectedObjects->append(object);
+
+ const QMetaObject *metaObject = object->metaObject();
+ for (int index = 0; index < metaObject->propertyCount(); ++index) {
+ QMetaProperty metaProperty = metaObject->property(index);
+ QQmlProperty declarativeProperty(object, QString::fromUtf8(metaProperty.name()));
+ if (declarativeProperty.isValid() && !declarativeProperty.isWritable() && declarativeProperty.propertyTypeCategory() == QQmlProperty::Object) {
+ if (declarativeProperty.name() != QLatin1String("parent")) {
+ QObject *childObject = QQmlMetaType::toQObject(declarativeProperty.read());
+ if (childObject)
+ propertyNameList.append(propertyNameListForWritableProperties(childObject,
+ baseName + QQuickDesignerSupport::PropertyName(metaProperty.name())
+ + '.', inspectedObjects));
+ }
+ } else if (QQmlValueTypeFactory::valueType(metaProperty.userType())) {
+ QQmlValueType *valueType = QQmlValueTypeFactory::valueType(metaProperty.userType());
+ valueType->setValue(metaProperty.read(object));
+ propertyNameList.append(propertyNameListForWritableProperties(valueType,
+ baseName + QQuickDesignerSupport::PropertyName(metaProperty.name())
+ + '.', inspectedObjects));
+ }
+
+ if (metaProperty.isReadable() && metaProperty.isWritable()) {
+ addToPropertyNameListIfNotBlackListed(&propertyNameList,
+ baseName + QQuickDesignerSupport::PropertyName(metaProperty.name()));
+ }
+ }
+
+ return propertyNameList;
+}
+
+bool QQuickDesignerSupportProperties::isPropertyBlackListed(const QQuickDesignerSupport::PropertyName &propertyName)
+{
+ if (propertyName.contains(".") && propertyName.contains("__"))
+ return true;
+
+ if (propertyName.count(".") > 1)
+ return true;
+
+ return false;
+}
+
+QQuickDesignerSupport::PropertyNameList QQuickDesignerSupportProperties::allPropertyNames(QObject *object,
+ const QQuickDesignerSupport::PropertyName &baseName,
+ QObjectList *inspectedObjects)
+{
+ QQuickDesignerSupport::PropertyNameList propertyNameList;
+
+ QObjectList localObjectList;
+
+ if (inspectedObjects == 0)
+ inspectedObjects = &localObjectList;
+
+
+ if (inspectedObjects->contains(object))
+ return propertyNameList;
+
+ inspectedObjects->append(object);
+
+
+ const QMetaObject *metaObject = object->metaObject();
+ for (int index = 0; index < metaObject->propertyCount(); ++index) {
+ QMetaProperty metaProperty = metaObject->property(index);
+ QQmlProperty declarativeProperty(object, QString::fromUtf8(metaProperty.name()));
+ if (declarativeProperty.isValid() && declarativeProperty.propertyTypeCategory() == QQmlProperty::Object) {
+ if (declarativeProperty.name() != QLatin1String("parent")) {
+ QObject *childObject = QQmlMetaType::toQObject(declarativeProperty.read());
+ if (childObject)
+ propertyNameList.append(allPropertyNames(childObject,
+ baseName
+ + QQuickDesignerSupport::PropertyName(metaProperty.name())
+ + '.', inspectedObjects));
+ }
+ } else if (QQmlValueTypeFactory::valueType(metaProperty.userType())) {
+ QQmlValueType *valueType = QQmlValueTypeFactory::valueType(metaProperty.userType());
+ valueType->setValue(metaProperty.read(object));
+ propertyNameList.append(baseName + QQuickDesignerSupport::PropertyName(metaProperty.name()));
+ propertyNameList.append(allPropertyNames(valueType,
+ baseName
+ + QQuickDesignerSupport::PropertyName(metaProperty.name())
+ + '.', inspectedObjects));
+ } else {
+ addToPropertyNameListIfNotBlackListed(&propertyNameList,
+ baseName + QQuickDesignerSupport::PropertyName(metaProperty.name()));
+ }
+ }
+
+ return propertyNameList;
+}
+
+
+QT_END_NAMESPACE
+
+
+
+
diff --git a/src/quick/designer/qquickdesignersupportproperties_p.h b/src/quick/designer/qquickdesignersupportproperties_p.h
new file mode 100644
index 0000000000..187bc6e2a6
--- /dev/null
+++ b/src/quick/designer/qquickdesignersupportproperties_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DESIGNERSUPPORTPROPERTIES_H
+#define DESIGNERSUPPORTPROPERTIES_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qquickdesignersupport_p.h"
+
+#include <QObject>
+#include <QString>
+#include <QVariant>
+#include <QList>
+#include <QByteArray>
+#include <QQmlContext>
+#include <QQmlListReference>
+
+QT_BEGIN_NAMESPACE
+
+class Q_QUICK_EXPORT QQuickDesignerSupportProperties
+{
+public:
+ static void createNewDynamicProperty(QObject *object, QQmlEngine *engine, const QString &name);
+ static void registerNodeInstanceMetaObject(QObject *object, QQmlEngine *engine);
+ static void registerCustomData(QObject *object);
+ static QVariant getResetValue(QObject *object, const QQuickDesignerSupport::PropertyName &propertyName);
+ static void doResetProperty(QObject *object, QQmlContext *context, const QQuickDesignerSupport::PropertyName &propertyName);
+ static bool hasValidResetBinding(QObject *object, const QQuickDesignerSupport::PropertyName &propertyName);
+
+ static bool hasBindingForProperty(QObject *object,
+ QQmlContext *context,
+ const QQuickDesignerSupport::PropertyName &propertyName,
+ bool *hasChanged);
+ static void setPropertyBinding(QObject *object,
+ QQmlContext *context,
+ const QQuickDesignerSupport::PropertyName &propertyName,
+ const QString &expression);
+ static void keepBindingFromGettingDeleted(QObject *object,
+ QQmlContext *context,
+ const QQuickDesignerSupport::PropertyName &propertyName);
+
+ static bool isPropertyQObject(const QMetaProperty &metaProperty);
+ static QObject *readQObjectProperty(const QMetaProperty &metaProperty, QObject *object);
+
+ static void getPropertyCache(QObject *object, QQmlEngine *engine);
+ static bool isPropertyBlackListed(const QQuickDesignerSupport::PropertyName &propertyName);
+ static QQuickDesignerSupport::PropertyNameList propertyNameListForWritableProperties(QObject *object,
+ const QQuickDesignerSupport::PropertyName &baseName = QQuickDesignerSupport::PropertyName(),
+ QObjectList *inspectedObjects = 0);
+ static QQuickDesignerSupport::PropertyNameList allPropertyNames(QObject *object,
+ const QQuickDesignerSupport::PropertyName &baseName = QQuickDesignerSupport::PropertyName(),
+ QObjectList *inspectedObjects = 0);
+ static bool hasFullImplementedListInterface(const QQmlListReference &list);
+};
+
+QT_END_NAMESPACE
+
+#endif // DESIGNERSUPPORTPROPERTIES_H
diff --git a/src/quick/designer/qquickdesignersupportpropertychanges.cpp b/src/quick/designer/qquickdesignersupportpropertychanges.cpp
new file mode 100644
index 0000000000..92fa637b54
--- /dev/null
+++ b/src/quick/designer/qquickdesignersupportpropertychanges.cpp
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickdesignersupportpropertychanges_p.h"
+
+#include <private/qquickpropertychanges_p.h>
+#include <private/qquickstateoperations_p.h>
+
+QT_BEGIN_NAMESPACE
+
+void QQuickDesignerSupportPropertyChanges::attachToState(QObject *propertyChanges)
+{
+ QQuickPropertyChanges *propertyChange = qobject_cast<QQuickPropertyChanges*>(propertyChanges);
+
+ if (!propertyChange)
+ return;
+
+ propertyChange->attachToState();
+}
+
+QObject *QQuickDesignerSupportPropertyChanges::targetObject(QObject *propertyChanges)
+{
+ QQuickPropertyChanges *propertyChange = qobject_cast<QQuickPropertyChanges*>(propertyChanges);
+
+ if (!propertyChange)
+ return 0;
+
+ return propertyChange->object();
+}
+
+void QQuickDesignerSupportPropertyChanges::removeProperty(QObject *propertyChanges, const QQuickDesignerSupport::PropertyName &propertyName)
+{
+ QQuickPropertyChanges *propertyChange = qobject_cast<QQuickPropertyChanges*>(propertyChanges);
+
+ if (!propertyChange)
+ return;
+
+ propertyChange->removeProperty(QString::fromUtf8(propertyName));
+}
+
+QVariant QQuickDesignerSupportPropertyChanges::getProperty(QObject *propertyChanges,
+ const QQuickDesignerSupport::PropertyName &propertyName)
+{
+ QQuickPropertyChanges *propertyChange = qobject_cast<QQuickPropertyChanges*>(propertyChanges);
+
+ if (!propertyChange)
+ return QVariant();
+
+ return propertyChange->property(QString::fromUtf8(propertyName));
+}
+
+void QQuickDesignerSupportPropertyChanges::changeValue(QObject *propertyChanges,
+ const QQuickDesignerSupport::PropertyName &propertyName,
+ const QVariant &value)
+{
+ QQuickPropertyChanges *propertyChange = qobject_cast<QQuickPropertyChanges*>(propertyChanges);
+
+ if (!propertyChange)
+ return;
+
+ propertyChange->changeValue(QString::fromUtf8(propertyName), value);
+}
+
+void QQuickDesignerSupportPropertyChanges::changeExpression(QObject *propertyChanges,
+ const QQuickDesignerSupport::PropertyName &propertyName,
+ const QString &expression)
+{
+ QQuickPropertyChanges *propertyChange = qobject_cast<QQuickPropertyChanges*>(propertyChanges);
+
+ if (!propertyChange)
+ return;
+
+ propertyChange->changeExpression(QString::fromUtf8(propertyName), expression);
+}
+
+QObject *QQuickDesignerSupportPropertyChanges::stateObject(QObject *propertyChanges)
+{
+ QQuickPropertyChanges *propertyChange = qobject_cast<QQuickPropertyChanges*>(propertyChanges);
+
+ if (!propertyChange)
+ return 0;
+
+ return propertyChange->state();
+}
+
+bool QQuickDesignerSupportPropertyChanges::isNormalProperty(const QQuickDesignerSupport::PropertyName &propertyName)
+{
+ QMetaObject metaObject = QQuickPropertyChanges::staticMetaObject;
+
+ return (metaObject.indexOfProperty(propertyName) > 0); // 'restoreEntryValues', 'explicit'
+}
+
+void QQuickDesignerSupportPropertyChanges::detachFromState(QObject *propertyChanges)
+{
+ QQuickPropertyChanges *propertyChange = qobject_cast<QQuickPropertyChanges*>(propertyChanges);
+
+ if (!propertyChange)
+ return;
+
+ propertyChange->detachFromState();
+}
+
+QT_END_NAMESPACE
+
+
diff --git a/src/quick/designer/qquickdesignersupportpropertychanges_p.h b/src/quick/designer/qquickdesignersupportpropertychanges_p.h
new file mode 100644
index 0000000000..432383d5b4
--- /dev/null
+++ b/src/quick/designer/qquickdesignersupportpropertychanges_p.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DESIGNERSUPPORTPROPERTYCHANGES_H
+#define DESIGNERSUPPORTPROPERTYCHANGES_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qquickdesignersupport_p.h"
+
+#include <QVariant>
+
+QT_BEGIN_NAMESPACE
+
+class Q_QUICK_EXPORT QQuickDesignerSupportPropertyChanges
+{
+public:
+ static void detachFromState(QObject *propertyChanges);
+ static void attachToState(QObject *propertyChanges);
+ static QObject *targetObject(QObject *propertyChanges);
+ static void removeProperty(QObject *propertyChanges, const QQuickDesignerSupport::PropertyName &propertyName);
+ static QVariant getProperty(QObject *propertyChanges, const QQuickDesignerSupport::PropertyName &propertyName);
+ static void changeValue(QObject *propertyChanges, const QQuickDesignerSupport::PropertyName &propertyName, const QVariant &value);
+ static void changeExpression(QObject *propertyChanges, const QQuickDesignerSupport::PropertyName &propertyName, const QString &expression);
+ static QObject *stateObject(QObject *propertyChanges);
+ static bool isNormalProperty(const QQuickDesignerSupport::PropertyName &propertyName);
+};
+
+QT_END_NAMESPACE
+
+#endif // DESIGNERSUPPORTPROPERTYCHANGES_H
diff --git a/src/quick/designer/qquickdesignersupportstates.cpp b/src/quick/designer/qquickdesignersupportstates.cpp
new file mode 100644
index 0000000000..b75ec7115a
--- /dev/null
+++ b/src/quick/designer/qquickdesignersupportstates.cpp
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickdesignersupportstates_p.h"
+
+#include <private/qquickstategroup_p.h>
+#include <private/qquickpropertychanges_p.h>
+
+QT_BEGIN_NAMESPACE
+
+bool QQuickDesignerSupportStates::isStateActive(QObject *object, QQmlContext *context)
+{
+ QQuickState *stateObject = qobject_cast<QQuickState*>(object);
+
+ if (!stateObject)
+ return false;
+
+ QQuickStateGroup *stateGroup = stateObject->stateGroup();
+
+ QQmlProperty property(object, QLatin1String("name"), context);
+
+ return stateObject && stateGroup && stateGroup->state() == property.read();
+}
+
+void QQuickDesignerSupportStates::activateState(QObject *object, QQmlContext *context)
+{
+ QQuickState *stateObject = qobject_cast<QQuickState*>(object);
+
+ if (!stateObject)
+ return;
+
+ QQuickStateGroup *stateGroup = stateObject->stateGroup();
+
+ QQmlProperty property(object, QLatin1String("name"), context);
+
+ stateGroup->setState(property.read().toString());
+}
+
+void QQuickDesignerSupportStates::deactivateState(QObject *object)
+{
+ QQuickState *stateObject = qobject_cast<QQuickState*>(object);
+
+ if (!stateObject)
+ return;
+
+ QQuickStateGroup *stateGroup = stateObject->stateGroup();
+
+ if (stateGroup)
+ stateGroup->setState(QString());
+}
+
+bool QQuickDesignerSupportStates::changeValueInRevertList(QObject *state, QObject *target,
+ const QQuickDesignerSupport::PropertyName &propertyName,
+ const QVariant &value)
+{
+ QQuickState *stateObject = qobject_cast<QQuickState*>(state);
+
+ if (!stateObject)
+ return false;
+
+ return stateObject->changeValueInRevertList(target, QString::fromUtf8(propertyName), value);
+}
+
+bool QQuickDesignerSupportStates::updateStateBinding(QObject *state, QObject *target,
+ const QQuickDesignerSupport::PropertyName &propertyName,
+ const QString &expression)
+{
+ QQuickState *stateObject = qobject_cast<QQuickState*>(state);
+
+ if (!stateObject)
+ return false;
+
+ return stateObject->changeValueInRevertList(target, QString::fromUtf8(propertyName), expression);
+}
+
+bool QQuickDesignerSupportStates::resetStateProperty(QObject *state, QObject *target,
+ const QQuickDesignerSupport::PropertyName &propertyName,
+ const QVariant & /* resetValue */)
+{
+ QQuickState *stateObject = qobject_cast<QQuickState*>(state);
+
+ if (!stateObject)
+ return false;
+
+ return stateObject->removeEntryFromRevertList(target, QString::fromUtf8(propertyName));
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/quick/designer/qquickdesignersupportstates_p.h b/src/quick/designer/qquickdesignersupportstates_p.h
new file mode 100644
index 0000000000..daa5a2ff01
--- /dev/null
+++ b/src/quick/designer/qquickdesignersupportstates_p.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DESIGNERSUPPORTSTATES_H
+#define DESIGNERSUPPORTSTATES_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qquickdesignersupport_p.h"
+
+#include <QVariant>
+
+QT_BEGIN_NAMESPACE
+
+class Q_QUICK_EXPORT QQuickDesignerSupportStates
+{
+public:
+ static bool isStateActive(QObject *object, QQmlContext *context);
+ static void activateState(QObject *object, QQmlContext *context);
+ static void deactivateState(QObject *object);
+ static bool changeValueInRevertList(QObject *state,
+ QObject *target,
+ const QQuickDesignerSupport::PropertyName &propertyName,
+ const QVariant &value);
+
+ static bool updateStateBinding(QObject *state, QObject *target,
+ const QQuickDesignerSupport::PropertyName &propertyName,
+ const QString &expression);
+
+ static bool resetStateProperty(QObject *state, QObject *target,
+ const QQuickDesignerSupport::PropertyName &propertyName,
+ const QVariant &);
+};
+
+QT_END_NAMESPACE
+
+#endif // DESIGNERSUPPORTSTATES_H
diff --git a/src/quick/designer/designerwindowmanager.cpp b/src/quick/designer/qquickdesignerwindowmanager.cpp
index f37d6a2180..b1ad42ddb4 100644
--- a/src/quick/designer/designerwindowmanager.cpp
+++ b/src/quick/designer/qquickdesignerwindowmanager.cpp
@@ -31,35 +31,34 @@
**
****************************************************************************/
-#include "designerwindowmanager_p.h"
+#include "qquickdesignerwindowmanager_p.h"
#include "private/qquickwindow_p.h"
#include <QtGui/QOpenGLContext>
#include <QtQuick/QQuickWindow>
-
QT_BEGIN_NAMESPACE
-DesignerWindowManager::DesignerWindowManager()
+QQuickDesignerWindowManager::QQuickDesignerWindowManager()
: m_sgContext(QSGContext::createDefaultContext())
{
m_renderContext.reset(new QSGRenderContext(m_sgContext.data()));
}
-void DesignerWindowManager::show(QQuickWindow *window)
+void QQuickDesignerWindowManager::show(QQuickWindow *window)
{
makeOpenGLContext(window);
}
-void DesignerWindowManager::hide(QQuickWindow *)
+void QQuickDesignerWindowManager::hide(QQuickWindow *)
{
}
-void DesignerWindowManager::windowDestroyed(QQuickWindow *)
+void QQuickDesignerWindowManager::windowDestroyed(QQuickWindow *)
{
}
-void DesignerWindowManager::makeOpenGLContext(QQuickWindow *window)
+void QQuickDesignerWindowManager::makeOpenGLContext(QQuickWindow *window)
{
if (!m_openGlContext) {
m_openGlContext.reset(new QOpenGLContext());
@@ -73,31 +72,31 @@ void DesignerWindowManager::makeOpenGLContext(QQuickWindow *window)
}
}
-void DesignerWindowManager::exposureChanged(QQuickWindow *)
+void QQuickDesignerWindowManager::exposureChanged(QQuickWindow *)
{
}
-QImage DesignerWindowManager::grab(QQuickWindow *)
+QImage QQuickDesignerWindowManager::grab(QQuickWindow *)
{
return QImage();
}
-void DesignerWindowManager::maybeUpdate(QQuickWindow *)
+void QQuickDesignerWindowManager::maybeUpdate(QQuickWindow *)
{
}
-QSGContext *DesignerWindowManager::sceneGraphContext() const
+QSGContext *QQuickDesignerWindowManager::sceneGraphContext() const
{
return m_sgContext.data();
}
-void DesignerWindowManager::createOpenGLContext(QQuickWindow *window)
+void QQuickDesignerWindowManager::createOpenGLContext(QQuickWindow *window)
{
window->create();
window->update();
}
-void DesignerWindowManager::update(QQuickWindow *window)
+void QQuickDesignerWindowManager::update(QQuickWindow *window)
{
makeOpenGLContext(window);
}
diff --git a/src/quick/designer/designerwindowmanager_p.h b/src/quick/designer/qquickdesignerwindowmanager_p.h
index e7a7314c20..6d98e25347 100644
--- a/src/quick/designer/designerwindowmanager_p.h
+++ b/src/quick/designer/qquickdesignerwindowmanager_p.h
@@ -60,11 +60,11 @@ class QSGRenderContext;
class QAnimationDriver;
class QOpenGLContext;
-class DesignerWindowManager : public QSGRenderLoop
+class QQuickDesignerWindowManager : public QSGRenderLoop
{
Q_OBJECT
public:
- DesignerWindowManager();
+ QQuickDesignerWindowManager();
void show(QQuickWindow *window);
void hide(QQuickWindow *window);
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp
index 75507c68d2..9932747dd3 100644
--- a/src/quick/items/context2d/qquickcanvasitem.cpp
+++ b/src/quick/items/context2d/qquickcanvasitem.cpp
@@ -46,7 +46,7 @@
#include <QtCore/QBuffer>
#include <QtCore/qdatetime.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4functionobject_p.h>
#include <private/qv4scopedvalue_p.h>
@@ -994,7 +994,7 @@ void QQuickCanvasItem::loadImage(const QUrl& url)
if (!d->pixmaps.contains(fullPathUrl)) {
QQuickPixmap* pix = new QQuickPixmap();
QQmlRefPointer<QQuickCanvasPixmap> canvasPix;
- canvasPix.take(new QQuickCanvasPixmap(pix));
+ canvasPix.adopt(new QQuickCanvasPixmap(pix));
d->pixmaps.insert(fullPathUrl, canvasPix);
pix->load(qmlEngine(this)
diff --git a/src/quick/items/context2d/qquickcanvasitem_p.h b/src/quick/items/context2d/qquickcanvasitem_p.h
index bcd7072903..4a1a59d61e 100644
--- a/src/quick/items/context2d/qquickcanvasitem_p.h
+++ b/src/quick/items/context2d/qquickcanvasitem_p.h
@@ -68,8 +68,6 @@ private:
class QQuickCanvasItem : public QQuickItem
{
Q_OBJECT
- Q_ENUMS(RenderTarget)
- Q_ENUMS(RenderStrategy)
Q_PROPERTY(bool available READ isAvailable NOTIFY availableChanged)
Q_PROPERTY(QString contextType READ contextType WRITE setContextType NOTIFY contextTypeChanged)
@@ -85,12 +83,14 @@ public:
Image,
FramebufferObject
};
+ Q_ENUM(RenderTarget)
enum RenderStrategy {
Immediate,
Threaded,
Cooperative
};
+ Q_ENUM(RenderStrategy)
QQuickCanvasItem(QQuickItem *parent = 0);
~QQuickCanvasItem();
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index 4aa3b1c8d0..0a09ee42de 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -53,7 +53,7 @@
#include <private/qv4object_p.h>
#include <private/qquickwindow_p.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4functionobject_p.h>
#include <private/qv4objectproto_p.h>
#include <private/qv4scopedvalue_p.h>
@@ -300,7 +300,7 @@ static QStringList qExtractFontFamiliesFromString(const QString &fontFamiliesStr
*/
static bool qSetFontFamilyFromTokens(QFont &font, const QStringList &fontFamilyTokens)
{
- foreach (QString fontFamilyToken, fontFamilyTokens) {
+ foreach (const QString &fontFamilyToken, fontFamilyTokens) {
QFontDatabase fontDatabase;
if (fontDatabase.hasFamily(fontFamilyToken)) {
font.setFamily(fontFamilyToken);
@@ -411,7 +411,7 @@ static QFont qt_font_from_string(const QString& fontString, const QFont &current
int usedTokens = NoTokens;
// Optional properties can be in any order, but font-size and font-family must be last.
- foreach (const QString token, tokens) {
+ foreach (const QString &token, tokens) {
if (token.compare(QLatin1String("normal")) == 0) {
if (!(usedTokens & FontStyle) || !(usedTokens & FontVariant) || !(usedTokens & FontWeight)) {
// Could be font-style, font-variant or font-weight.
@@ -884,7 +884,7 @@ struct QQuickJSContext2DPixelData : public QV4::Object
V4_OBJECT2(QQuickJSContext2DPixelData, QV4::Object)
V4_NEEDS_DESTROY
- static QV4::ReturnedValue getIndexed(QV4::Managed *m, uint index, bool *hasProperty);
+ static QV4::ReturnedValue getIndexed(const QV4::Managed *m, uint index, bool *hasProperty);
static void putIndexed(QV4::Managed *m, uint index, const QV4::Value &value);
static QV4::ReturnedValue proto_get_length(QV4::CallContext *ctx);
@@ -1379,7 +1379,7 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_fillStyle(QV4::CallContext *ctx
QV4::ScopedValue value(scope, ctx->argument(0));
- if (value->asObject()) {
+ if (value->as<Object>()) {
QColor color = scope.engine->toVariant(value, qMetaTypeId<QColor>()).value<QColor>();
if (color.isValid()) {
r->d()->context->state.fillStyle = color;
@@ -1488,7 +1488,7 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_strokeStyle(QV4::CallContext *c
QV4::ScopedValue value(scope, ctx->argument(0));
- if (value->asObject()) {
+ if (value->as<Object>()) {
QColor color = scope.engine->toVariant(value, qMetaTypeId<QColor>()).value<QColor>();
if (color.isValid()) {
r->d()->context->state.fillStyle = color;
@@ -1719,7 +1719,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createPattern(QV4::CallCon
} else {
QImage patternTexture;
- if (QV4::Object *o = ctx->args()[0].asObject()) {
+ if (const QV4::Object *o = ctx->args()[0].as<Object>()) {
QV4::ScopedString s(scope, scope.engine->newString(QStringLiteral("data")));
QV4::Scoped<QQuickJSContext2DPixelData> pixelData(scope, o->get(s));
if (!!pixelData) {
@@ -2912,7 +2912,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::CallContext
} else if (QQuickCanvasItem *canvas = qobject_cast<QQuickCanvasItem*>(qobjectWrapper->object())) {
QImage img = canvas->toImage();
if (!img.isNull())
- pixmap.take(new QQuickCanvasPixmap(img));
+ pixmap.adopt(new QQuickCanvasPixmap(img));
} else {
V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
}
@@ -2921,7 +2921,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::CallContext
if (!!imageData) {
QV4::Scoped<QQuickJSContext2DPixelData> pix(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
if (pix && !pix->d()->image.isNull()) {
- pixmap.take(new QQuickCanvasPixmap(pix->d()->image));
+ pixmap.adopt(new QQuickCanvasPixmap(pix->d()->image));
} else {
V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
}
@@ -3089,12 +3089,12 @@ QV4::ReturnedValue QQuickJSContext2DPixelData::proto_get_length(QV4::CallContext
return QV4::Encode(r->d()->image.width() * r->d()->image.height() * 4);
}
-QV4::ReturnedValue QQuickJSContext2DPixelData::getIndexed(QV4::Managed *m, uint index, bool *hasProperty)
+QV4::ReturnedValue QQuickJSContext2DPixelData::getIndexed(const QV4::Managed *m, uint index, bool *hasProperty)
{
Q_ASSERT(m->as<QQuickJSContext2DPixelData>());
- QV4::ExecutionEngine *v4 = static_cast<QQuickJSContext2DPixelData *>(m)->engine();
+ QV4::ExecutionEngine *v4 = static_cast<const QQuickJSContext2DPixelData *>(m)->engine();
QV4::Scope scope(v4);
- QV4::Scoped<QQuickJSContext2DPixelData> r(scope, static_cast<QQuickJSContext2DPixelData *>(m));
+ QV4::Scoped<QQuickJSContext2DPixelData> r(scope, static_cast<const QQuickJSContext2DPixelData *>(m));
if (index < static_cast<quint32>(r->d()->image.width() * r->d()->image.height() * 4)) {
if (hasProperty)
@@ -3357,7 +3357,7 @@ QV4::ReturnedValue QQuickContext2DStyle::gradient_proto_addColorStop(QV4::CallCo
qreal pos = ctx->args()[0].toNumber();
QColor color;
- if (ctx->args()[1].asObject()) {
+ if (ctx->args()[1].as<Object>()) {
color = scope.engine->toVariant(ctx->args()[1], qMetaTypeId<QColor>()).value<QColor>();
} else {
color = qt_color_from_string(ctx->args()[1]);
@@ -4235,7 +4235,7 @@ QQuickContext2DEngineData::QQuickContext2DEngineData(QV4::ExecutionEngine *v4)
gradientProto = proto;
proto = scope.engine->newObject();
- proto->defineAccessorProperty(scope.engine->id_length, QQuickJSContext2DPixelData::proto_get_length, 0);
+ proto->defineAccessorProperty(scope.engine->id_length(), QQuickJSContext2DPixelData::proto_get_length, 0);
pixelArrayProto = proto;
}
diff --git a/src/quick/items/context2d/qquickcontext2d_p.h b/src/quick/items/context2d/qquickcontext2d_p.h
index 67d3a2e4fb..78fa26d791 100644
--- a/src/quick/items/context2d/qquickcontext2d_p.h
+++ b/src/quick/items/context2d/qquickcontext2d_p.h
@@ -48,7 +48,7 @@
#include <private/qv8engine_p.h>
#include <QtCore/QWaitCondition>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
//#define QQUICKCONTEXT2D_DEBUG //enable this for just DEBUG purpose!
diff --git a/src/quick/items/qquickanchors.cpp b/src/quick/items/qquickanchors.cpp
index f559f166bf..606d4c45da 100644
--- a/src/quick/items/qquickanchors.cpp
+++ b/src/quick/items/qquickanchors.cpp
@@ -414,13 +414,27 @@ void QQuickAnchorsPrivate::updateMe()
void QQuickAnchorsPrivate::updateOnComplete()
{
//optimization to only set initial dependencies once, at completion time
- QSet<QQuickItem *> dependencies;
- dependencies << fill << centerIn
- << left.item << right.item << hCenter.item
- << top.item << bottom.item << vCenter.item << baseline.item;
-
- foreach (QQuickItem *dependency, dependencies)
- addDepend(dependency);
+ QQuickItem *dependencies[9];
+ dependencies[0] = fill;
+ dependencies[1] = centerIn;
+ dependencies[2] = left.item;
+ dependencies[3] = right.item;
+ dependencies[4] = hCenter.item;
+ dependencies[5] = top.item;
+ dependencies[6] = bottom.item;
+ dependencies[7] = vCenter.item;
+ dependencies[8] = baseline.item;
+
+ std::sort(dependencies, dependencies + 9);
+
+ QQuickItem *lastDependency = 0;
+ for (int i = 0; i < 9; ++i) {
+ QQuickItem *dependency = dependencies[i];
+ if (lastDependency != dependency) {
+ addDepend(dependency);
+ lastDependency = dependency;
+ }
+ }
update();
}
diff --git a/src/quick/items/qquickanimatedsprite_p.h b/src/quick/items/qquickanimatedsprite_p.h
index 4778afc88b..a10ebb4b73 100644
--- a/src/quick/items/qquickanimatedsprite_p.h
+++ b/src/quick/items/qquickanimatedsprite_p.h
@@ -70,12 +70,12 @@ class Q_AUTOTEST_EXPORT QQuickAnimatedSprite : public QQuickItem
Q_PROPERTY(bool paused READ paused WRITE setPaused NOTIFY pausedChanged)
Q_PROPERTY(int currentFrame READ currentFrame WRITE setCurrentFrame NOTIFY currentFrameChanged)
- Q_ENUMS(LoopParameters)
public:
explicit QQuickAnimatedSprite(QQuickItem *parent = 0);
enum LoopParameters {
Infinite = -1
};
+ Q_ENUM(LoopParameters)
bool running() const
{
diff --git a/src/quick/items/qquickborderimage_p.h b/src/quick/items/qquickborderimage_p.h
index f2a172fad3..8a88e3d0d3 100644
--- a/src/quick/items/qquickborderimage_p.h
+++ b/src/quick/items/qquickborderimage_p.h
@@ -44,7 +44,6 @@ class QQuickBorderImagePrivate;
class Q_AUTOTEST_EXPORT QQuickBorderImage : public QQuickImageBase
{
Q_OBJECT
- Q_ENUMS(TileMode)
Q_PROPERTY(QQuickScaleGrid *border READ border CONSTANT)
Q_PROPERTY(TileMode horizontalTileMode READ horizontalTileMode WRITE setHorizontalTileMode NOTIFY horizontalTileModeChanged)
@@ -59,6 +58,7 @@ public:
QQuickScaleGrid *border();
enum TileMode { Stretch = Qt::StretchTile, Repeat = Qt::RepeatTile, Round = Qt::RoundTile };
+ Q_ENUM(TileMode)
TileMode horizontalTileMode() const;
void setHorizontalTileMode(TileMode);
diff --git a/src/quick/items/qquickdrag_p.h b/src/quick/items/qquickdrag_p.h
index 4bd4cfc6fd..2b4b2a51d4 100644
--- a/src/quick/items/qquickdrag_p.h
+++ b/src/quick/items/qquickdrag_p.h
@@ -140,7 +140,6 @@ class Q_AUTOTEST_EXPORT QQuickDrag : public QObject
{
Q_OBJECT
- Q_ENUMS(Axis DragType)
Q_PROPERTY(QQuickItem *target READ target WRITE setTarget NOTIFY targetChanged RESET resetTarget)
Q_PROPERTY(Axis axis READ axis WRITE setAxis NOTIFY axisChanged)
Q_PROPERTY(qreal minimumX READ xmin WRITE setXmin NOTIFY minimumXChanged)
@@ -160,12 +159,14 @@ public:
~QQuickDrag();
enum DragType { None, Automatic, Internal };
+ Q_ENUM(DragType)
QQuickItem *target() const;
void setTarget(QQuickItem *target);
void resetTarget();
enum Axis { XAxis=0x01, YAxis=0x02, XAndYAxis=0x03, XandYAxis=XAndYAxis };
+ Q_ENUM(Axis)
Axis axis() const;
void setAxis(Axis);
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 19fb66c19c..ea4398bc71 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -619,7 +619,7 @@ is finished.
\qmlsignal QtQuick::Flickable::movementStarted()
This signal is emitted when the view begins moving due to user
- interaction.
+ interaction or a generated flick().
The corresponding handler is \c onMovementStarted.
*/
@@ -628,9 +628,9 @@ is finished.
\qmlsignal QtQuick::Flickable::movementEnded()
This signal is emitted when the view stops moving due to user
- interaction. If a flick was generated, this signal will
+ interaction or a generated flick(). If a flick was active, this signal will
be emitted once the flick stops. If a flick was not
- generated, this signal will be emitted when the
+ active, this signal will be emitted when the
user stops dragging - i.e. a mouse or touch release.
The corresponding handler is \c onMovementEnded.
@@ -1347,7 +1347,7 @@ void QQuickFlickable::mouseReleaseEvent(QMouseEvent *event)
if (window() && window()->mouseGrabberItem()) {
QPointF localPos = window()->mouseGrabberItem()->mapFromScene(event->windowPos());
QScopedPointer<QMouseEvent> mouseEvent(QQuickWindowPrivate::cloneMouseEvent(event, &localPos));
- window()->sendEvent(window()->mouseGrabberItem(), mouseEvent.data());
+ QCoreApplication::sendEvent(window(), mouseEvent.data());
}
// And the event has been consumed
@@ -1451,6 +1451,7 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event)
d->lastPosTime = currentTimestamp;
d->accumulatedWheelPixelDelta += QVector2D(event->pixelDelta());
d->drag(currentTimestamp, event->type(), event->posF(), d->accumulatedWheelPixelDelta, true, !d->scrollingPhase, true, velocity);
+ event->accept();
}
if (!event->isAccepted())
@@ -1670,6 +1671,9 @@ void QQuickFlickable::geometryChanged(const QRectF &newGeometry,
\qmlmethod QtQuick::Flickable::flick(qreal xVelocity, qreal yVelocity)
Flicks the content with \a xVelocity horizontally and \a yVelocity vertically in pixels/sec.
+
+ Calling this method will update the corresponding moving and flicking properties and signals,
+ just like a real flick.
*/
void QQuickFlickable::flick(qreal xVelocity, qreal yVelocity)
@@ -1679,8 +1683,15 @@ void QQuickFlickable::flick(qreal xVelocity, qreal yVelocity)
d->vData.reset();
d->hData.velocity = xVelocity;
d->vData.velocity = yVelocity;
+
bool flickedX = d->flickX(xVelocity);
bool flickedY = d->flickY(yVelocity);
+
+ if (flickedX)
+ d->hMoved = true;
+ if (flickedY)
+ d->vMoved = true;
+ movementStarting();
d->flickingStarted(flickedX, flickedY);
}
diff --git a/src/quick/items/qquickflickable_p.h b/src/quick/items/qquickflickable_p.h
index 3c3cd362dd..c974da66d6 100644
--- a/src/quick/items/qquickflickable_p.h
+++ b/src/quick/items/qquickflickable_p.h
@@ -93,7 +93,6 @@ class Q_QUICK_PRIVATE_EXPORT QQuickFlickable : public QQuickItem
Q_PROPERTY(QQmlListProperty<QQuickItem> flickableChildren READ flickableChildren)
Q_CLASSINFO("DefaultProperty", "flickableData")
- Q_ENUMS(FlickableDirection)
Q_FLAGS(BoundsBehavior)
public:
@@ -177,6 +176,7 @@ public:
QQuickItem *contentItem();
enum FlickableDirection { AutoFlickDirection=0x00, HorizontalFlick=0x01, VerticalFlick=0x02, HorizontalAndVerticalFlick=0x03 };
+ Q_ENUM(FlickableDirection)
FlickableDirection flickableDirection() const;
void setFlickableDirection(FlickableDirection);
diff --git a/src/quick/items/qquickflipable_p.h b/src/quick/items/qquickflipable_p.h
index bd2efe0676..31bfe97923 100644
--- a/src/quick/items/qquickflipable_p.h
+++ b/src/quick/items/qquickflipable_p.h
@@ -47,7 +47,6 @@ class Q_AUTOTEST_EXPORT QQuickFlipable : public QQuickItem
{
Q_OBJECT
- Q_ENUMS(Side)
Q_PROPERTY(QQuickItem *front READ front WRITE setFront NOTIFY frontChanged)
Q_PROPERTY(QQuickItem *back READ back WRITE setBack NOTIFY backChanged)
Q_PROPERTY(Side side READ side NOTIFY sideChanged)
@@ -64,6 +63,7 @@ public:
void setBack(QQuickItem *);
enum Side { Front, Back };
+ Q_ENUM(Side)
Side side() const;
Q_SIGNALS:
diff --git a/src/quick/items/qquickframebufferobject.cpp b/src/quick/items/qquickframebufferobject.cpp
index 6031315b90..74abd8cf9f 100644
--- a/src/quick/items/qquickframebufferobject.cpp
+++ b/src/quick/items/qquickframebufferobject.cpp
@@ -47,11 +47,13 @@ class QQuickFramebufferObjectPrivate : public QQuickItemPrivate
public:
QQuickFramebufferObjectPrivate()
: followsItemSize(true)
+ , mirrorVertically(false)
, node(0)
{
}
bool followsItemSize;
+ bool mirrorVertically;
mutable QSGFramebufferObjectNode *node;
};
@@ -138,6 +140,34 @@ bool QQuickFramebufferObject::textureFollowsItemSize() const
}
/*!
+ * \property QQuickFramebufferObject::mirrorVertically
+ *
+ * This property controls if the size of the FBO's contents should be mirrored
+ * vertically when drawing. This allows easy integration of third-party
+ * rendering code that does not follow the standard expectations.
+ *
+ * The default value is \c {false}.
+ *
+ * \since 5.6
+ */
+
+void QQuickFramebufferObject::setMirrorVertically(bool enable)
+{
+ Q_D(QQuickFramebufferObject);
+ if (d->mirrorVertically == enable)
+ return;
+ d->mirrorVertically = enable;
+ emit mirrorVerticallyChanged(d->mirrorVertically);
+ update();
+}
+
+bool QQuickFramebufferObject::mirrorVertically() const
+{
+ Q_D(const QQuickFramebufferObject);
+ return d->mirrorVertically;
+}
+
+/*!
* \internal
*/
void QQuickFramebufferObject::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
@@ -290,6 +320,7 @@ QSGNode *QQuickFramebufferObject::updatePaintNode(QSGNode *node, UpdatePaintNode
QQuickWindow::TextureHasAlphaChannel));
}
+ n->setTextureCoordinatesTransform(d->mirrorVertically ? QSGSimpleTextureNode::MirrorVertically : QSGSimpleTextureNode::NoTransform);
n->setFiltering(d->smooth ? QSGTexture::Linear : QSGTexture::Nearest);
n->setRect(0, 0, width(), height());
diff --git a/src/quick/items/qquickframebufferobject.h b/src/quick/items/qquickframebufferobject.h
index 4a0248c082..7fb7262222 100644
--- a/src/quick/items/qquickframebufferobject.h
+++ b/src/quick/items/qquickframebufferobject.h
@@ -49,6 +49,7 @@ class Q_QUICK_EXPORT QQuickFramebufferObject : public QQuickItem
Q_DECLARE_PRIVATE(QQuickFramebufferObject)
Q_PROPERTY(bool textureFollowsItemSize READ textureFollowsItemSize WRITE setTextureFollowsItemSize NOTIFY textureFollowsItemSizeChanged)
+ Q_PROPERTY(bool mirrorVertically READ mirrorVertically WRITE setMirrorVertically NOTIFY mirrorVerticallyChanged)
public:
@@ -73,6 +74,9 @@ public:
bool textureFollowsItemSize() const;
void setTextureFollowsItemSize(bool follows);
+ bool mirrorVertically() const;
+ void setMirrorVertically(bool enable);
+
virtual Renderer *createRenderer() const = 0;
bool isTextureProvider() const Q_DECL_OVERRIDE;
@@ -87,6 +91,7 @@ protected:
Q_SIGNALS:
void textureFollowsItemSizeChanged(bool);
+ void mirrorVerticallyChanged(bool);
private Q_SLOTS:
void invalidateSceneGraph();
diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp
index 99c77488f4..3ac9c6eb1c 100644
--- a/src/quick/items/qquickgridview.cpp
+++ b/src/quick/items/qquickgridview.cpp
@@ -267,9 +267,13 @@ qreal QQuickGridViewPrivate::originPosition() const
qreal QQuickGridViewPrivate::lastPosition() const
{
qreal pos = 0;
- if (model && model->count()) {
- // get end position of last item
- pos = (rowPosAt(model->count() - 1) + rowSize());
+ if (model && (model->count() || !visibleItems.isEmpty())) {
+ qreal lastRowPos = model->count() ? rowPosAt(model->count() - 1) : 0;
+ if (!visibleItems.isEmpty()) {
+ // If there are items in delayRemove state, they may be after any items linked to the model
+ lastRowPos = qMax(lastRowPos, static_cast<FxGridItemSG*>(visibleItems.last())->rowPos());
+ }
+ pos = lastRowPos + rowSize();
}
return pos;
}
@@ -918,13 +922,13 @@ void QQuickGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExte
tempPosition -= bias;
}
FxViewItem *topItem = snapItemAt(tempPosition+highlightRangeStart);
- if (!topItem && strictHighlightRange && currentItem) {
+ if (strictHighlightRange && currentItem) {
// StrictlyEnforceRange always keeps an item in range
updateHighlight();
topItem = currentItem;
}
FxViewItem *bottomItem = snapItemAt(tempPosition+highlightRangeEnd);
- if (!bottomItem && strictHighlightRange && currentItem) {
+ if (strictHighlightRange && currentItem) {
// StrictlyEnforceRange always keeps an item in range
updateHighlight();
bottomItem = currentItem;
diff --git a/src/quick/items/qquickgridview_p.h b/src/quick/items/qquickgridview_p.h
index 7e1ace01dd..389ef27585 100644
--- a/src/quick/items/qquickgridview_p.h
+++ b/src/quick/items/qquickgridview_p.h
@@ -52,8 +52,6 @@ class Q_AUTOTEST_EXPORT QQuickGridView : public QQuickItemView
Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged)
- Q_ENUMS(SnapMode)
- Q_ENUMS(Flow)
Q_CLASSINFO("DefaultProperty", "data")
public:
@@ -61,6 +59,7 @@ public:
FlowLeftToRight = LeftToRight,
FlowTopToBottom = TopToBottom
};
+ Q_ENUM(Flow)
QQuickGridView(QQuickItem *parent=0);
~QQuickGridView();
@@ -78,6 +77,7 @@ public:
void setCellHeight(qreal);
enum SnapMode { NoSnap, SnapToRow, SnapOneRow };
+ Q_ENUM(SnapMode)
SnapMode snapMode() const;
void setSnapMode(SnapMode mode);
diff --git a/src/quick/items/qquickimage_p.h b/src/quick/items/qquickimage_p.h
index be514ae2f5..421360bd35 100644
--- a/src/quick/items/qquickimage_p.h
+++ b/src/quick/items/qquickimage_p.h
@@ -40,12 +40,9 @@
QT_BEGIN_NAMESPACE
class QQuickImagePrivate;
-class Q_AUTOTEST_EXPORT QQuickImage : public QQuickImageBase
+class Q_QUICK_PRIVATE_EXPORT QQuickImage : public QQuickImageBase
{
Q_OBJECT
- Q_ENUMS(FillMode)
- Q_ENUMS(HAlignment)
- Q_ENUMS(VAlignment)
Q_PROPERTY(FillMode fillMode READ fillMode WRITE setFillMode NOTIFY fillModeChanged)
Q_PROPERTY(qreal paintedWidth READ paintedWidth NOTIFY paintedGeometryChanged)
@@ -62,11 +59,14 @@ public:
enum HAlignment { AlignLeft = Qt::AlignLeft,
AlignRight = Qt::AlignRight,
AlignHCenter = Qt::AlignHCenter };
+ Q_ENUM(HAlignment)
enum VAlignment { AlignTop = Qt::AlignTop,
AlignBottom = Qt::AlignBottom,
AlignVCenter = Qt::AlignVCenter };
+ Q_ENUM(VAlignment)
enum FillMode { Stretch, PreserveAspectFit, PreserveAspectCrop, Tile, TileVertically, TileHorizontally, Pad };
+ Q_ENUM(FillMode)
FillMode fillMode() const;
void setFillMode(FillMode);
diff --git a/src/quick/items/qquickimagebase.cpp b/src/quick/items/qquickimagebase.cpp
index 223cb8f46f..e54f5bb9c9 100644
--- a/src/quick/items/qquickimagebase.cpp
+++ b/src/quick/items/qquickimagebase.cpp
@@ -213,15 +213,27 @@ void QQuickImageBase::load()
d->devicePixelRatio = 1.0;
QUrl loadUrl = d->url;
- if (d->url.scheme() == QStringLiteral("image")
- || d->url.toString().endsWith(QLatin1String(".svg"))
- || d->url.toString().endsWith(QLatin1String(".svgz"))) {
- // QQuickImageProvider and SVG can generate a high resolution image when
- // sourceSize is set. If sourceSize is not set then the provider default size
- // will be used, as usual.
- if (!d->sourcesize.isEmpty())
+
+ // QQuickImageProvider and SVG can generate a high resolution image when
+ // sourceSize is set. If sourceSize is not set then the provider default size
+ // will be used, as usual.
+ bool setDevicePixelRatio = false;
+ if (!d->sourcesize.isValid()) {
+ if (loadUrl.scheme() == QStringLiteral("image")) {
+ setDevicePixelRatio = true;
+ } else {
+ QString stringUrl = loadUrl.toString();
+ if (stringUrl.endsWith(QLatin1String("svg")) ||
+ stringUrl.endsWith(QLatin1String("svgz"))) {
+ setDevicePixelRatio = true;
+ }
+ }
+
+ if (setDevicePixelRatio)
d->devicePixelRatio = targetDevicePixelRatio;
- } else {
+ }
+
+ if (!setDevicePixelRatio) {
// (possible) local file: loadUrl and d->devicePixelRatio will be modified if
// an "@2x" file is found.
resolve2xLocalFile(d->url, targetDevicePixelRatio, &loadUrl, &d->devicePixelRatio);
@@ -368,7 +380,7 @@ void QQuickImageBase::resolve2xLocalFile(const QUrl &url, qreal targetDevicePixe
// Look for an @2x version
QString localFile2x = image2xPath(localFile);
- if (!QFile(localFile2x).exists())
+ if (!QFile::exists(localFile2x))
return;
// @2x file found found: Change url and devicePixelRatio
diff --git a/src/quick/items/qquickimagebase_p.h b/src/quick/items/qquickimagebase_p.h
index 4fcfaecd7d..98943a235c 100644
--- a/src/quick/items/qquickimagebase_p.h
+++ b/src/quick/items/qquickimagebase_p.h
@@ -43,7 +43,6 @@ class QQuickImageBasePrivate;
class Q_QUICK_PRIVATE_EXPORT QQuickImageBase : public QQuickImplicitSizeItem
{
Q_OBJECT
- Q_ENUMS(Status)
Q_PROPERTY(Status status READ status NOTIFY statusChanged)
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
@@ -57,6 +56,7 @@ public:
QQuickImageBase(QQuickItem *parent=0);
~QQuickImageBase();
enum Status { Null, Ready, Loading, Error };
+ Q_ENUM(Status)
Status status() const;
qreal progress() const;
diff --git a/src/quick/items/qquickimplicitsizeitem_p_p.h b/src/quick/items/qquickimplicitsizeitem_p_p.h
index f2e502af15..d606474e9d 100644
--- a/src/quick/items/qquickimplicitsizeitem_p_p.h
+++ b/src/quick/items/qquickimplicitsizeitem_p_p.h
@@ -51,7 +51,7 @@
QT_BEGIN_NAMESPACE
-class QQuickImplicitSizeItemPrivate : public QQuickItemPrivate
+class Q_QUICK_PRIVATE_EXPORT QQuickImplicitSizeItemPrivate : public QQuickItemPrivate
{
Q_DECLARE_PUBLIC(QQuickImplicitSizeItem)
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 5fd1882216..32c3e651dd 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -1304,8 +1304,8 @@ void QQuickKeysAttached::setPriority(Priority order)
void QQuickKeysAttached::componentComplete()
{
- Q_D(QQuickKeysAttached);
#ifndef QT_NO_IM
+ Q_D(QQuickKeysAttached);
if (d->item) {
for (int ii = 0; ii < d->targets.count(); ++ii) {
QQuickItem *targetItem = d->targets.at(ii);
@@ -1608,6 +1608,85 @@ void QQuickItemPrivate::setLayoutMirror(bool mirror)
}
}
+/*!
+ \qmltype EnterKey
+ \instantiates QQuickEnterKeyAttached
+ \inqmlmodule QtQuick
+ \ingroup qtquick-input
+ \since 5.6
+ \brief Provides a property to manipulate the appearance of Enter key on
+ an on-screen keyboard.
+
+ The EnterKey attached property is used to manipulate the appearance and
+ behavior of the Enter key on an on-screen keyboard.
+*/
+
+/*!
+ \qmlproperty enumeration QtQuick::EnterKey::type
+
+ Holds the type of the Enter key.
+
+ \note Not all of these values are supported on all platforms. For
+ unsupported values the default key is used instead.
+
+ \value Qt.EnterKeyDefault The default Enter key. This can be either a
+ button to accept the input and close the
+ keyboard, or a \e Return button to enter a
+ newline in case of a multi-line input field.
+
+ \value Qt.EnterKeyReturn Show a \e Return button that inserts a
+ newline.
+
+ \value Qt.EnterKeyDone Show a \e {"Done"} button. Typically, the
+ keyboard is expected to close when the button
+ is pressed.
+
+ \value Qt.EnterKeyGo Show a \e {"Go"} button. Typically used in an
+ address bar when entering a URL.
+
+ \value Qt.EnterKeySend Show a \e {"Send"} button.
+
+ \value Qt.EnterKeySearch Show a \e {"Search"} button.
+
+ \value Qt.EnterKeyNext Show a \e {"Next"} button. Typically used in a
+ form to allow navigating to the next input
+ field without the keyboard closing.
+
+ \value Qt.EnterKeyPrevious Show a \e {"Previous"} button.
+*/
+
+QQuickEnterKeyAttached::QQuickEnterKeyAttached(QObject *parent)
+ : QObject(parent), itemPrivate(0), keyType(Qt::EnterKeyDefault)
+{
+ if (QQuickItem *item = qobject_cast<QQuickItem*>(parent)) {
+ itemPrivate = QQuickItemPrivate::get(item);
+ itemPrivate->extra.value().enterKeyAttached = this;
+ } else
+ qmlInfo(parent) << tr("EnterKey attached property only works with Items");
+}
+
+QQuickEnterKeyAttached *QQuickEnterKeyAttached::qmlAttachedProperties(QObject *object)
+{
+ return new QQuickEnterKeyAttached(object);
+}
+
+Qt::EnterKeyType QQuickEnterKeyAttached::type() const
+{
+ return keyType;
+}
+
+void QQuickEnterKeyAttached::setType(Qt::EnterKeyType type)
+{
+ if (keyType != type) {
+ keyType = type;
+#ifndef QT_NO_IM
+ if (itemPrivate && itemPrivate->activeFocus)
+ QGuiApplication::inputMethod()->update(Qt::ImEnterKeyType);
+#endif
+ typeChanged();
+ }
+}
+
void QQuickItemPrivate::setAccessible()
{
isAccessible = true;
@@ -2776,7 +2855,7 @@ void QQuickItemPrivate::refWindow(QQuickWindow *c)
window = c;
if (polishScheduled)
- QQuickWindowPrivate::get(window)->itemsToPolish.insert(q);
+ QQuickWindowPrivate::get(window)->itemsToPolish.append(q);
if (!parentItem)
QQuickWindowPrivate::get(window)->parentlessItems.insert(q);
@@ -2808,7 +2887,7 @@ void QQuickItemPrivate::derefWindow()
removeFromDirtyList();
QQuickWindowPrivate *c = QQuickWindowPrivate::get(window);
if (polishScheduled)
- c->itemsToPolish.remove(q);
+ c->itemsToPolish.removeOne(q);
QMutableHashIterator<int, QQuickItem *> itemTouchMapIt(c->itemForTouchPointId);
while (itemTouchMapIt.hasNext()) {
if (itemTouchMapIt.next().value() == q)
@@ -3960,6 +4039,11 @@ QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
case Qt::ImPreferredLanguage:
if (d->extra.isAllocated() && d->extra->keyHandler)
v = d->extra->keyHandler->inputMethodQuery(query);
+ break;
+ case Qt::ImEnterKeyType:
+ if (d->extra.isAllocated() && d->extra->enterKeyAttached)
+ v = d->extra->enterKeyAttached->type();
+ break;
default:
break;
}
@@ -4102,7 +4186,7 @@ void QQuickItem::polish()
if (d->window) {
QQuickWindowPrivate *p = QQuickWindowPrivate::get(d->window);
bool maybeupdate = p->itemsToPolish.isEmpty();
- p->itemsToPolish.insert(this);
+ p->itemsToPolish.append(this);
if (maybeupdate) d->window->maybeUpdate();
}
}
@@ -7839,6 +7923,7 @@ void QQuickItemLayer::updateMatrix()
QQuickItemPrivate::ExtraData::ExtraData()
: z(0), scale(1), rotation(0), opacity(1),
contents(0), screenAttached(0), layoutDirectionAttached(0),
+ enterKeyAttached(0),
keyHandler(0), layer(0),
effectRefCount(0), hideRefCount(0),
opacityNode(0), clipNode(0), rootNode(0),
diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h
index 463113386b..d92910ce9c 100644
--- a/src/quick/items/qquickitem.h
+++ b/src/quick/items/qquickitem.h
@@ -141,7 +141,6 @@ class Q_QUICK_EXPORT QQuickItem : public QObject, public QQmlParserStatus
Q_PRIVATE_PROPERTY(QQuickItem::d_func(), QQuickItemLayer *layer READ layer DESIGNABLE false CONSTANT FINAL)
- Q_ENUMS(TransformOrigin)
Q_CLASSINFO("DefaultProperty", "data")
Q_CLASSINFO("qt_HasQmlAccessors", "true")
@@ -187,6 +186,7 @@ public:
Left, Center, Right,
BottomLeft, Bottom, BottomRight
};
+ Q_ENUM(TransformOrigin)
QQuickItem(QQuickItem *parent = 0);
virtual ~QQuickItem();
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index 64d8bd0ede..5e0246c32e 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -78,6 +78,7 @@ QT_BEGIN_NAMESPACE
class QNetworkReply;
class QQuickItemKeyFilter;
class QQuickLayoutMirroringAttached;
+class QQuickEnterKeyAttached;
class QQuickScreenAttached;
class QQuickContents : public QQuickItemChangeListener
@@ -338,6 +339,7 @@ public:
QQuickContents *contents;
QQuickScreenAttached *screenAttached;
QQuickLayoutMirroringAttached* layoutDirectionAttached;
+ QQuickEnterKeyAttached *enterKeyAttached;
QQuickItemKeyFilter *keyHandler;
mutable QQuickItemLayer *layer;
#ifndef QT_NO_CURSOR
@@ -645,8 +647,6 @@ class Q_QUICK_PRIVATE_EXPORT QQuickKeyNavigationAttached : public QObject, publi
Q_PROPERTY(QQuickItem *backtab READ backtab WRITE setBacktab NOTIFY backtabChanged)
Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged)
- Q_ENUMS(Priority)
-
public:
QQuickKeyNavigationAttached(QObject * = 0);
@@ -664,6 +664,7 @@ public:
void setBacktab(QQuickItem *);
enum Priority { BeforeItem, AfterItem };
+ Q_ENUM(Priority)
Priority priority() const;
void setPriority(Priority);
@@ -710,6 +711,27 @@ private:
QQuickItemPrivate *itemPrivate;
};
+class QQuickEnterKeyAttached : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(Qt::EnterKeyType type READ type WRITE setType NOTIFY typeChanged)
+
+public:
+ explicit QQuickEnterKeyAttached(QObject *parent = Q_NULLPTR);
+
+ Qt::EnterKeyType type() const;
+ void setType(Qt::EnterKeyType type);
+
+ static QQuickEnterKeyAttached *qmlAttachedProperties(QObject *);
+Q_SIGNALS:
+ void typeChanged();
+private:
+ friend class QQuickItemPrivate;
+ QQuickItemPrivate *itemPrivate;
+
+ Qt::EnterKeyType keyType;
+};
+
class QQuickKeysAttachedPrivate : public QObjectPrivate
{
public:
@@ -739,8 +761,6 @@ class QQuickKeysAttached : public QObject, public QQuickItemKeyFilter
Q_PROPERTY(QQmlListProperty<QQuickItem> forwardTo READ forwardTo)
Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged)
- Q_ENUMS(Priority)
-
public:
QQuickKeysAttached(QObject *parent=0);
~QQuickKeysAttached();
@@ -755,6 +775,7 @@ public:
}
enum Priority { BeforeItem, AfterItem};
+ Q_ENUM(Priority)
Priority priority() const;
void setPriority(Priority);
@@ -895,5 +916,7 @@ QML_DECLARE_TYPE(QQuickKeyNavigationAttached)
QML_DECLARE_TYPEINFO(QQuickKeyNavigationAttached, QML_HAS_ATTACHED_PROPERTIES)
QML_DECLARE_TYPE(QQuickLayoutMirroringAttached)
QML_DECLARE_TYPEINFO(QQuickLayoutMirroringAttached, QML_HAS_ATTACHED_PROPERTIES)
+QML_DECLARE_TYPE(QQuickEnterKeyAttached)
+QML_DECLARE_TYPEINFO(QQuickEnterKeyAttached, QML_HAS_ATTACHED_PROPERTIES)
#endif // QQUICKITEM_P_H
diff --git a/src/quick/items/qquickitemanimation_p.h b/src/quick/items/qquickitemanimation_p.h
index 907687a2bd..9f0b3dccb8 100644
--- a/src/quick/items/qquickitemanimation_p.h
+++ b/src/quick/items/qquickitemanimation_p.h
@@ -136,7 +136,7 @@ public:
BottomFirst,
TopFirst
};
- Q_ENUMS(Orientation)
+ Q_ENUM(Orientation)
int duration() const;
void setDuration(int);
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index 5fbae66b6c..4df1ef038c 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -158,11 +158,6 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickPathView>(uri,major,minor,"PathView");
qmlRegisterUncreatableType<QQuickBasePositioner>(uri,major,minor,"Positioner",
QStringLiteral("Positioner is an abstract type that is only available as an attached property."));
-#ifndef QT_NO_VALIDATOR
- qmlRegisterType<QQuickIntValidator>(uri,major,minor,"IntValidator");
- qmlRegisterType<QQuickDoubleValidator>(uri,major,minor,"DoubleValidator");
- qmlRegisterType<QRegExpValidator>(uri,major,minor,"RegExpValidator");
-#endif
qmlRegisterType<QQuickRectangle>(uri,major,minor,"Rectangle");
qmlRegisterType<QQuickRepeater>(uri,major,minor,"Repeater");
qmlRegisterType<QQuickRow>(uri,major,minor,"Row");
@@ -190,9 +185,6 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickCurve>();
qmlRegisterType<QQuickScaleGrid>();
qmlRegisterType<QQuickTextLine>();
-#ifndef QT_NO_VALIDATOR
- qmlRegisterType<QValidator>();
-#endif
qmlRegisterType<QQuickPen>();
qmlRegisterType<QQuickFlickableVisibleArea>();
qRegisterMetaType<QQuickAnchorLine>("QQuickAnchorLine");
@@ -269,6 +261,18 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickPinchArea, 1>(uri, 2, 5,"PinchArea");
qmlRegisterType<QQuickImage, 2>(uri, 2, 5,"Image");
qmlRegisterType<QQuickMouseArea, 2>(uri, 2, 5, "MouseArea");
+
+ qmlRegisterType<QQuickText, 6>(uri, 2, 6, "Text");
+ qmlRegisterType<QQuickTextEdit, 6>(uri, 2, 6, "TextEdit");
+ qmlRegisterType<QQuickTextInput, 6>(uri, 2, 6, "TextInput");
+ qmlRegisterUncreatableType<QQuickBasePositioner, 6>(uri, 2, 6, "Positioner",
+ QStringLiteral("Positioner is an abstract type that is only available as an attached property."));
+ qmlRegisterType<QQuickColumn, 6>(uri, 2, 6, "Column");
+ qmlRegisterType<QQuickRow, 6>(uri, 2, 6, "Row");
+ qmlRegisterType<QQuickGrid, 6>(uri, 2, 6, "Grid");
+ qmlRegisterType<QQuickFlow, 6>(uri, 2, 6, "Flow");
+ qmlRegisterUncreatableType<QQuickEnterKeyAttached, 6>(uri, 2, 6, "EnterKey",
+ QQuickEnterKeyAttached::tr("EnterKey is only available via attached properties"));
}
static void initResources()
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 01ef1e65f7..d4c8c3f8ee 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -71,19 +71,19 @@ FxViewItem::~FxViewItem()
qreal FxViewItem::itemX() const
{
- return transitionableItem ? transitionableItem->itemX() : item->x();
+ return transitionableItem ? transitionableItem->itemX() : (item ? item->x() : 0);
}
qreal FxViewItem::itemY() const
{
- return transitionableItem ? transitionableItem->itemY() : item->y();
+ return transitionableItem ? transitionableItem->itemY() : (item ? item->y() : 0);
}
void FxViewItem::moveTo(const QPointF &pos, bool immediate)
{
if (transitionableItem)
transitionableItem->moveTo(pos, immediate);
- else
+ else if (item)
item->setPosition(pos);
}
@@ -91,21 +91,26 @@ void FxViewItem::setVisible(bool visible)
{
if (!visible && transitionableItem && transitionableItem->transitionScheduledOrRunning())
return;
- QQuickItemPrivate::get(item)->setCulled(!visible);
+ if (item)
+ QQuickItemPrivate::get(item)->setCulled(!visible);
}
void FxViewItem::trackGeometry(bool track)
{
if (track) {
if (!trackGeom) {
- QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
- itemPrivate->addItemChangeListener(QQuickItemViewPrivate::get(view), QQuickItemPrivate::Geometry);
+ if (item) {
+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+ itemPrivate->addItemChangeListener(QQuickItemViewPrivate::get(view), QQuickItemPrivate::Geometry);
+ }
trackGeom = true;
}
} else {
if (trackGeom) {
- QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
- itemPrivate->removeItemChangeListener(QQuickItemViewPrivate::get(view), QQuickItemPrivate::Geometry);
+ if (item) {
+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+ itemPrivate->removeItemChangeListener(QQuickItemViewPrivate::get(view), QQuickItemPrivate::Geometry);
+ }
trackGeom = false;
}
}
@@ -905,11 +910,7 @@ void QQuickItemViewPrivate::positionViewAtIndex(int index, int mode)
qreal pos = isContentFlowReversed() ? -position() - size() : position();
FxViewItem *item = visibleItem(idx);
- qreal maxExtent;
- if (layoutOrientation() == Qt::Vertical)
- maxExtent = isContentFlowReversed() ? q->minYExtent()-size(): -q->maxYExtent();
- else
- maxExtent = isContentFlowReversed() ? q->minXExtent()-size(): -q->maxXExtent();
+ qreal maxExtent = calculatedMaxExtent();
if (!item) {
qreal itemPos = positionAt(idx);
changedVisibleIndex(idx);
@@ -955,11 +956,7 @@ void QQuickItemViewPrivate::positionViewAtIndex(int index, int mode)
break;
}
pos = qMin(pos, maxExtent);
- qreal minExtent;
- if (layoutOrientation() == Qt::Vertical)
- minExtent = isContentFlowReversed() ? q->maxYExtent()-size(): -q->minYExtent();
- else
- minExtent = isContentFlowReversed() ? q->maxXExtent()-size(): -q->minXExtent();
+ qreal minExtent = calculatedMinExtent();
pos = qMax(pos, minExtent);
moveReason = QQuickItemViewPrivate::Other;
q->cancelFlick();
@@ -1130,6 +1127,29 @@ qreal QQuickItemViewPrivate::maxExtentForAxis(const AxisData &axisData, bool for
return extent;
}
+qreal QQuickItemViewPrivate::calculatedMinExtent() const
+{
+ Q_Q(const QQuickItemView);
+ qreal minExtent;
+ if (layoutOrientation() == Qt::Vertical)
+ minExtent = isContentFlowReversed() ? q->maxYExtent() - size(): -q->minYExtent();
+ else
+ minExtent = isContentFlowReversed() ? q->maxXExtent() - size(): -q->minXExtent();
+ return minExtent;
+
+}
+
+qreal QQuickItemViewPrivate::calculatedMaxExtent() const
+{
+ Q_Q(const QQuickItemView);
+ qreal maxExtent;
+ if (layoutOrientation() == Qt::Vertical)
+ maxExtent = isContentFlowReversed() ? q->minYExtent() - size(): -q->maxYExtent();
+ else
+ maxExtent = isContentFlowReversed() ? q->minXExtent() - size(): -q->maxXExtent();
+ return maxExtent;
+}
+
// for debugging only
void QQuickItemViewPrivate::checkVisible() const
{
@@ -1199,7 +1219,7 @@ void QQuickItemView::destroyRemoved()
for (QList<FxViewItem*>::Iterator it = d->visibleItems.begin();
it != d->visibleItems.end();) {
FxViewItem *item = *it;
- if (item->index == -1 && item->attached->delayRemove() == false) {
+ if (item->index == -1 && (!item->attached || item->attached->delayRemove() == false)) {
if (d->transitioner && d->transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, true)) {
// don't remove from visibleItems until next layout()
d->runDelayedRemoveTransition = true;
@@ -1277,10 +1297,12 @@ void QQuickItemView::trackedPositionChanged()
if (trackedPos < pos + d->highlightRangeStart)
pos = trackedPos - d->highlightRangeStart;
if (d->highlightRange != StrictlyEnforceRange) {
- if (pos > d->endPosition() - d->size())
- pos = d->endPosition() - d->size();
- if (pos < d->startPosition())
- pos = d->startPosition();
+ qreal maxExtent = d->calculatedMaxExtent();
+ if (pos > maxExtent)
+ pos = maxExtent;
+ qreal minExtent = d->calculatedMinExtent();
+ if (pos < minExtent)
+ pos = minExtent;
}
} else {
if (d->trackedItem != d->currentItem) {
@@ -1344,7 +1366,7 @@ void QQuickItemView::geometryChanged(const QRectF &newGeometry, const QRectF &ol
{
Q_D(QQuickItemView);
d->markExtentsDirty();
- if (isComponentComplete() && d->isValid())
+ if (isComponentComplete() && (d->isValid() || !d->visibleItems.isEmpty()))
d->forceLayoutPolish();
QQuickFlickable::geometryChanged(newGeometry, oldGeometry);
}
@@ -1641,7 +1663,8 @@ void QQuickItemViewPrivate::updateCurrent(int modelIndex)
applyPendingChanges();
if (!q->isComponentComplete() || !isValid() || modelIndex < 0 || modelIndex >= model->count()) {
if (currentItem) {
- currentItem->attached->setIsCurrentItem(false);
+ if (currentItem->attached)
+ currentItem->attached->setIsCurrentItem(false);
releaseItem(currentItem);
currentItem = 0;
currentIndex = modelIndex;
@@ -1664,11 +1687,12 @@ void QQuickItemViewPrivate::updateCurrent(int modelIndex)
int oldCurrentIndex = currentIndex;
currentIndex = modelIndex;
currentItem = createItem(modelIndex, false);
- if (oldCurrentItem && (!currentItem || oldCurrentItem->item != currentItem->item))
+ if (oldCurrentItem && oldCurrentItem->attached && (!currentItem || oldCurrentItem->item != currentItem->item))
oldCurrentItem->attached->setIsCurrentItem(false);
if (currentItem) {
currentItem->item->setFocus(true);
- currentItem->attached->setIsCurrentItem(true);
+ if (currentItem->attached)
+ currentItem->attached->setIsCurrentItem(true);
initializeCurrentItem();
}
@@ -1806,7 +1830,7 @@ void QQuickItemViewPrivate::updateViewport()
{
Q_Q(QQuickItemView);
qreal extra = headerSize() + footerSize();
- qreal contentSize = isValid() ? (endPosition() - startPosition()) : 0.0;
+ qreal contentSize = isValid() || !visibleItems.isEmpty() ? (endPosition() - startPosition()) : 0.0;
if (layoutOrientation() == Qt::Vertical)
q->setContentHeight(contentSize + extra);
else
@@ -1824,6 +1848,7 @@ void QQuickItemViewPrivate::layout()
if (!isValid() && !visibleItems.count()) {
clear();
setPosition(contentStartOffset());
+ updateViewport();
if (transitioner)
transitioner->setPopulateTransitionEnabled(false);
inLayout = false;
@@ -1967,7 +1992,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
QQmlChangeSet::Change removal;
for (QList<FxViewItem*>::Iterator it = visibleItems.begin(); it != visibleItems.end();) {
FxViewItem *item = *it;
- if (item->index == -1 && !item->attached->delayRemove()) {
+ if (item->index == -1 && (!item->attached || !item->attached->delayRemove())) {
removeItem(item, removal, &removalResult);
removedCount++;
it = visibleItems.erase(it);
@@ -2007,8 +2032,10 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
}
itemCount += insertions[i].count;
}
- for (int i=0; i<newItems.count(); i++)
- newItems.at(i)->attached->emitAdd();
+ for (int i=0; i<newItems.count(); i++) {
+ if (newItems.at(i)->attached)
+ newItems.at(i)->attached->emitAdd();
+ }
// for each item that was moved directly into the view as a result of a move(),
// find the index it was moved from in order to set its initial position, so that we
@@ -2040,7 +2067,8 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
if (currentChanges.currentChanged) {
if (currentChanges.currentRemoved && currentItem) {
- currentItem->attached->setIsCurrentItem(false);
+ if (currentItem->item && currentItem->attached)
+ currentItem->attached->setIsCurrentItem(false);
releaseItem(currentItem);
currentItem = 0;
}
@@ -2092,10 +2120,10 @@ bool QQuickItemViewPrivate::applyRemovalChange(const QQmlChangeSet::Change &remo
} else {
// removed item
visibleAffected = true;
- if (!removal.isMove())
+ if (!removal.isMove() && item->item && item->attached)
item->attached->emitRemove();
- if (item->attached->delayRemove() && !removal.isMove()) {
+ if (item->item && item->attached && item->attached->delayRemove() && !removal.isMove()) {
item->index = -1;
QObject::connect(item->attached, SIGNAL(delayRemoveChanged()), q, SLOT(destroyRemoved()), Qt::QueuedConnection);
++it;
@@ -2352,12 +2380,14 @@ bool QQuickItemViewPrivate::releaseItem(FxViewItem *item)
item->trackGeometry(false);
QQmlInstanceModel::ReleaseFlags flags = model->release(item->item);
- if (flags == 0) {
- // item was not destroyed, and we no longer reference it.
- QQuickItemPrivate::get(item->item)->setCulled(true);
- unrequestedItems.insert(item->item, model->indexOf(item->item, q));
- } else if (flags & QQmlInstanceModel::Destroyed) {
- item->item->setParentItem(0);
+ if (item->item) {
+ if (flags == 0) {
+ // item was not destroyed, and we no longer reference it.
+ QQuickItemPrivate::get(item->item)->setCulled(true);
+ unrequestedItems.insert(item->item, model->indexOf(item->item, q));
+ } else if (flags & QQmlInstanceModel::Destroyed) {
+ item->item->setParentItem(0);
+ }
}
delete item;
return flags != QQmlInstanceModel::Referenced;
@@ -2421,7 +2451,7 @@ void QQuickItemViewPrivate::updateUnrequestedIndexes()
void QQuickItemViewPrivate::updateUnrequestedPositions()
{
- for (QHash<QQuickItem*,int>::const_iterator it = unrequestedItems.begin(), cend = unrequestedItems.end(); it != cend; ++it)
+ for (QHash<QQuickItem*,int>::const_iterator it = unrequestedItems.cbegin(), cend = unrequestedItems.cend(); it != cend; ++it)
repositionPackageItemAt(it.key(), it.value());
}
diff --git a/src/quick/items/qquickitemview_p.h b/src/quick/items/qquickitemview_p.h
index 6e5ae032c2..3e28ff336d 100644
--- a/src/quick/items/qquickitemview_p.h
+++ b/src/quick/items/qquickitemview_p.h
@@ -88,11 +88,6 @@ class Q_AUTOTEST_EXPORT QQuickItemView : public QQuickFlickable
Q_PROPERTY(qreal preferredHighlightEnd READ preferredHighlightEnd WRITE setPreferredHighlightEnd NOTIFY preferredHighlightEndChanged RESET resetPreferredHighlightEnd)
Q_PROPERTY(int highlightMoveDuration READ highlightMoveDuration WRITE setHighlightMoveDuration NOTIFY highlightMoveDurationChanged)
- Q_ENUMS(HighlightRangeMode)
- Q_ENUMS(PositionMode)
- Q_ENUMS(VerticalLayoutDirection)
- Q_ENUMS(LayoutDirection)
-
public:
// this holds all layout enum values so they can be referred to by other enums
// to ensure consistent values - e.g. QML references to GridView.TopToBottom flow
@@ -103,11 +98,13 @@ public:
VerticalTopToBottom,
VerticalBottomToTop
};
+ Q_ENUM(LayoutDirection)
enum VerticalLayoutDirection {
TopToBottom = VerticalTopToBottom,
BottomToTop = VerticalBottomToTop
};
+ Q_ENUM(VerticalLayoutDirection)
QQuickItemView(QQuickFlickablePrivate &dd, QQuickItem *parent = 0);
~QQuickItemView();
@@ -185,6 +182,7 @@ public:
virtual void setHighlightFollowsCurrentItem(bool);
enum HighlightRangeMode { NoHighlightRange, ApplyRange, StrictlyEnforceRange };
+ Q_ENUM(HighlightRangeMode)
HighlightRangeMode highlightRangeMode() const;
void setHighlightRangeMode(HighlightRangeMode mode);
@@ -200,6 +198,7 @@ public:
virtual void setHighlightMoveDuration(int);
enum PositionMode { Beginning, Center, End, Visible, Contain, SnapPosition };
+ Q_ENUM(PositionMode)
Q_INVOKABLE void positionViewAtIndex(int index, int mode);
Q_INVOKABLE int indexAt(qreal x, qreal y) const;
diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h
index a8352b229e..0931db4e56 100644
--- a/src/quick/items/qquickitemview_p_p.h
+++ b/src/quick/items/qquickitemview_p_p.h
@@ -53,6 +53,8 @@ public:
qreal itemX() const;
qreal itemY() const;
+ inline qreal itemWidth() const { return item ? item->width() : 0; }
+ inline qreal itemHeight() const { return item ? item->height() : 0; }
void moveTo(const QPointF &pos, bool immediate);
void setVisible(bool visible);
@@ -75,7 +77,7 @@ public:
virtual bool contains(qreal x, qreal y) const = 0;
- QQuickItem *item;
+ QPointer<QQuickItem> item;
QQuickItemView *view;
QQuickItemViewTransitionableItem *transitionableItem;
QQuickItemViewAttached *attached;
@@ -198,6 +200,8 @@ public:
qreal minExtentForAxis(const AxisData &axisData, bool forXAxis) const;
qreal maxExtentForAxis(const AxisData &axisData, bool forXAxis) const;
+ qreal calculatedMinExtent() const;
+ qreal calculatedMaxExtent() const;
void applyPendingChanges();
bool applyModelChanges(ChangeResult *insertionResult, ChangeResult *removalResult);
diff --git a/src/quick/items/qquickitemviewtransition.cpp b/src/quick/items/qquickitemviewtransition.cpp
index 7fa6cdc161..6fa299bf03 100644
--- a/src/quick/items/qquickitemviewtransition.cpp
+++ b/src/quick/items/qquickitemviewtransition.cpp
@@ -34,6 +34,7 @@
#include "qquickitemviewtransition_p.h"
#include <QtQuick/qquickitem.h>
#include <QtQuick/private/qquicktransition_p.h>
+#include <QtQuick/private/qquicktransitionmanager_p_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/quick/items/qquickitemviewtransition_p.h b/src/quick/items/qquickitemviewtransition_p.h
index 170072a814..6f93697cc5 100644
--- a/src/quick/items/qquickitemviewtransition_p.h
+++ b/src/quick/items/qquickitemviewtransition_p.h
@@ -34,16 +34,20 @@
#ifndef QQUICKITEMVIEWTRANSITION_P_P_H
#define QQUICKITEMVIEWTRANSITION_P_P_H
-#include <private/qquicktransitionmanager_p_p.h>
+#include <QtQuick/private/qtquickglobal_p.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qpoint.h>
+#include <QtQml/qqml.h>
QT_BEGIN_NAMESPACE
class QQuickItem;
+class QQuickTransition;
class QQuickItemViewTransitionableItem;
class QQuickItemViewTransitionJob;
-class QQuickItemViewTransitionChangeListener
+class Q_QUICK_PRIVATE_EXPORT QQuickItemViewTransitionChangeListener
{
public:
QQuickItemViewTransitionChangeListener() {}
@@ -53,7 +57,7 @@ public:
};
-class QQuickItemViewTransitioner
+class Q_QUICK_PRIVATE_EXPORT QQuickItemViewTransitioner
{
public:
enum TransitionType {
@@ -113,7 +117,7 @@ private:
/*
An item that can be transitioned using QQuickViewTransitionJob.
*/
-class QQuickItemViewTransitionableItem
+class Q_QUICK_PRIVATE_EXPORT QQuickItemViewTransitionableItem
{
public:
QQuickItemViewTransitionableItem(QQuickItem *i);
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index 20b6dd5b36..a1d765d6ec 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -267,18 +267,18 @@ public:
}
qreal itemPosition() const {
if (view->orientation() == QQuickListView::Vertical)
- return (view->verticalLayoutDirection() == QQuickItemView::BottomToTop ? -item->height()-itemY() : itemY());
+ return (view->verticalLayoutDirection() == QQuickItemView::BottomToTop ? -itemHeight()-itemY() : itemY());
else
- return (view->effectiveLayoutDirection() == Qt::RightToLeft ? -item->width()-itemX() : itemX());
+ return (view->effectiveLayoutDirection() == Qt::RightToLeft ? -itemWidth()-itemX() : itemX());
}
qreal size() const Q_DECL_OVERRIDE {
if (section())
- return (view->orientation() == QQuickListView::Vertical ? item->height()+section()->height() : item->width()+section()->width());
+ return (view->orientation() == QQuickListView::Vertical ? itemHeight()+section()->height() : itemWidth()+section()->width());
else
- return (view->orientation() == QQuickListView::Vertical ? item->height() : item->width());
+ return (view->orientation() == QQuickListView::Vertical ? itemHeight() : itemWidth());
}
qreal itemSize() const {
- return (view->orientation() == QQuickListView::Vertical ? item->height() : item->width());
+ return (view->orientation() == QQuickListView::Vertical ? itemHeight() : itemWidth());
}
qreal sectionSize() const Q_DECL_OVERRIDE {
if (section())
@@ -289,11 +289,11 @@ public:
if (view->orientation() == QQuickListView::Vertical) {
return (view->verticalLayoutDirection() == QQuickItemView::BottomToTop
? -itemY()
- : itemY() + item->height());
+ : itemY() + itemHeight());
} else {
return (view->effectiveLayoutDirection() == Qt::RightToLeft
? -itemX()
- : itemX() + item->width());
+ : itemX() + itemWidth());
}
}
void setPosition(qreal pos, bool immediate = false) {
@@ -320,8 +320,8 @@ public:
item->setWidth(size);
}
bool contains(qreal x, qreal y) const Q_DECL_OVERRIDE {
- return (x >= itemX() && x < itemX() + item->width() &&
- y >= itemY() && y < itemY() + item->height());
+ return (x >= itemX() && x < itemX() + itemWidth() &&
+ y >= itemY() && y < itemY() + itemHeight());
}
QQuickListView *view;
@@ -332,7 +332,7 @@ private:
if (view->verticalLayoutDirection() == QQuickItemView::BottomToTop) {
if (section())
pos += section()->height();
- return QPointF(itemX(), -item->height() - pos);
+ return QPointF(itemX(), -itemHeight() - pos);
} else {
if (section())
pos += section()->height();
@@ -342,7 +342,7 @@ private:
if (view->effectiveLayoutDirection() == Qt::RightToLeft) {
if (section())
pos += section()->width();
- return QPointF(-item->width() - pos, itemY());
+ return QPointF(-itemWidth() - pos, itemY());
} else {
if (section())
pos += section()->width();
@@ -427,14 +427,24 @@ qreal QQuickListViewPrivate::lastPosition() const
{
qreal pos = 0;
if (!visibleItems.isEmpty()) {
- int invisibleCount = visibleItems.count() - visibleIndex;
+ int invisibleCount = INT_MIN;
+ int delayRemovedCount = 0;
for (int i = visibleItems.count()-1; i >= 0; --i) {
if (visibleItems.at(i)->index != -1) {
- invisibleCount = model->count() - visibleItems.at(i)->index - 1;
+ // Find the invisible count after the last visible item with known index
+ invisibleCount = model->count() - (visibleItems.at(i)->index + 1 + delayRemovedCount);
break;
+ } else if (visibleItems.at(i)->attached->delayRemove()) {
+ ++delayRemovedCount;
}
}
- pos = (*(--visibleItems.constEnd()))->endPosition() + invisibleCount * (averageSize + spacing);
+ if (invisibleCount == INT_MIN) {
+ // All visible items are in delayRemove state
+ invisibleCount = model->count();
+ }
+ pos = (*(--visibleItems.constEnd()))->endPosition();
+ if (invisibleCount > 0)
+ pos += invisibleCount * (averageSize + spacing);
} else if (model && model->count()) {
pos = (model->count() * averageSize + (model->count()-1) * spacing);
}
@@ -599,10 +609,11 @@ bool QQuickListViewPrivate::releaseItem(FxViewItem *item)
if (!item || !model)
return true;
+ QPointer<QQuickItem> it = item->item;
QQuickListViewAttached *att = static_cast<QQuickListViewAttached*>(item->attached);
bool released = QQuickItemViewPrivate::releaseItem(item);
- if (released && att && att->m_sectionItem) {
+ if (released && it && att && att->m_sectionItem) {
// We hold no more references to this item
int i = 0;
do {
@@ -657,10 +668,11 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal
while (modelIndex < model->count() && pos <= fillTo) {
if (!(item = static_cast<FxListItemSG*>(createItem(modelIndex, doBuffer))))
break;
- qCDebug(lcItemViewDelegateLifecycle) << "refill: append item" << modelIndex << "pos" << pos << "buffer" << doBuffer << "item" << item->item->objectName();
+ qCDebug(lcItemViewDelegateLifecycle) << "refill: append item" << modelIndex << "pos" << pos << "buffer" << doBuffer << "item" << (QObject *)(item->item);
if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems()
item->setPosition(pos, true);
- QQuickItemPrivate::get(item->item)->setCulled(doBuffer);
+ if (item->item)
+ QQuickItemPrivate::get(item->item)->setCulled(doBuffer);
pos += item->size() + spacing;
visibleItems.append(item);
++modelIndex;
@@ -673,12 +685,13 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal
while (visibleIndex > 0 && visibleIndex <= model->count() && visiblePos > fillFrom) {
if (!(item = static_cast<FxListItemSG*>(createItem(visibleIndex-1, doBuffer))))
break;
- qCDebug(lcItemViewDelegateLifecycle) << "refill: prepend item" << visibleIndex-1 << "current top pos" << visiblePos << "buffer" << doBuffer << "item" << item->item->objectName();
+ qCDebug(lcItemViewDelegateLifecycle) << "refill: prepend item" << visibleIndex-1 << "current top pos" << visiblePos << "buffer" << doBuffer << "item" << (QObject *)(item->item);
--visibleIndex;
visiblePos -= item->size() + spacing;
if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems()
item->setPosition(visiblePos, true);
- QQuickItemPrivate::get(item->item)->setCulled(doBuffer);
+ if (item->item)
+ QQuickItemPrivate::get(item->item)->setCulled(doBuffer);
visibleItems.prepend(item);
changed = true;
}
@@ -709,7 +722,7 @@ bool QQuickListViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal buffer
visibleIndex++;
visibleItems.removeAt(index);
if (item->transitionScheduledOrRunning()) {
- qCDebug(lcItemViewDelegateLifecycle) << "\tnot releasing animating item" << item->index << item->item->objectName();
+ qCDebug(lcItemViewDelegateLifecycle) << "\tnot releasing animating item" << item->index << (QObject *)(item->item);
item->releaseAfterTransition = true;
releasePendingTransition.append(item);
} else {
@@ -728,10 +741,10 @@ bool QQuickListViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal buffer
while (visibleItems.count() > 1 && (item = visibleItems.last()) && item->position() > bufferTo) {
if (item->attached->delayRemove())
break;
- qCDebug(lcItemViewDelegateLifecycle) << "refill: remove last" << visibleIndex+visibleItems.count()-1 << item->position() << item->item->objectName();
+ qCDebug(lcItemViewDelegateLifecycle) << "refill: remove last" << visibleIndex+visibleItems.count()-1 << item->position() << (QObject *)(item->item);
visibleItems.removeLast();
if (item->transitionScheduledOrRunning()) {
- qCDebug(lcItemViewDelegateLifecycle) << "\tnot releasing animating item" << item->index << item->item->objectName();
+ qCDebug(lcItemViewDelegateLifecycle) << "\tnot releasing animating item" << item->index << (QObject *)(item->item);
item->releaseAfterTransition = true;
releasePendingTransition.append(item);
} else {
@@ -1457,13 +1470,13 @@ void QQuickListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExte
tempPosition -= bias;
}
FxViewItem *topItem = snapItemAt(tempPosition+highlightRangeStart);
- if (!topItem && strictHighlightRange && currentItem) {
+ if (strictHighlightRange && currentItem) {
// StrictlyEnforceRange always keeps an item in range
updateHighlight();
topItem = currentItem;
}
FxViewItem *bottomItem = snapItemAt(tempPosition+highlightRangeEnd);
- if (!bottomItem && strictHighlightRange && currentItem) {
+ if (strictHighlightRange && currentItem) {
// StrictlyEnforceRange always keeps an item in range
updateHighlight();
bottomItem = currentItem;
@@ -2844,7 +2857,8 @@ void QQuickListView::viewportMoved(Qt::Orientations orient)
qreal to = d->isContentFlowReversed() ? -d->position()+d->displayMarginEnd : d->position()+d->size()+d->displayMarginEnd;
for (int i = 0; i < d->visibleItems.count(); ++i) {
FxViewItem *item = static_cast<FxListItemSG*>(d->visibleItems.at(i));
- QQuickItemPrivate::get(item->item)->setCulled(item->endPosition() < from || item->position() > to);
+ if (item->item)
+ QQuickItemPrivate::get(item->item)->setCulled(item->endPosition() < from || item->position() > to);
}
if (d->currentItem)
QQuickItemPrivate::get(d->currentItem->item)->setCulled(d->currentItem->endPosition() < from || d->currentItem->position() > to);
diff --git a/src/quick/items/qquicklistview_p.h b/src/quick/items/qquicklistview_p.h
index bcb4e18751..7f64e12bba 100644
--- a/src/quick/items/qquicklistview_p.h
+++ b/src/quick/items/qquicklistview_p.h
@@ -47,8 +47,6 @@ class Q_AUTOTEST_EXPORT QQuickViewSection : public QObject
Q_PROPERTY(SectionCriteria criteria READ criteria WRITE setCriteria NOTIFY criteriaChanged)
Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
Q_PROPERTY(int labelPositioning READ labelPositioning WRITE setLabelPositioning NOTIFY labelPositioningChanged)
- Q_ENUMS(SectionCriteria)
- Q_ENUMS(LabelPositioning)
public:
QQuickViewSection(QQuickListView *parent=0);
@@ -56,6 +54,7 @@ public:
void setProperty(const QString &);
enum SectionCriteria { FullString, FirstCharacter };
+ Q_ENUM(SectionCriteria)
SectionCriteria criteria() const { return m_criteria; }
void setCriteria(SectionCriteria);
@@ -65,6 +64,7 @@ public:
QString sectionString(const QString &value);
enum LabelPositioning { InlineLabels = 0x01, CurrentLabelAtStart = 0x02, NextLabelAtEnd = 0x04 };
+ Q_ENUM(LabelPositioning)
int labelPositioning() { return m_labelPositioning; }
void setLabelPositioning(int pos);
@@ -106,10 +106,6 @@ class Q_AUTOTEST_EXPORT QQuickListView : public QQuickItemView
Q_PROPERTY(HeaderPositioning headerPositioning READ headerPositioning WRITE setHeaderPositioning NOTIFY headerPositioningChanged REVISION 2)
Q_PROPERTY(FooterPositioning footerPositioning READ footerPositioning WRITE setFooterPositioning NOTIFY footerPositioningChanged REVISION 2)
- Q_ENUMS(Orientation)
- Q_ENUMS(SnapMode)
- Q_ENUMS(HeaderPositioning)
- Q_ENUMS(FooterPositioning)
Q_CLASSINFO("DefaultProperty", "data")
public:
@@ -120,6 +116,7 @@ public:
void setSpacing(qreal spacing);
enum Orientation { Horizontal = Qt::Horizontal, Vertical = Qt::Vertical };
+ Q_ENUM(Orientation)
Orientation orientation() const;
void setOrientation(Orientation);
@@ -140,14 +137,17 @@ public:
void setHighlightMoveDuration(int) Q_DECL_OVERRIDE;
enum SnapMode { NoSnap, SnapToItem, SnapOneItem };
+ Q_ENUM(SnapMode)
SnapMode snapMode() const;
void setSnapMode(SnapMode mode);
enum HeaderPositioning { InlineHeader, OverlayHeader, PullBackHeader };
+ Q_ENUM(HeaderPositioning)
HeaderPositioning headerPositioning() const;
void setHeaderPositioning(HeaderPositioning positioning);
enum FooterPositioning { InlineFooter, OverlayFooter, PullBackFooter };
+ Q_ENUM(FooterPositioning)
FooterPositioning footerPositioning() const;
void setFooterPositioning(FooterPositioning positioning);
diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp
index dd04568db2..d46e25d255 100644
--- a/src/quick/items/qquickloader.cpp
+++ b/src/quick/items/qquickloader.cpp
@@ -576,7 +576,6 @@ void QQuickLoader::setSource(QQmlV4Function *args)
if (!ipv->isUndefined()) {
d->disposeInitialPropertyValues();
d->initialPropertyValues.set(args->v4engine(), ipv);
- d->qmlGlobalForIpv.set(args->v4engine(), args->qmlGlobal());
}
setSource(sourceUrl, false); // already cleared and set ipv above.
@@ -642,11 +641,11 @@ void QQuickLoaderPrivate::setInitialState(QObject *obj)
QQmlComponentPrivate *d = QQmlComponentPrivate::get(component);
Q_ASSERT(d && d->engine);
- QV4::ExecutionEngine *v4 = qmlGlobalForIpv.engine();
+ QV4::ExecutionEngine *v4 = QV8Engine::getV4(d->engine);
Q_ASSERT(v4);
QV4::Scope scope(v4);
QV4::ScopedValue ipv(scope, initialPropertyValues.value());
- d->initializeObjectWithInitialProperties(*qmlGlobalForIpv.valueRef(), ipv, obj);
+ d->initializeObjectWithInitialProperties(ipv, obj);
}
void QQuickLoaderIncubator::statusChanged(Status status)
@@ -943,7 +942,7 @@ QV4::ReturnedValue QQuickLoaderPrivate::extractInitialPropertyValues(QQmlV4Funct
QV4::ScopedValue valuemap(scope, QV4::Primitive::undefinedValue());
if (args->length() >= 2) {
QV4::ScopedValue v(scope, (*args)[1]);
- if (!v->isObject() || v->asArrayObject()) {
+ if (!v->isObject() || v->as<QV4::ArrayObject>()) {
*error = true;
qmlInfo(loader) << QQuickLoader::tr("setSource: value is not an object");
} else {
diff --git a/src/quick/items/qquickloader_p.h b/src/quick/items/qquickloader_p.h
index 2c0e98de59..6ed4f2437b 100644
--- a/src/quick/items/qquickloader_p.h
+++ b/src/quick/items/qquickloader_p.h
@@ -42,7 +42,6 @@ class QQuickLoaderPrivate;
class Q_AUTOTEST_EXPORT QQuickLoader : public QQuickImplicitSizeItem
{
Q_OBJECT
- Q_ENUMS(Status)
Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
@@ -69,6 +68,7 @@ public:
void resetSourceComponent();
enum Status { Null, Ready, Loading, Error };
+ Q_ENUM(Status)
Status status() const;
qreal progress() const;
diff --git a/src/quick/items/qquickloader_p_p.h b/src/quick/items/qquickloader_p_p.h
index 621419d1a7..9677318b58 100644
--- a/src/quick/items/qquickloader_p_p.h
+++ b/src/quick/items/qquickloader_p_p.h
@@ -50,7 +50,7 @@
#include "qquickitemchangelistener_p.h"
#include <qqmlincubator.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
QT_BEGIN_NAMESPACE
@@ -102,7 +102,6 @@ public:
QQmlContext *itemContext;
QQuickLoaderIncubator *incubator;
QV4::PersistentValue initialPropertyValues;
- QV4::PersistentValue qmlGlobalForIpv;
bool updatingSize: 1;
bool active : 1;
bool loadingFromSource : 1;
diff --git a/src/quick/items/qquickopenglinfo_p.h b/src/quick/items/qquickopenglinfo_p.h
index 2a2e2a719b..511413c814 100644
--- a/src/quick/items/qquickopenglinfo_p.h
+++ b/src/quick/items/qquickopenglinfo_p.h
@@ -63,7 +63,6 @@ class QQuickOpenGLInfo : public QObject
Q_PROPERTY(int minorVersion READ minorVersion NOTIFY minorVersionChanged FINAL)
Q_PROPERTY(ContextProfile profile READ profile NOTIFY profileChanged FINAL)
Q_PROPERTY(RenderableType renderableType READ renderableType NOTIFY renderableTypeChanged FINAL)
- Q_ENUMS(ContextProfile RenderableType)
public:
QQuickOpenGLInfo(QQuickItem *item = 0);
@@ -77,6 +76,7 @@ public:
CoreProfile = QSurfaceFormat::CoreProfile,
CompatibilityProfile = QSurfaceFormat::CompatibilityProfile
};
+ Q_ENUM(ContextProfile)
ContextProfile profile() const;
// keep in sync with QSurfaceFormat::RenderableType
@@ -85,6 +85,7 @@ public:
OpenGL = QSurfaceFormat::OpenGL,
OpenGLES = QSurfaceFormat::OpenGLES
};
+ Q_ENUM(RenderableType)
RenderableType renderableType() const;
static QQuickOpenGLInfo *qmlAttachedProperties(QObject *object);
diff --git a/src/quick/items/qquickpainteditem.h b/src/quick/items/qquickpainteditem.h
index 356e4a46f6..28eb3398a0 100644
--- a/src/quick/items/qquickpainteditem.h
+++ b/src/quick/items/qquickpainteditem.h
@@ -43,7 +43,6 @@ class QQuickPaintedItemPrivate;
class Q_QUICK_EXPORT QQuickPaintedItem : public QQuickItem
{
Q_OBJECT
- Q_ENUMS(RenderTarget)
Q_PROPERTY(QSize contentsSize READ contentsSize WRITE setContentsSize NOTIFY contentsSizeChanged)
Q_PROPERTY(QColor fillColor READ fillColor WRITE setFillColor NOTIFY fillColorChanged)
@@ -58,6 +57,7 @@ public:
FramebufferObject,
InvertedYFramebufferObject
};
+ Q_ENUM(RenderTarget)
enum PerformanceHint {
FastFBOResizing = 0x1
diff --git a/src/quick/items/qquickpainteditem_p.h b/src/quick/items/qquickpainteditem_p.h
index 3712e964f8..2759d9d683 100644
--- a/src/quick/items/qquickpainteditem_p.h
+++ b/src/quick/items/qquickpainteditem_p.h
@@ -42,7 +42,7 @@ QT_BEGIN_NAMESPACE
class QQuickPaintedItemTextureProvider;
class QSGPainterNode;
-class QQuickPaintedItemPrivate : public QQuickItemPrivate
+class Q_QUICK_PRIVATE_EXPORT QQuickPaintedItemPrivate : public QQuickItemPrivate
{
public:
QQuickPaintedItemPrivate();
diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp
index 58605f79dd..302532c3d1 100644
--- a/src/quick/items/qquickpathview.cpp
+++ b/src/quick/items/qquickpathview.cpp
@@ -98,7 +98,7 @@ QQuickPathViewPrivate::QQuickPathViewPrivate()
, inRefill(false)
, dragMargin(0), deceleration(100), maximumFlickVelocity(QML_FLICK_DEFAULTMAXVELOCITY)
, moveOffset(this, &QQuickPathViewPrivate::setAdjustedOffset), flickDuration(0)
- , firstIndex(-1), pathItems(-1), requestedIndex(-1), cacheSize(0), requestedZ(0)
+ , pathItems(-1), requestedIndex(-1), cacheSize(0), requestedZ(0)
, moveReason(Other), moveDirection(Shortest), attType(0), highlightComponent(0), highlightItem(0)
, moveHighlight(this, &QQuickPathViewPrivate::setHighlightPosition)
, highlightPosition(0)
@@ -447,7 +447,6 @@ void QQuickPathViewPrivate::regenerate()
if (!isValid())
return;
- firstIndex = -1;
updateMappedRange();
q->refill();
}
@@ -1473,7 +1472,7 @@ int QQuickPathView::indexAt(qreal x, qreal y) const
QQuickItem *item = d->items.at(idx);
QPointF p = item->mapFromItem(this, QPointF(x, y));
if (item->contains(p))
- return (d->firstIndex + idx) % d->modelCount;
+ return d->model->indexOf(item, 0);
}
return -1;
@@ -1896,12 +1895,12 @@ void QQuickPathView::refill()
int count = d->pathItems == -1 ? d->modelCount : qMin(d->pathItems, d->modelCount);
// first move existing items and remove items off path
- int idx = d->firstIndex;
- qCDebug(lcItemViewDelegateLifecycle) << "firstIndex" << idx << "currentIndex" << d->currentIndex << "offset" << d->offset;
+ qCDebug(lcItemViewDelegateLifecycle) << "currentIndex" << d->currentIndex << "offset" << d->offset;
QList<QQuickItem*>::iterator it = d->items.begin();
while (it != d->items.end()) {
- qreal pos = d->positionOfIndex(idx);
QQuickItem *item = *it;
+ int idx = d->model->indexOf(item, 0);
+ qreal pos = d->positionOfIndex(idx);
if (lcItemViewDelegateLifecycle().isDebugEnabled()) {
QQuickText *text = qmlobject_cast<QQuickText*>(item);
if (text)
@@ -1923,81 +1922,140 @@ void QQuickPathView::refill()
if (!d->isInBound(pos, d->mappedRange - d->mappedCache, 1.0 + d->mappedCache)) {
qCDebug(lcItemViewDelegateLifecycle) << "release" << idx << "@" << pos << ", !isInBound: lower" << (d->mappedRange - d->mappedCache) << "upper" << (1.0 + d->mappedCache);
d->releaseItem(item);
- if (it == d->items.begin()) {
- if (++d->firstIndex >= d->modelCount) {
- d->firstIndex = 0;
- }
- }
it = d->items.erase(it);
} else {
++it;
}
}
- ++idx;
- if (idx >= d->modelCount)
- idx = 0;
}
- if (!d->items.count())
- d->firstIndex = -1;
-
bool waiting = false;
if (d->modelCount) {
- // add items to beginning and end
+ // add items as needed
if (d->items.count() < count+d->cacheSize) {
- int idx = qRound(d->modelCount - d->offset) % d->modelCount;
+ int endIdx = 0;
+ qreal endPos;
+ int startIdx = 0;
qreal startPos = 0.0;
- if (d->haveHighlightRange && (d->highlightRangeMode != QQuickPathView::NoHighlightRange
- || d->snapMode != QQuickPathView::NoSnap))
- startPos = d->highlightRangeStart;
- if (d->firstIndex >= 0) {
- startPos = d->positionOfIndex(d->firstIndex);
- idx = (d->firstIndex + d->items.count()) % d->modelCount;
+ if (d->items.count()) {
+ //Find the beginning and end, items may not be in sorted order
+ endPos = -1.0;
+ startPos = 2.0;
+
+ for (int i = 0; i < d->items.count(); i++) {
+ int idx = d->model->indexOf(d->items[i], 0);
+ qreal curPos = d->positionOfIndex(idx);
+ if (curPos > endPos) {
+ endPos = curPos;
+ endIdx = idx;
+ }
+
+ if (curPos < startPos) {
+ startPos = curPos;
+ startIdx = idx;
+ }
+ }
+ } else {
+ if (d->haveHighlightRange
+ && (d->highlightRangeMode != QQuickPathView::NoHighlightRange
+ || d->snapMode != QQuickPathView::NoSnap))
+ startPos = d->highlightRangeStart;
+ // With no items, then "end" is just off the top so we populate via append
+ endIdx = (qRound(d->modelCount - d->offset) - 1) % d->modelCount;
+ endPos = d->positionOfIndex(endIdx);
}
- qreal pos = d->positionOfIndex(idx);
- while ((d->isInBound(pos, startPos, 1.0 + d->mappedCache) || !d->items.count()) && d->items.count() < count+d->cacheSize) {
- qCDebug(lcItemViewDelegateLifecycle) << "append" << idx << "@" << pos << (d->currentIndex == idx ? "current" : "") << "items count was" << d->items.count();
- QQuickItem *item = d->getItem(idx, idx+1, pos >= 1.0);
+ //Append
+ int idx = endIdx + 1;
+ if (idx >= d->modelCount)
+ idx = 0;
+ qreal nextPos = d->positionOfIndex(idx);
+ while ((d->isInBound(nextPos, endPos, 1.0 + d->mappedCache) || !d->items.count())
+ && d->items.count() < count+d->cacheSize) {
+ qCDebug(lcItemViewDelegateLifecycle) << "append" << idx << "@" << nextPos << (d->currentIndex == idx ? "current" : "") << "items count was" << d->items.count();
+ QQuickItem *item = d->getItem(idx, idx+1, nextPos >= 1.0);
if (!item) {
waiting = true;
break;
}
+ if (d->items.contains(item)) {
+ break; //Otherwise we'd "re-add" it, and get confused
+ }
if (d->currentIndex == idx) {
currentVisible = true;
- d->currentItemOffset = pos;
+ d->currentItemOffset = nextPos;
}
- if (d->items.count() == 0)
- d->firstIndex = idx;
d->items.append(item);
- d->updateItem(item, pos);
+ d->updateItem(item, nextPos);
+ endIdx = idx;
+ endPos = nextPos;
++idx;
if (idx >= d->modelCount)
idx = 0;
- pos = d->positionOfIndex(idx);
+ nextPos = d->positionOfIndex(idx);
}
- idx = d->firstIndex - 1;
+ //Prepend
+ idx = startIdx - 1;
if (idx < 0)
idx = d->modelCount - 1;
- pos = d->positionOfIndex(idx);
- while (!waiting && d->isInBound(pos, d->mappedRange - d->mappedCache, startPos) && d->items.count() < count+d->cacheSize) {
- qCDebug(lcItemViewDelegateLifecycle) << "prepend" << idx << "@" << pos << (d->currentIndex == idx ? "current" : "") << "items count was" << d->items.count();
- QQuickItem *item = d->getItem(idx, idx+1, pos >= 1.0);
+ nextPos = d->positionOfIndex(idx);
+ while (!waiting && d->isInBound(nextPos, d->mappedRange - d->mappedCache, startPos)
+ && d->items.count() < count+d->cacheSize) {
+ qCDebug(lcItemViewDelegateLifecycle) << "prepend" << idx << "@" << nextPos << (d->currentIndex == idx ? "current" : "") << "items count was" << d->items.count();
+ QQuickItem *item = d->getItem(idx, idx+1, nextPos >= 1.0);
if (!item) {
waiting = true;
break;
}
+ if (d->items.contains(item)) {
+ break; //Otherwise we'd "re-add" it, and get confused
+ }
if (d->currentIndex == idx) {
currentVisible = true;
- d->currentItemOffset = pos;
+ d->currentItemOffset = nextPos;
}
d->items.prepend(item);
- d->updateItem(item, pos);
- d->firstIndex = idx;
- idx = d->firstIndex - 1;
+ d->updateItem(item, nextPos);
+ startIdx = idx;
+ startPos = nextPos;
+ --idx;
if (idx < 0)
idx = d->modelCount - 1;
- pos = d->positionOfIndex(idx);
+ nextPos = d->positionOfIndex(idx);
+ }
+
+ // In rare cases, when jumping around with pathCount close to modelCount,
+ // new items appear in the middle. This more generic addition iteration handles this
+ // Since this is the rare case, we try append/prepend first and only do this if
+ // there are gaps still left to fill.
+ if (!waiting && d->items.count() < count+d->cacheSize) {
+ qCDebug(lcItemViewDelegateLifecycle) << "Checking for pathview middle inserts, items count was" << d->items.count();
+ idx = startIdx;
+ QQuickItem *lastItem = d->items[0];
+ while (idx != endIdx) {
+ //This gets the reference from the delegate model, and will not re-create
+ QQuickItem *item = d->getItem(idx, idx+1, nextPos >= 1.0);
+ if (!item) {
+ waiting = true;
+ break;
+ }
+ if (!d->items.contains(item)) { //We found a hole
+ nextPos = d->positionOfIndex(idx);
+ qCDebug(lcItemViewDelegateLifecycle) << "middle insert" << idx << "@" << nextPos << (d->currentIndex == idx ? "current" : "") << "items count was" << d->items.count();
+ if (d->currentIndex == idx) {
+ currentVisible = true;
+ d->currentItemOffset = nextPos;
+ }
+ int lastListIdx = d->items.indexOf(lastItem);
+ d->items.insert(lastListIdx + 1, item);
+ d->updateItem(item, nextPos);
+ }
+
+ lastItem = item;
+ ++idx;
+ if (idx >= d->modelCount)
+ idx = 0;
+ }
}
}
}
@@ -2128,7 +2186,6 @@ void QQuickPathView::modelUpdated(const QQmlChangeSet &changeSet, bool reset)
d->offset = qmlMod(d->modelCount - d->currentIndex, d->modelCount);
changedOffset = true;
}
- d->firstIndex = -1;
d->updateMappedRange();
d->scheduleLayout();
}
@@ -2185,8 +2242,16 @@ void QQuickPathViewPrivate::createCurrentItem()
{
if (requestedIndex != -1)
return;
- int itemIndex = (currentIndex - firstIndex + modelCount) % modelCount;
- if (itemIndex < items.count()) {
+
+ bool inItems = false;
+ for (int i = 0; i < items.count(); i++) {
+ if (model->indexOf(items[i], 0) == currentIndex) {
+ inItems = true;
+ break;
+ }
+ }
+
+ if (inItems) {
if ((currentItem = getItem(currentIndex, currentIndex))) {
currentItem->setFocus(true);
if (QQuickPathViewAttached *att = attached(currentItem))
diff --git a/src/quick/items/qquickpathview_p.h b/src/quick/items/qquickpathview_p.h
index 8062e07795..0f2e4a956c 100644
--- a/src/quick/items/qquickpathview_p.h
+++ b/src/quick/items/qquickpathview_p.h
@@ -78,10 +78,6 @@ class Q_AUTOTEST_EXPORT QQuickPathView : public QQuickItem
Q_PROPERTY(int cacheItemCount READ cacheItemCount WRITE setCacheItemCount NOTIFY cacheItemCountChanged)
- Q_ENUMS(HighlightRangeMode)
- Q_ENUMS(SnapMode)
- Q_ENUMS(PositionMode)
-
public:
QQuickPathView(QQuickItem *parent=0);
virtual ~QQuickPathView();
@@ -105,6 +101,7 @@ public:
QQuickItem *highlightItem();
enum HighlightRangeMode { NoHighlightRange, ApplyRange, StrictlyEnforceRange };
+ Q_ENUM(HighlightRangeMode)
HighlightRangeMode highlightRangeMode() const;
void setHighlightRangeMode(HighlightRangeMode mode);
@@ -146,10 +143,12 @@ public:
void setCacheItemCount(int);
enum SnapMode { NoSnap, SnapToItem, SnapOneItem };
+ Q_ENUM(SnapMode)
SnapMode snapMode() const;
void setSnapMode(SnapMode mode);
enum PositionMode { Beginning, Center, End, Contain=4, SnapPosition }; // 3 == Visible in other views
+ Q_ENUM(PositionMode)
Q_INVOKABLE void positionViewAtIndex(int index, int mode);
Q_INVOKABLE int indexAt(qreal x, qreal y) const;
Q_INVOKABLE QQuickItem *itemAt(qreal x, qreal y) const;
diff --git a/src/quick/items/qquickpathview_p_p.h b/src/quick/items/qquickpathview_p_p.h
index 35ea8616a5..2a497881d4 100644
--- a/src/quick/items/qquickpathview_p_p.h
+++ b/src/quick/items/qquickpathview_p_p.h
@@ -155,7 +155,6 @@ public:
QQuickTimeLine tl;
QQuickTimeLineValueProxy<QQuickPathViewPrivate> moveOffset;
int flickDuration;
- int firstIndex;
int pathItems;
int requestedIndex;
int cacheSize;
diff --git a/src/quick/items/qquickpincharea_p.h b/src/quick/items/qquickpincharea_p.h
index d2de59b5d6..602b2804cc 100644
--- a/src/quick/items/qquickpincharea_p.h
+++ b/src/quick/items/qquickpincharea_p.h
@@ -42,7 +42,6 @@ class Q_AUTOTEST_EXPORT QQuickPinch : public QObject
{
Q_OBJECT
- Q_ENUMS(Axis)
Q_PROPERTY(QQuickItem *target READ target WRITE setTarget RESET resetTarget)
Q_PROPERTY(qreal minimumScale READ minimumScale WRITE setMinimumScale NOTIFY minimumScaleChanged)
Q_PROPERTY(qreal maximumScale READ maximumScale WRITE setMaximumScale NOTIFY maximumScaleChanged)
@@ -103,6 +102,7 @@ public:
}
enum Axis { NoDrag=0x00, XAxis=0x01, YAxis=0x02, XAndYAxis=0x03, XandYAxis=XAndYAxis };
+ Q_ENUM(Axis)
Axis axis() const { return m_axis; }
void setAxis(Axis a) {
if (a == m_axis)
diff --git a/src/quick/items/qquickpositioners.cpp b/src/quick/items/qquickpositioners.cpp
index 887d317069..de2596b679 100644
--- a/src/quick/items/qquickpositioners.cpp
+++ b/src/quick/items/qquickpositioners.cpp
@@ -70,6 +70,10 @@ QQuickBasePositioner::PositionedItem::PositionedItem(QQuickItem *i)
, index(-1)
, isNew(false)
, isVisible(true)
+ , topPadding(0)
+ , leftPadding(0)
+ , rightPadding(0)
+ , bottomPadding(0)
{
}
@@ -116,6 +120,13 @@ void QQuickBasePositioner::PositionedItem::startTransition(QQuickItemViewTransit
transitionableItem->startTransition(transitioner, index);
}
+void QQuickBasePositioner::PositionedItem::updatePadding(qreal lp, qreal tp, qreal rp, qreal bp)
+{
+ leftPadding = lp;
+ topPadding = tp;
+ rightPadding = rp;
+ bottomPadding = bp;
+}
QQuickBasePositioner::QQuickBasePositioner(PositionerType at, QQuickItem *parent)
: QQuickImplicitSizeItem(*(new QQuickBasePositionerPrivate), parent)
@@ -388,11 +399,8 @@ void QQuickBasePositioner::prePositioning()
void QQuickBasePositioner::positionItem(qreal x, qreal y, PositionedItem *target)
{
- Q_D(QQuickBasePositioner);
- if ( (target->itemX() != x || target->itemY() != y)
- && d->type == Both) {
+ if ( target->itemX() != x || target->itemY() != y )
target->moveTo(QPointF(x, y));
- }
}
void QQuickBasePositioner::positionItemX(qreal x, PositionedItem *target)
@@ -503,6 +511,185 @@ void QQuickBasePositioner::updateAttachedProperties(QQuickPositionerAttached *sp
}
}
+qreal QQuickBasePositioner::padding() const
+{
+ Q_D(const QQuickBasePositioner);
+ return d->padding();
+}
+
+void QQuickBasePositioner::setPadding(qreal padding)
+{
+ Q_D(QQuickBasePositioner);
+ if (qFuzzyCompare(d->padding(), padding))
+ return;
+
+ d->extra.value().padding = padding;
+ d->setPositioningDirty();
+ emit paddingChanged();
+ if (!d->extra.isAllocated() || !d->extra->explicitTopPadding)
+ emit topPaddingChanged();
+ if (!d->extra.isAllocated() || !d->extra->explicitLeftPadding)
+ emit leftPaddingChanged();
+ if (!d->extra.isAllocated() || !d->extra->explicitRightPadding)
+ emit rightPaddingChanged();
+ if (!d->extra.isAllocated() || !d->extra->explicitBottomPadding)
+ emit bottomPaddingChanged();
+}
+
+void QQuickBasePositioner::resetPadding()
+{
+ setPadding(0);
+}
+
+qreal QQuickBasePositioner::topPadding() const
+{
+ Q_D(const QQuickBasePositioner);
+ if (d->extra.isAllocated() && d->extra->explicitTopPadding)
+ return d->extra->topPadding;
+ return d->padding();
+}
+
+void QQuickBasePositioner::setTopPadding(qreal padding)
+{
+ Q_D(QQuickBasePositioner);
+ d->setTopPadding(padding);
+}
+
+void QQuickBasePositioner::resetTopPadding()
+{
+ Q_D(QQuickBasePositioner);
+ d->setTopPadding(0, true);
+}
+
+qreal QQuickBasePositioner::leftPadding() const
+{
+ Q_D(const QQuickBasePositioner);
+ if (d->extra.isAllocated() && d->extra->explicitLeftPadding)
+ return d->extra->leftPadding;
+ return d->padding();
+}
+
+void QQuickBasePositioner::setLeftPadding(qreal padding)
+{
+ Q_D(QQuickBasePositioner);
+ d->setLeftPadding(padding);
+}
+
+void QQuickBasePositioner::resetLeftPadding()
+{
+ Q_D(QQuickBasePositioner);
+ d->setLeftPadding(0, true);
+}
+
+qreal QQuickBasePositioner::rightPadding() const
+{
+ Q_D(const QQuickBasePositioner);
+ if (d->extra.isAllocated() && d->extra->explicitRightPadding)
+ return d->extra->rightPadding;
+ return d->padding();
+}
+
+void QQuickBasePositioner::setRightPadding(qreal padding)
+{
+ Q_D(QQuickBasePositioner);
+ d->setRightPadding(padding);
+}
+
+void QQuickBasePositioner::resetRightPadding()
+{
+ Q_D(QQuickBasePositioner);
+ d->setRightPadding(0, true);
+}
+
+qreal QQuickBasePositioner::bottomPadding() const
+{
+ Q_D(const QQuickBasePositioner);
+ if (d->extra.isAllocated() && d->extra->explicitBottomPadding)
+ return d->extra->bottomPadding;
+ return d->padding();
+}
+
+void QQuickBasePositioner::setBottomPadding(qreal padding)
+{
+ Q_D(QQuickBasePositioner);
+ d->setBottomPadding(padding);
+}
+
+void QQuickBasePositioner::resetBottomPadding()
+{
+ Q_D(QQuickBasePositioner);
+ d->setBottomPadding(0, true);
+}
+
+QQuickBasePositionerPrivate::ExtraData::ExtraData()
+ : padding(0)
+ , topPadding(0)
+ , leftPadding(0)
+ , rightPadding(0)
+ , bottomPadding(0)
+ , explicitTopPadding(false)
+ , explicitLeftPadding(false)
+ , explicitRightPadding(false)
+ , explicitBottomPadding(false)
+{
+}
+
+void QQuickBasePositionerPrivate::setTopPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickBasePositioner);
+ qreal oldPadding = q->topPadding();
+ if (!reset || extra.isAllocated()) {
+ extra.value().topPadding = value;
+ extra.value().explicitTopPadding = !reset;
+ }
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding()))) {
+ setPositioningDirty();
+ emit q->topPaddingChanged();
+ }
+}
+
+void QQuickBasePositionerPrivate::setLeftPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickBasePositioner);
+ qreal oldPadding = q->leftPadding();
+ if (!reset || extra.isAllocated()) {
+ extra.value().leftPadding = value;
+ extra.value().explicitLeftPadding = !reset;
+ }
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding()))) {
+ setPositioningDirty();
+ emit q->leftPaddingChanged();
+ }
+}
+
+void QQuickBasePositionerPrivate::setRightPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickBasePositioner);
+ qreal oldPadding = q->rightPadding();
+ if (!reset || extra.isAllocated()) {
+ extra.value().rightPadding = value;
+ extra.value().explicitRightPadding = !reset;
+ }
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding()))) {
+ setPositioningDirty();
+ emit q->rightPaddingChanged();
+ }
+}
+
+void QQuickBasePositionerPrivate::setBottomPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickBasePositioner);
+ qreal oldPadding = q->bottomPadding();
+ if (!reset || extra.isAllocated()) {
+ extra.value().bottomPadding = value;
+ extra.value().explicitBottomPadding = !reset;
+ }
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding()))) {
+ setPositioningDirty();
+ emit q->bottomPaddingChanged();
+ }
+}
+
/*!
\qmltype Positioner
\instantiates QQuickPositionerAttached
@@ -640,6 +827,16 @@ void QQuickPositionerAttached::setIsLastItem(bool isLastItem)
\sa Row, Grid, Flow, Positioner, ColumnLayout, {Qt Quick Examples - Positioners}
*/
/*!
+ \since 5.6
+ \qmlproperty real QtQuick::Column::padding
+ \qmlproperty real QtQuick::Column::topPadding
+ \qmlproperty real QtQuick::Column::leftPadding
+ \qmlproperty real QtQuick::Column::bottomPadding
+ \qmlproperty real QtQuick::Column::rightPadding
+
+ These properties hold the padding around the content.
+*/
+/*!
\qmlproperty Transition QtQuick::Column::populate
This property holds the transition to be run for items that are part of
@@ -715,20 +912,23 @@ QQuickColumn::QQuickColumn(QQuickItem *parent)
void QQuickColumn::doPositioning(QSizeF *contentSize)
{
//Precondition: All items in the positioned list have a valid item pointer and should be positioned
- qreal voffset = 0;
+ qreal voffset = topPadding();
+ const qreal padding = leftPadding() + rightPadding();
+ contentSize->setWidth(qMax(contentSize->width(), padding));
for (int ii = 0; ii < positionedItems.count(); ++ii) {
PositionedItem &child = positionedItems[ii];
- positionItemY(voffset, &child);
- contentSize->setWidth(qMax(contentSize->width(), child.item->width()));
+ positionItem(child.itemX() + leftPadding() - child.leftPadding, voffset, &child);
+ child.updatePadding(leftPadding(), topPadding(), rightPadding(), bottomPadding());
+ contentSize->setWidth(qMax(contentSize->width(), child.item->width() + padding));
voffset += child.item->height();
voffset += spacing();
}
- if (voffset != 0)//If we positioned any items, undo the spacing from the last item
+ if (voffset - topPadding() != 0)//If we positioned any items, undo the spacing from the last item
voffset -= spacing();
- contentSize->setHeight(voffset);
+ contentSize->setHeight(voffset + bottomPadding());
}
void QQuickColumn::reportConflictingAnchors()
@@ -794,6 +994,16 @@ void QQuickColumn::reportConflictingAnchors()
\sa Column, Grid, Flow, Positioner, RowLayout, {Qt Quick Examples - Positioners}
*/
/*!
+ \since 5.6
+ \qmlproperty real QtQuick::Row::padding
+ \qmlproperty real QtQuick::Row::topPadding
+ \qmlproperty real QtQuick::Row::leftPadding
+ \qmlproperty real QtQuick::Row::bottomPadding
+ \qmlproperty real QtQuick::Row::rightPadding
+
+ These properties hold the padding around the content.
+*/
+/*!
\qmlproperty Transition QtQuick::Row::populate
This property holds the transition to be run for items that are part of
@@ -940,27 +1150,34 @@ void QQuickRow::doPositioning(QSizeF *contentSize)
{
//Precondition: All items in the positioned list have a valid item pointer and should be positioned
QQuickBasePositionerPrivate *d = static_cast<QQuickBasePositionerPrivate* >(QQuickBasePositionerPrivate::get(this));
- qreal hoffset = 0;
+ qreal hoffset1 = leftPadding();
+ qreal hoffset2 = rightPadding();
+ if (!d->isLeftToRight())
+ qSwap(hoffset1, hoffset2);
+ qreal hoffset = hoffset1;
+ const qreal padding = topPadding() + bottomPadding();
+ contentSize->setHeight(qMax(contentSize->height(), padding));
QList<qreal> hoffsets;
for (int ii = 0; ii < positionedItems.count(); ++ii) {
PositionedItem &child = positionedItems[ii];
if (d->isLeftToRight()) {
- positionItemX(hoffset, &child);
+ positionItem(hoffset, child.itemY() + topPadding() - child.topPadding, &child);
+ child.updatePadding(leftPadding(), topPadding(), rightPadding(), bottomPadding());
} else {
hoffsets << hoffset;
}
- contentSize->setHeight(qMax(contentSize->height(), child.item->height()));
+ contentSize->setHeight(qMax(contentSize->height(), child.item->height() + padding));
hoffset += child.item->width();
hoffset += spacing();
}
- if (hoffset != 0)//If we positioned any items, undo the extra spacing from the last item
+ if (hoffset - hoffset1 != 0)//If we positioned any items, undo the extra spacing from the last item
hoffset -= spacing();
- contentSize->setWidth(hoffset);
+ contentSize->setWidth(hoffset + hoffset2);
if (d->isLeftToRight())
return;
@@ -976,7 +1193,8 @@ void QQuickRow::doPositioning(QSizeF *contentSize)
for (int ii = 0; ii < positionedItems.count(); ++ii) {
PositionedItem &child = positionedItems[ii];
hoffset = end - hoffsets[acc++] - child.item->width();
- positionItemX(hoffset, &child);
+ positionItem(hoffset, child.itemY() + topPadding() - child.topPadding, &child);
+ child.updatePadding(leftPadding(), topPadding(), rightPadding(), bottomPadding());
}
}
@@ -1044,6 +1262,16 @@ void QQuickRow::reportConflictingAnchors()
\sa Flow, Row, Column, Positioner, GridLayout, {Qt Quick Examples - Positioners}
*/
/*!
+ \since 5.6
+ \qmlproperty real QtQuick::Grid::padding
+ \qmlproperty real QtQuick::Grid::topPadding
+ \qmlproperty real QtQuick::Grid::leftPadding
+ \qmlproperty real QtQuick::Grid::bottomPadding
+ \qmlproperty real QtQuick::Grid::rightPadding
+
+ These properties hold the padding around the content.
+*/
+/*!
\qmlproperty Transition QtQuick::Grid::populate
This property holds the transition to be run for items that are part of
@@ -1423,8 +1651,11 @@ void QQuickGrid::doPositioning(QSizeF *contentSize)
c = (numVisible+(m_rows-1))/m_rows;
}
- if (r == 0 || c == 0)
- return; //Nothing to do
+ if (r == 0 || c == 0) {
+ contentSize->setHeight(topPadding() + bottomPadding());
+ contentSize->setWidth(leftPadding() + rightPadding());
+ return; //Nothing else to do
+ }
QList<qreal> maxColWidth;
QList<qreal> maxRowHeight;
@@ -1476,6 +1707,7 @@ void QQuickGrid::doPositioning(QSizeF *contentSize)
widthSum += columnSpacing;
widthSum += maxColWidth[j];
}
+ widthSum += leftPadding() + rightPadding();
qreal heightSum = 0;
for (int i = 0; i < maxRowHeight.size(); i++) {
@@ -1483,6 +1715,7 @@ void QQuickGrid::doPositioning(QSizeF *contentSize)
heightSum += rowSpacing;
heightSum += maxRowHeight[i];
}
+ heightSum += topPadding() + bottomPadding();
contentSize->setHeight(heightSum);
contentSize->setWidth(widthSum);
@@ -1493,10 +1726,10 @@ void QQuickGrid::doPositioning(QSizeF *contentSize)
else
end = widthSum;
- qreal xoffset = 0;
+ qreal xoffset = leftPadding();
if (!d->isLeftToRight())
- xoffset = end;
- qreal yoffset = 0;
+ xoffset = end - rightPadding();
+ qreal yoffset = topPadding();
int curRow =0;
int curCol =0;
for (int i = 0; i < positionedItems.count(); ++i) {
@@ -1518,6 +1751,7 @@ void QQuickGrid::doPositioning(QSizeF *contentSize)
alignYOffset += maxRowHeight[curRow] - child.item->height();
positionItem(childXOffset, alignYOffset, &child);
+ child.updatePadding(leftPadding(), topPadding(), rightPadding(), bottomPadding());
if (m_flow == LeftToRight) {
if (d->isLeftToRight())
@@ -1529,9 +1763,9 @@ void QQuickGrid::doPositioning(QSizeF *contentSize)
if (!curCol) {
yoffset += maxRowHeight[curRow]+rowSpacing;
if (d->isLeftToRight())
- xoffset = 0;
+ xoffset = leftPadding();
else
- xoffset = end;
+ xoffset = end - rightPadding();
curRow++;
if (curRow>=r)
break;
@@ -1545,7 +1779,7 @@ void QQuickGrid::doPositioning(QSizeF *contentSize)
xoffset += maxColWidth[curCol]+columnSpacing;
else
xoffset -= maxColWidth[curCol]+columnSpacing;
- yoffset = 0;
+ yoffset = topPadding();
curCol++;
if (curCol>=c)
break;
@@ -1603,6 +1837,16 @@ void QQuickGrid::reportConflictingAnchors()
\sa Column, Row, Grid, Positioner, {Qt Quick Examples - Positioners}
*/
/*!
+ \since 5.6
+ \qmlproperty real QtQuick::Flow::padding
+ \qmlproperty real QtQuick::Flow::topPadding
+ \qmlproperty real QtQuick::Flow::leftPadding
+ \qmlproperty real QtQuick::Flow::bottomPadding
+ \qmlproperty real QtQuick::Flow::rightPadding
+
+ These properties hold the padding around the content.
+*/
+/*!
\qmlproperty Transition QtQuick::Flow::populate
This property holds the transition to be run for items that are part of
@@ -1786,23 +2030,30 @@ void QQuickFlow::doPositioning(QSizeF *contentSize)
//Precondition: All items in the positioned list have a valid item pointer and should be positioned
Q_D(QQuickFlow);
- qreal hoffset = 0;
- qreal voffset = 0;
+ qreal hoffset1 = leftPadding();
+ qreal hoffset2 = rightPadding();
+ if (!d->isLeftToRight())
+ qSwap(hoffset1, hoffset2);
+ qreal hoffset = hoffset1;
+ const qreal voffset1 = topPadding();
+ qreal voffset = voffset1;
qreal linemax = 0;
QList<qreal> hoffsets;
+ contentSize->setWidth(qMax(contentSize->width(), hoffset1 + hoffset2));
+ contentSize->setHeight(qMax(contentSize->height(), voffset + bottomPadding()));
for (int i = 0; i < positionedItems.count(); ++i) {
PositionedItem &child = positionedItems[i];
if (d->flow == LeftToRight) {
- if (widthValid() && hoffset && hoffset + child.item->width() > width()) {
- hoffset = 0;
+ if (widthValid() && hoffset != hoffset1 && hoffset + child.item->width() + hoffset2 > width()) {
+ hoffset = hoffset1;
voffset += linemax + spacing();
linemax = 0;
}
} else {
- if (heightValid() && voffset && voffset + child.item->height() > height()) {
- voffset = 0;
+ if (heightValid() && voffset != voffset1 && voffset + child.item->height() + bottomPadding() > height()) {
+ voffset = voffset1;
hoffset += linemax + spacing();
linemax = 0;
}
@@ -1810,13 +2061,16 @@ void QQuickFlow::doPositioning(QSizeF *contentSize)
if (d->isLeftToRight()) {
positionItem(hoffset, voffset, &child);
+ child.updatePadding(leftPadding(), topPadding(), rightPadding(), bottomPadding());
} else {
hoffsets << hoffset;
positionItemY(voffset, &child);
+ child.topPadding = topPadding();
+ child.bottomPadding = bottomPadding();
}
- contentSize->setWidth(qMax(contentSize->width(), hoffset + child.item->width()));
- contentSize->setHeight(qMax(contentSize->height(), voffset + child.item->height()));
+ contentSize->setWidth(qMax(contentSize->width(), hoffset + child.item->width() + hoffset2));
+ contentSize->setHeight(qMax(contentSize->height(), voffset + child.item->height() + bottomPadding()));
if (d->flow == LeftToRight) {
hoffset += child.item->width();
@@ -1828,6 +2082,7 @@ void QQuickFlow::doPositioning(QSizeF *contentSize)
linemax = qMax(linemax, child.item->width());
}
}
+
if (d->isLeftToRight())
return;
@@ -1841,6 +2096,8 @@ void QQuickFlow::doPositioning(QSizeF *contentSize)
PositionedItem &child = positionedItems[i];
hoffset = end - hoffsets[acc++] - child.item->width();
positionItemX(hoffset, &child);
+ child.leftPadding = leftPadding();
+ child.rightPadding = rightPadding();
}
}
diff --git a/src/quick/items/qquickpositioners_p.h b/src/quick/items/qquickpositioners_p.h
index ea779695eb..bc67701306 100644
--- a/src/quick/items/qquickpositioners_p.h
+++ b/src/quick/items/qquickpositioners_p.h
@@ -86,6 +86,12 @@ class Q_QUICK_PRIVATE_EXPORT QQuickBasePositioner : public QQuickImplicitSizeIte
Q_PROPERTY(QQuickTransition *populate READ populate WRITE setPopulate NOTIFY populateChanged)
Q_PROPERTY(QQuickTransition *move READ move WRITE setMove NOTIFY moveChanged)
Q_PROPERTY(QQuickTransition *add READ add WRITE setAdd NOTIFY addChanged)
+
+ Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION 6)
+ Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6)
public:
enum PositionerType { None = 0x0, Horizontal = 0x1, Vertical = 0x2, Both = 0x3 };
@@ -108,6 +114,26 @@ public:
void updateAttachedProperties(QQuickPositionerAttached *specificProperty = 0, QQuickItem *specificPropertyOwner = 0) const;
+ qreal padding() const;
+ void setPadding(qreal padding);
+ void resetPadding();
+
+ qreal topPadding() const;
+ void setTopPadding(qreal padding);
+ void resetTopPadding();
+
+ qreal leftPadding() const;
+ void setLeftPadding(qreal padding);
+ void resetLeftPadding();
+
+ qreal rightPadding() const;
+ void setRightPadding(qreal padding);
+ void resetRightPadding();
+
+ qreal bottomPadding() const;
+ void setBottomPadding(qreal padding);
+ void resetBottomPadding();
+
protected:
QQuickBasePositioner(QQuickBasePositionerPrivate &dd, PositionerType at, QQuickItem *parent);
void componentComplete() Q_DECL_OVERRIDE;
@@ -120,6 +146,11 @@ Q_SIGNALS:
void populateChanged();
void moveChanged();
void addChanged();
+ Q_REVISION(6) void paddingChanged();
+ Q_REVISION(6) void topPaddingChanged();
+ Q_REVISION(6) void leftPaddingChanged();
+ Q_REVISION(6) void rightPaddingChanged();
+ Q_REVISION(6) void bottomPaddingChanged();
protected Q_SLOTS:
void prePositioning();
@@ -144,11 +175,18 @@ protected:
bool prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds);
void startTransition(QQuickItemViewTransitioner *transitioner);
+ void updatePadding(qreal lp, qreal tp, qreal rp, qreal bp);
+
QQuickItem *item;
QQuickItemViewTransitionableItem *transitionableItem;
int index;
bool isNew;
bool isVisible;
+
+ qreal topPadding;
+ qreal leftPadding;
+ qreal rightPadding;
+ qreal bottomPadding;
};
QPODVector<PositionedItem,8> positionedItems;
@@ -236,8 +274,8 @@ public:
void setColumnSpacing(qreal);
void resetColumnSpacing() { m_useColumnSpacing = false; }
- Q_ENUMS(Flow)
enum Flow { LeftToRight, TopToBottom };
+ Q_ENUM(Flow)
Flow flow() const;
void setFlow(Flow);
@@ -245,14 +283,14 @@ public:
void setLayoutDirection (Qt::LayoutDirection);
Qt::LayoutDirection effectiveLayoutDirection() const;
- Q_ENUMS(HAlignment)
- Q_ENUMS(VAlignment)
enum HAlignment { AlignLeft = Qt::AlignLeft,
AlignRight = Qt::AlignRight,
AlignHCenter = Qt::AlignHCenter};
+ Q_ENUM(HAlignment)
enum VAlignment { AlignTop = Qt::AlignTop,
AlignBottom = Qt::AlignBottom,
AlignVCenter = Qt::AlignVCenter };
+ Q_ENUM(VAlignment)
HAlignment hItemAlign() const;
void setHItemAlign(HAlignment align);
@@ -301,8 +339,8 @@ class Q_AUTOTEST_EXPORT QQuickFlow: public QQuickBasePositioner
public:
QQuickFlow(QQuickItem *parent=0);
- Q_ENUMS(Flow)
enum Flow { LeftToRight, TopToBottom };
+ Q_ENUM(Flow)
Flow flow() const;
void setFlow(Flow);
diff --git a/src/quick/items/qquickpositioners_p_p.h b/src/quick/items/qquickpositioners_p_p.h
index 3a8fe20351..6e1e15d4ef 100644
--- a/src/quick/items/qquickpositioners_p_p.h
+++ b/src/quick/items/qquickpositioners_p_p.h
@@ -51,6 +51,7 @@
#include <QtQuick/private/qquickstate_p.h>
#include <private/qquicktransitionmanager_p_p.h>
#include <private/qquickstatechangescript_p.h>
+#include <private/qlazilyallocated_p.h>
#include <QtCore/qobject.h>
#include <QtCore/qstring.h>
@@ -65,10 +66,26 @@ class QQuickBasePositionerPrivate : public QQuickImplicitSizeItemPrivate, public
Q_DECLARE_PUBLIC(QQuickBasePositioner)
public:
+ struct ExtraData {
+ ExtraData();
+
+ qreal padding;
+ qreal topPadding;
+ qreal leftPadding;
+ qreal rightPadding;
+ qreal bottomPadding;
+ bool explicitTopPadding : 1;
+ bool explicitLeftPadding : 1;
+ bool explicitRightPadding : 1;
+ bool explicitBottomPadding : 1;
+ };
+ QLazilyAllocated<ExtraData> extra;
+
QQuickBasePositionerPrivate()
: spacing(0), type(QQuickBasePositioner::None)
, transitioner(0), positioningDirty(false)
, doingPositioning(false), anchorConflict(false), layoutDirection(Qt::LeftToRight)
+
{
}
@@ -149,6 +166,12 @@ public:
virtual void effectiveLayoutDirectionChange()
{
}
+
+ inline qreal padding() const { return extra.isAllocated() ? extra->padding : 0.0; }
+ void setTopPadding(qreal value, bool reset = false);
+ void setLeftPadding(qreal value, bool reset = false);
+ void setRightPadding(qreal value, bool reset = false);
+ void setBottomPadding(qreal value, bool reset = false);
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickrectangle_p.h b/src/quick/items/qquickrectangle_p.h
index 8a00dbaf92..16afa39bdd 100644
--- a/src/quick/items/qquickrectangle_p.h
+++ b/src/quick/items/qquickrectangle_p.h
@@ -125,7 +125,7 @@ private:
};
class QQuickRectanglePrivate;
-class Q_AUTOTEST_EXPORT QQuickRectangle : public QQuickItem
+class Q_QUICK_PRIVATE_EXPORT QQuickRectangle : public QQuickItem
{
Q_OBJECT
diff --git a/src/quick/items/qquickrendercontrol.cpp b/src/quick/items/qquickrendercontrol.cpp
index 6b0b9c3a06..cc4cec443a 100644
--- a/src/quick/items/qquickrendercontrol.cpp
+++ b/src/quick/items/qquickrendercontrol.cpp
@@ -46,7 +46,6 @@
#include <QtQuick/QQuickWindow>
#include <QtQuick/private/qquickwindow_p.h>
-#include <private/qqmlprofilerservice_p.h>
#include <QtCore/private/qobject_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/quick/items/qquickrepeater.cpp b/src/quick/items/qquickrepeater.cpp
index 0168d73c8f..09b504b742 100644
--- a/src/quick/items/qquickrepeater.cpp
+++ b/src/quick/items/qquickrepeater.cpp
@@ -50,6 +50,7 @@ QQuickRepeaterPrivate::QQuickRepeaterPrivate()
, delegateValidated(false)
, itemCount(0)
{
+ setTransparentForPositioner(true);
}
QQuickRepeaterPrivate::~QQuickRepeaterPrivate()
@@ -360,8 +361,8 @@ void QQuickRepeater::clear()
if (QQuickItem *item = d->deletables.at(i)) {
if (complete)
emit itemRemoved(i, item);
- item->setParentItem(0);
d->model->release(item);
+ item->setParentItem(0);
}
}
}
@@ -397,9 +398,17 @@ void QQuickRepeaterPrivate::requestItems()
void QQuickRepeater::createdItem(int index, QObject *)
{
Q_D(QQuickRepeater);
+ QObject *object = d->model->object(index, false);
+ QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
+ emit itemAdded(index, item);
+}
+
+void QQuickRepeater::initItem(int index, QObject *object)
+{
+ Q_D(QQuickRepeater);
+ QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
+
if (!d->deletables.at(index)) {
- QObject *object = d->model->object(index, false);
- QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
if (!item) {
if (object) {
d->model->release(object);
@@ -425,17 +434,9 @@ void QQuickRepeater::createdItem(int index, QObject *)
}
item->stackBefore(after);
}
- emit itemAdded(index, item);
}
}
-void QQuickRepeater::initItem(int, QObject *object)
-{
- QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
- if (item)
- item->setParentItem(parentItem());
-}
-
void QQuickRepeater::modelUpdated(const QQmlChangeSet &changeSet, bool reset)
{
Q_D(QQuickRepeater);
@@ -465,8 +466,8 @@ void QQuickRepeater::modelUpdated(const QQmlChangeSet &changeSet, bool reset)
d->deletables.remove(index);
emit itemRemoved(index, item);
if (item) {
- item->setParentItem(0);
d->model->release(item);
+ item->setParentItem(0);
}
--d->itemCount;
}
diff --git a/src/quick/items/qquickscalegrid_p_p.h b/src/quick/items/qquickscalegrid_p_p.h
index 7e0c021c19..b12da7a706 100644
--- a/src/quick/items/qquickscalegrid_p_p.h
+++ b/src/quick/items/qquickscalegrid_p_p.h
@@ -47,7 +47,6 @@ QT_BEGIN_NAMESPACE
class QQuickScaleGrid : public QObject
{
Q_OBJECT
- Q_ENUMS(TileRule)
Q_PROPERTY(int left READ left WRITE setLeft NOTIFY borderChanged)
Q_PROPERTY(int top READ top WRITE setTop NOTIFY borderChanged)
diff --git a/src/quick/items/qquickshadereffect_p.h b/src/quick/items/qquickshadereffect_p.h
index 1c60d9feaa..75a8319615 100644
--- a/src/quick/items/qquickshadereffect_p.h
+++ b/src/quick/items/qquickshadereffect_p.h
@@ -92,8 +92,6 @@ class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffect : public QQuickItem
Q_PROPERTY(QString log READ log NOTIFY logChanged)
Q_PROPERTY(Status status READ status NOTIFY statusChanged)
Q_PROPERTY(bool supportsAtlasTextures READ supportsAtlasTextures WRITE setSupportsAtlasTextures NOTIFY supportsAtlasTexturesChanged REVISION 1)
- Q_ENUMS(CullMode)
- Q_ENUMS(Status)
public:
enum CullMode
@@ -102,6 +100,7 @@ public:
BackFaceCulling = QQuickShaderEffectMaterial::BackFaceCulling,
FrontFaceCulling = QQuickShaderEffectMaterial::FrontFaceCulling
};
+ Q_ENUM(CullMode)
enum Status
{
@@ -109,6 +108,7 @@ public:
Uncompiled,
Error
};
+ Q_ENUM(Status)
QQuickShaderEffect(QQuickItem *parent = 0);
~QQuickShaderEffect();
diff --git a/src/quick/items/qquickshadereffectnode.cpp b/src/quick/items/qquickshadereffectnode.cpp
index de6cae0ea6..b84a4adaab 100644
--- a/src/quick/items/qquickshadereffectnode.cpp
+++ b/src/quick/items/qquickshadereffectnode.cpp
@@ -83,7 +83,9 @@ QQuickCustomMaterialShader::QQuickCustomMaterialShader(const QQuickShaderEffectM
, m_compiled(false)
, m_initialized(false)
{
- for (int i = 0; i < m_attributes.count(); ++i)
+ const int attributesCount = m_attributes.count();
+ m_attributeNames.reserve(attributesCount + 1);
+ for (int i = 0; i < attributesCount; ++i)
m_attributeNames.append(m_attributes.at(i).constData());
m_attributeNames.append(0);
}
diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h
index 31e503be42..94bb315566 100644
--- a/src/quick/items/qquickshadereffectsource_p.h
+++ b/src/quick/items/qquickshadereffectsource_p.h
@@ -67,7 +67,6 @@ class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectSource : public QQuickItem, publi
Q_PROPERTY(bool mipmap READ mipmap WRITE setMipmap NOTIFY mipmapChanged)
Q_PROPERTY(bool recursive READ recursive WRITE setRecursive NOTIFY recursiveChanged)
- Q_ENUMS(Format WrapMode)
public:
enum WrapMode {
ClampToEdge,
@@ -75,12 +74,14 @@ public:
RepeatVertically,
Repeat
};
+ Q_ENUM(WrapMode)
enum Format {
Alpha = GL_ALPHA,
RGB = GL_RGB,
RGBA = GL_RGBA
};
+ Q_ENUM(Format)
QQuickShaderEffectSource(QQuickItem *parent = 0);
~QQuickShaderEffectSource();
diff --git a/src/quick/items/qquickstateoperations.cpp b/src/quick/items/qquickstateoperations.cpp
index 579919db27..ac7fbc24af 100644
--- a/src/quick/items/qquickstateoperations.cpp
+++ b/src/quick/items/qquickstateoperations.cpp
@@ -358,7 +358,7 @@ QQuickStateOperation::ActionList QQuickParentChange::actions()
newBinding->setTarget(property);
QQuickStateAction xa;
xa.property = property;
- xa.toBinding = QQmlAbstractBinding::getPointer(newBinding);
+ xa.toBinding = newBinding;
xa.fromValue = xa.property.read();
xa.deletableToBinding = true;
actions << xa;
@@ -377,7 +377,7 @@ QQuickStateOperation::ActionList QQuickParentChange::actions()
newBinding->setTarget(property);
QQuickStateAction ya;
ya.property = property;
- ya.toBinding = QQmlAbstractBinding::getPointer(newBinding);
+ ya.toBinding = newBinding;
ya.fromValue = ya.property.read();
ya.deletableToBinding = true;
actions << ya;
@@ -396,7 +396,7 @@ QQuickStateOperation::ActionList QQuickParentChange::actions()
newBinding->setTarget(property);
QQuickStateAction sa;
sa.property = property;
- sa.toBinding = QQmlAbstractBinding::getPointer(newBinding);
+ sa.toBinding = newBinding;
sa.fromValue = sa.property.read();
sa.deletableToBinding = true;
actions << sa;
@@ -415,7 +415,7 @@ QQuickStateOperation::ActionList QQuickParentChange::actions()
newBinding->setTarget(property);
QQuickStateAction ra;
ra.property = property;
- ra.toBinding = QQmlAbstractBinding::getPointer(newBinding);
+ ra.toBinding = newBinding;
ra.fromValue = ra.property.read();
ra.deletableToBinding = true;
actions << ra;
@@ -434,7 +434,7 @@ QQuickStateOperation::ActionList QQuickParentChange::actions()
newBinding->setTarget(property);
QQuickStateAction wa;
wa.property = property;
- wa.toBinding = QQmlAbstractBinding::getPointer(newBinding);
+ wa.toBinding = newBinding;
wa.fromValue = wa.property.read();
wa.deletableToBinding = true;
actions << wa;
@@ -453,7 +453,7 @@ QQuickStateOperation::ActionList QQuickParentChange::actions()
newBinding->setTarget(property);
QQuickStateAction ha;
ha.property = property;
- ha.toBinding = QQmlAbstractBinding::getPointer(newBinding);
+ ha.toBinding = newBinding;
ha.fromValue = ha.property.read();
ha.deletableToBinding = true;
actions << ha;
@@ -482,7 +482,7 @@ void QQuickParentChange::saveOriginals()
saveCurrentValues();
}*/
-void QQuickParentChange::execute(Reason)
+void QQuickParentChange::execute()
{
Q_D(QQuickParentChange);
d->doChange(d->parent);
@@ -493,7 +493,7 @@ bool QQuickParentChange::isReversable()
return true;
}
-void QQuickParentChange::reverse(Reason)
+void QQuickParentChange::reverse()
{
Q_D(QQuickParentChange);
d->doChange(d->origParent, d->origStackBefore);
@@ -765,12 +765,7 @@ class QQuickAnchorChangesPrivate : public QQuickStateOperationPrivate
{
public:
QQuickAnchorChangesPrivate()
- : target(0), anchorSet(new QQuickAnchorSet),
- leftBinding(0), rightBinding(0), hCenterBinding(0),
- topBinding(0), bottomBinding(0), vCenterBinding(0), baselineBinding(0),
- origLeftBinding(0), origRightBinding(0), origHCenterBinding(0),
- origTopBinding(0), origBottomBinding(0), origVCenterBinding(0),
- origBaselineBinding(0)
+ : target(0), anchorSet(new QQuickAnchorSet)
{
}
@@ -779,21 +774,21 @@ public:
QQuickItem *target;
QQuickAnchorSet *anchorSet;
- QQmlBinding *leftBinding;
- QQmlBinding *rightBinding;
- QQmlBinding *hCenterBinding;
- QQmlBinding *topBinding;
- QQmlBinding *bottomBinding;
- QQmlBinding *vCenterBinding;
- QQmlBinding *baselineBinding;
-
- QQmlAbstractBinding *origLeftBinding;
- QQmlAbstractBinding *origRightBinding;
- QQmlAbstractBinding *origHCenterBinding;
- QQmlAbstractBinding *origTopBinding;
- QQmlAbstractBinding *origBottomBinding;
- QQmlAbstractBinding *origVCenterBinding;
- QQmlAbstractBinding *origBaselineBinding;
+ QExplicitlySharedDataPointer<QQmlBinding> leftBinding;
+ QExplicitlySharedDataPointer<QQmlBinding> rightBinding;
+ QExplicitlySharedDataPointer<QQmlBinding> hCenterBinding;
+ QExplicitlySharedDataPointer<QQmlBinding> topBinding;
+ QExplicitlySharedDataPointer<QQmlBinding> bottomBinding;
+ QExplicitlySharedDataPointer<QQmlBinding> vCenterBinding;
+ QExplicitlySharedDataPointer<QQmlBinding> baselineBinding;
+
+ QQmlAbstractBinding::Ptr origLeftBinding;
+ QQmlAbstractBinding::Ptr origRightBinding;
+ QQmlAbstractBinding::Ptr origHCenterBinding;
+ QQmlAbstractBinding::Ptr origTopBinding;
+ QQmlAbstractBinding::Ptr origBottomBinding;
+ QQmlAbstractBinding::Ptr origVCenterBinding;
+ QQmlAbstractBinding::Ptr origBaselineBinding;
QQuickAnchorLine rewindLeft;
QQuickAnchorLine rewindRight;
@@ -831,8 +826,6 @@ public:
qreal origX;
qreal origY;
- QList<QQmlAbstractBinding*> oldBindings;
-
QQmlProperty leftProp;
QQmlProperty rightProp;
QQmlProperty hCenterProp;
@@ -849,29 +842,6 @@ QQuickAnchorChanges::QQuickAnchorChanges(QObject *parent)
QQuickAnchorChanges::~QQuickAnchorChanges()
{
- /*
- if the anchorchanges is active at destruction, any non-active orig
- bindings need to be destroyed
-
- the basic logic is that if both e.g. left and origLeft are present,
- then we are active (otherwise left would have been destroyed), and
- left is in use and origLeft needs to be cleaned up.
- */
- Q_D(QQuickAnchorChanges);
- if (d->leftBinding && d->origLeftBinding)
- d->origLeftBinding->destroy();
- if (d->rightBinding && d->origRightBinding)
- d->origRightBinding->destroy();
- if (d->hCenterBinding && d->origHCenterBinding)
- d->origHCenterBinding->destroy();
- if (d->topBinding && d->origTopBinding)
- d->origTopBinding->destroy();
- if (d->bottomBinding && d->origBottomBinding)
- d->origBottomBinding->destroy();
- if (d->vCenterBinding && d->origVCenterBinding)
- d->origVCenterBinding->destroy();
- if (d->baselineBinding && d->origBaselineBinding)
- d->origBaselineBinding->destroy();
}
QQuickAnchorChanges::ActionList QQuickAnchorChanges::actions()
@@ -967,7 +937,7 @@ void QQuickAnchorChanges::setObject(QQuickItem *target)
\endqml
*/
-void QQuickAnchorChanges::execute(Reason reason)
+void QQuickAnchorChanges::execute()
{
Q_D(QQuickAnchorChanges);
if (!d->target)
@@ -978,94 +948,84 @@ void QQuickAnchorChanges::execute(Reason reason)
if (d->applyOrigLeft) {
if (!d->origLeftBinding)
targetPrivate->anchors()->resetLeft();
- QQmlPropertyPrivate::setBinding(d->leftProp, d->origLeftBinding);
+ QQmlPropertyPrivate::setBinding(d->leftProp, d->origLeftBinding.data());
}
if (d->applyOrigRight) {
if (!d->origRightBinding)
targetPrivate->anchors()->resetRight();
- QQmlPropertyPrivate::setBinding(d->rightProp, d->origRightBinding);
+ QQmlPropertyPrivate::setBinding(d->rightProp, d->origRightBinding.data());
}
if (d->applyOrigHCenter) {
if (!d->origHCenterBinding)
targetPrivate->anchors()->resetHorizontalCenter();
- QQmlPropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding);
+ QQmlPropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding.data());
}
if (d->applyOrigTop) {
if (!d->origTopBinding)
targetPrivate->anchors()->resetTop();
- QQmlPropertyPrivate::setBinding(d->topProp, d->origTopBinding);
+ QQmlPropertyPrivate::setBinding(d->topProp, d->origTopBinding.data());
}
if (d->applyOrigBottom) {
if (!d->origBottomBinding)
targetPrivate->anchors()->resetBottom();
- QQmlPropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding);
+ QQmlPropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding.data());
}
if (d->applyOrigVCenter) {
if (!d->origVCenterBinding)
targetPrivate->anchors()->resetVerticalCenter();
- QQmlPropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding);
+ QQmlPropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding.data());
}
if (d->applyOrigBaseline) {
if (!d->origBaselineBinding)
targetPrivate->anchors()->resetBaseline();
- QQmlPropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding);
- }
-
- //destroy old bindings
- if (reason == ActualChange) {
- for (int i = 0; i < d->oldBindings.size(); ++i) {
- QQmlAbstractBinding *binding = d->oldBindings.at(i);
- if (binding)
- binding->destroy();
- }
- d->oldBindings.clear();
+ QQmlPropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding.data());
}
//reset any anchors that have been specified as "undefined"
if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::LeftAnchor) {
targetPrivate->anchors()->resetLeft();
- QQmlPropertyPrivate::setBinding(d->leftProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->leftProp);
}
if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::RightAnchor) {
targetPrivate->anchors()->resetRight();
- QQmlPropertyPrivate::setBinding(d->rightProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->rightProp);
}
if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::HCenterAnchor) {
targetPrivate->anchors()->resetHorizontalCenter();
- QQmlPropertyPrivate::setBinding(d->hCenterProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->hCenterProp);
}
if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::TopAnchor) {
targetPrivate->anchors()->resetTop();
- QQmlPropertyPrivate::setBinding(d->topProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->topProp);
}
if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::BottomAnchor) {
targetPrivate->anchors()->resetBottom();
- QQmlPropertyPrivate::setBinding(d->bottomProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->bottomProp);
}
if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::VCenterAnchor) {
targetPrivate->anchors()->resetVerticalCenter();
- QQmlPropertyPrivate::setBinding(d->vCenterProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->vCenterProp);
}
if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::BaselineAnchor) {
targetPrivate->anchors()->resetBaseline();
- QQmlPropertyPrivate::setBinding(d->baselineProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->baselineProp);
}
//set any anchors that have been specified
if (d->leftBinding)
- QQmlPropertyPrivate::setBinding(d->leftBinding->property(), d->leftBinding);
+ QQmlPropertyPrivate::setBinding(d->leftBinding.data());
if (d->rightBinding)
- QQmlPropertyPrivate::setBinding(d->rightBinding->property(), d->rightBinding);
+ QQmlPropertyPrivate::setBinding(d->rightBinding.data());
if (d->hCenterBinding)
- QQmlPropertyPrivate::setBinding(d->hCenterBinding->property(), d->hCenterBinding);
+ QQmlPropertyPrivate::setBinding(d->hCenterBinding.data());
if (d->topBinding)
- QQmlPropertyPrivate::setBinding(d->topBinding->property(), d->topBinding);
+ QQmlPropertyPrivate::setBinding(d->topBinding.data());
if (d->bottomBinding)
- QQmlPropertyPrivate::setBinding(d->bottomBinding->property(), d->bottomBinding);
+ QQmlPropertyPrivate::setBinding(d->bottomBinding.data());
if (d->vCenterBinding)
- QQmlPropertyPrivate::setBinding(d->vCenterBinding->property(), d->vCenterBinding);
+ QQmlPropertyPrivate::setBinding(d->vCenterBinding.data());
if (d->baselineBinding)
- QQmlPropertyPrivate::setBinding(d->baselineBinding->property(), d->baselineBinding);
+ QQmlPropertyPrivate::setBinding(d->baselineBinding.data());
}
bool QQuickAnchorChanges::isReversable()
@@ -1073,7 +1033,7 @@ bool QQuickAnchorChanges::isReversable()
return true;
}
-void QQuickAnchorChanges::reverse(Reason reason)
+void QQuickAnchorChanges::reverse()
{
Q_D(QQuickAnchorChanges);
if (!d->target)
@@ -1083,69 +1043,48 @@ void QQuickAnchorChanges::reverse(Reason reason)
//reset any anchors set by the state
if (d->leftBinding) {
targetPrivate->anchors()->resetLeft();
- QQmlPropertyPrivate::setBinding(d->leftBinding->property(), 0);
- if (reason == ActualChange) {
- d->leftBinding->destroy(); d->leftBinding = 0;
- }
+ QQmlPropertyPrivate::removeBinding(d->leftBinding.data());
}
if (d->rightBinding) {
targetPrivate->anchors()->resetRight();
- QQmlPropertyPrivate::setBinding(d->rightBinding->property(), 0);
- if (reason == ActualChange) {
- d->rightBinding->destroy(); d->rightBinding = 0;
- }
+ QQmlPropertyPrivate::removeBinding(d->rightBinding.data());
}
if (d->hCenterBinding) {
targetPrivate->anchors()->resetHorizontalCenter();
- QQmlPropertyPrivate::setBinding(d->hCenterBinding->property(), 0);
- if (reason == ActualChange) {
- d->hCenterBinding->destroy(); d->hCenterBinding = 0;
- }
+ QQmlPropertyPrivate::removeBinding(d->hCenterBinding.data());
}
if (d->topBinding) {
targetPrivate->anchors()->resetTop();
- QQmlPropertyPrivate::setBinding(d->topBinding->property(), 0);
- if (reason == ActualChange) {
- d->topBinding->destroy(); d->topBinding = 0;
- }
+ QQmlPropertyPrivate::removeBinding(d->topBinding.data());
}
if (d->bottomBinding) {
targetPrivate->anchors()->resetBottom();
- QQmlPropertyPrivate::setBinding(d->bottomBinding->property(), 0);
- if (reason == ActualChange) {
- d->bottomBinding->destroy(); d->bottomBinding = 0;
- }
+ QQmlPropertyPrivate::removeBinding(d->bottomBinding.data());
}
if (d->vCenterBinding) {
targetPrivate->anchors()->resetVerticalCenter();
- QQmlPropertyPrivate::setBinding(d->vCenterBinding->property(), 0);
- if (reason == ActualChange) {
- d->vCenterBinding->destroy(); d->vCenterBinding = 0;
- }
+ QQmlPropertyPrivate::removeBinding(d->vCenterBinding.data());
}
if (d->baselineBinding) {
targetPrivate->anchors()->resetBaseline();
- QQmlPropertyPrivate::setBinding(d->baselineBinding->property(), 0);
- if (reason == ActualChange) {
- d->baselineBinding->destroy(); d->baselineBinding = 0;
- }
+ QQmlPropertyPrivate::removeBinding(d->baselineBinding.data());
}
//restore previous anchors
if (d->origLeftBinding)
- QQmlPropertyPrivate::setBinding(d->leftProp, d->origLeftBinding);
+ QQmlPropertyPrivate::setBinding(d->leftProp, d->origLeftBinding.data());
if (d->origRightBinding)
- QQmlPropertyPrivate::setBinding(d->rightProp, d->origRightBinding);
+ QQmlPropertyPrivate::setBinding(d->rightProp, d->origRightBinding.data());
if (d->origHCenterBinding)
- QQmlPropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding);
+ QQmlPropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding.data());
if (d->origTopBinding)
- QQmlPropertyPrivate::setBinding(d->topProp, d->origTopBinding);
+ QQmlPropertyPrivate::setBinding(d->topProp, d->origTopBinding.data());
if (d->origBottomBinding)
- QQmlPropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding);
+ QQmlPropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding.data());
if (d->origVCenterBinding)
- QQmlPropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding);
+ QQmlPropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding.data());
if (d->origBaselineBinding)
- QQmlPropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding);
+ QQmlPropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding.data());
//restore any absolute geometry changed by the state's anchors
QQuickAnchors::Anchors stateVAnchors = d->anchorSet->d_func()->usedAnchors & QQuickAnchors::Vertical_Mask;
@@ -1289,10 +1228,6 @@ void QQuickAnchorChanges::copyOriginals(QQuickStateActionEvent *other)
d->origX = acp->origX;
d->origY = acp->origY;
- d->oldBindings.clear();
- d->oldBindings << acp->leftBinding << acp->rightBinding << acp->hCenterBinding
- << acp->topBinding << acp->bottomBinding << acp->vCenterBinding << acp->baselineBinding;
-
//clear old values from other
//### could this be generalized for all QQuickStateActionEvents, and called after copyOriginals?
acp->leftBinding = 0;
@@ -1333,31 +1268,31 @@ void QQuickAnchorChanges::clearBindings()
d->anchorSet->d_func()->usedAnchors;
if (d->applyOrigLeft || (combined & QQuickAnchors::LeftAnchor)) {
targetPrivate->anchors()->resetLeft();
- QQmlPropertyPrivate::setBinding(d->leftProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->leftProp);
}
if (d->applyOrigRight || (combined & QQuickAnchors::RightAnchor)) {
targetPrivate->anchors()->resetRight();
- QQmlPropertyPrivate::setBinding(d->rightProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->rightProp);
}
if (d->applyOrigHCenter || (combined & QQuickAnchors::HCenterAnchor)) {
targetPrivate->anchors()->resetHorizontalCenter();
- QQmlPropertyPrivate::setBinding(d->hCenterProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->hCenterProp);
}
if (d->applyOrigTop || (combined & QQuickAnchors::TopAnchor)) {
targetPrivate->anchors()->resetTop();
- QQmlPropertyPrivate::setBinding(d->topProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->topProp);
}
if (d->applyOrigBottom || (combined & QQuickAnchors::BottomAnchor)) {
targetPrivate->anchors()->resetBottom();
- QQmlPropertyPrivate::setBinding(d->bottomProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->bottomProp);
}
if (d->applyOrigVCenter || (combined & QQuickAnchors::VCenterAnchor)) {
targetPrivate->anchors()->resetVerticalCenter();
- QQmlPropertyPrivate::setBinding(d->vCenterProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->vCenterProp);
}
if (d->applyOrigBaseline || (combined & QQuickAnchors::BaselineAnchor)) {
targetPrivate->anchors()->resetBaseline();
- QQmlPropertyPrivate::setBinding(d->baselineProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->baselineProp);
}
}
diff --git a/src/quick/items/qquickstateoperations_p.h b/src/quick/items/qquickstateoperations_p.h
index 8d4231c5fa..1999e23a83 100644
--- a/src/quick/items/qquickstateoperations_p.h
+++ b/src/quick/items/qquickstateoperations_p.h
@@ -97,9 +97,9 @@ public:
void saveOriginals() Q_DECL_OVERRIDE;
//virtual void copyOriginals(QQuickStateActionEvent*);
- void execute(Reason reason = ActualChange) Q_DECL_OVERRIDE;
+ void execute() Q_DECL_OVERRIDE;
bool isReversable() Q_DECL_OVERRIDE;
- void reverse(Reason reason = ActualChange) Q_DECL_OVERRIDE;
+ void reverse() Q_DECL_OVERRIDE;
EventType type() const Q_DECL_OVERRIDE;
bool override(QQuickStateActionEvent*other) Q_DECL_OVERRIDE;
void rewind() Q_DECL_OVERRIDE;
@@ -180,9 +180,9 @@ public:
QQuickItem *object() const;
void setObject(QQuickItem *);
- void execute(Reason reason = ActualChange) Q_DECL_OVERRIDE;
+ void execute() Q_DECL_OVERRIDE;
bool isReversable() Q_DECL_OVERRIDE;
- void reverse(Reason reason = ActualChange) Q_DECL_OVERRIDE;
+ void reverse() Q_DECL_OVERRIDE;
EventType type() const Q_DECL_OVERRIDE;
bool override(QQuickStateActionEvent*other) Q_DECL_OVERRIDE;
bool changesBindings() Q_DECL_OVERRIDE;
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index 205571f2e7..924c455872 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -85,7 +85,16 @@ QQuickTextPrivate::QQuickTextPrivate()
}
QQuickTextPrivate::ExtraData::ExtraData()
- : lineHeight(1.0)
+ : padding(0)
+ , topPadding(0)
+ , leftPadding(0)
+ , rightPadding(0)
+ , bottomPadding(0)
+ , explicitTopPadding(false)
+ , explicitLeftPadding(false)
+ , explicitRightPadding(false)
+ , explicitBottomPadding(false)
+ , lineHeight(1.0)
, doc(0)
, minimumPixelSize(12)
, minimumPointSize(12)
@@ -284,6 +293,74 @@ qreal QQuickTextPrivate::getImplicitHeight() const
return implicitHeight;
}
+qreal QQuickTextPrivate::availableWidth() const
+{
+ Q_Q(const QQuickText);
+ return q->width() - q->leftPadding() - q->rightPadding();
+}
+
+qreal QQuickTextPrivate::availableHeight() const
+{
+ Q_Q(const QQuickText);
+ return q->height() - q->topPadding() - q->bottomPadding();
+}
+
+void QQuickTextPrivate::setTopPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickText);
+ qreal oldPadding = q->topPadding();
+ if (!reset || extra.isAllocated()) {
+ extra.value().topPadding = value;
+ extra.value().explicitTopPadding = !reset;
+ }
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding()))) {
+ updateSize();
+ emit q->topPaddingChanged();
+ }
+}
+
+void QQuickTextPrivate::setLeftPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickText);
+ qreal oldPadding = q->leftPadding();
+ if (!reset || extra.isAllocated()) {
+ extra.value().leftPadding = value;
+ extra.value().explicitLeftPadding = !reset;
+ }
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding()))) {
+ updateSize();
+ emit q->leftPaddingChanged();
+ }
+}
+
+void QQuickTextPrivate::setRightPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickText);
+ qreal oldPadding = q->rightPadding();
+ if (!reset || extra.isAllocated()) {
+ extra.value().rightPadding = value;
+ extra.value().explicitRightPadding = !reset;
+ }
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding()))) {
+ updateSize();
+ emit q->rightPaddingChanged();
+ }
+}
+
+void QQuickTextPrivate::setBottomPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickText);
+ qreal oldPadding = q->bottomPadding();
+ if (!reset || extra.isAllocated()) {
+ extra.value().bottomPadding = value;
+ extra.value().explicitBottomPadding = !reset;
+ }
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding()))) {
+ updateSize();
+ emit q->bottomPaddingChanged();
+ }
+}
+
/*!
\qmlproperty bool QtQuick::Text::antialiasing
@@ -327,9 +404,9 @@ void QQuickTextPrivate::updateLayout()
formatModifiesFontSize = fontSizeModified;
multilengthEos = -1;
} else {
- layout.clearAdditionalFormats();
+ layout.clearFormats();
if (elideLayout)
- elideLayout->clearAdditionalFormats();
+ elideLayout->clearFormats();
QString tmp = text;
multilengthEos = tmp.indexOf(QLatin1Char('\x9c'));
if (multilengthEos != -1) {
@@ -410,7 +487,7 @@ void QQuickTextPrivate::updateBaseline(qreal baseline, qreal dy)
yoff = dy/2;
}
- q->setBaselineOffset(baseline + yoff);
+ q->setBaselineOffset(baseline + yoff + q->topPadding());
}
void QQuickTextPrivate::updateSize()
@@ -430,6 +507,9 @@ void QQuickTextPrivate::updateSize()
return;
}
+ qreal hPadding = q->leftPadding() + q->rightPadding();
+ qreal vPadding = q->topPadding() + q->bottomPadding();
+
if (text.isEmpty() && !isLineLaidOutConnected() && fontSizeMode() == QQuickText::FixedSize) {
// How much more expensive is it to just do a full layout on an empty string here?
// There may be subtle differences in the height and baseline calculations between
@@ -442,8 +522,8 @@ void QQuickTextPrivate::updateSize()
? lineHeight()
: fontHeight * lineHeight();
}
- updateBaseline(fm.ascent(), q->height() - fontHeight);
- q->setImplicitSize(0, fontHeight);
+ updateBaseline(fm.ascent(), q->height() - fontHeight - vPadding);
+ q->setImplicitSize(hPadding, fontHeight + vPadding);
layedOutTextRect = QRectF(0, 0, 0, fontHeight);
emit q->contentSizeChanged();
updateType = UpdatePaintNode;
@@ -464,7 +544,7 @@ void QQuickTextPrivate::updateSize()
layedOutTextRect = textRect;
size = textRect.size();
- updateBaseline(baseline, q->height() - size.height());
+ updateBaseline(baseline, q->height() - size.height() - vPadding);
} else {
widthExceeded = true; // always relayout rich text on width changes..
heightExceeded = false; // rich text layout isn't affected by height changes.
@@ -488,15 +568,15 @@ void QQuickTextPrivate::updateSize()
naturalWidth = extra->doc->idealWidth();
const bool wasInLayout = internalWidthUpdate;
internalWidthUpdate = true;
- q->setImplicitWidth(naturalWidth);
+ q->setImplicitWidth(naturalWidth + hPadding);
internalWidthUpdate = wasInLayout;
}
if (internalWidthUpdate)
return;
extra->doc->setPageSize(QSizeF());
- if (q->widthValid() && (wrapMode != QQuickText::NoWrap || extra->doc->idealWidth() < q->width()))
- extra->doc->setTextWidth(q->width());
+ if (q->widthValid() && (wrapMode != QQuickText::NoWrap || extra->doc->idealWidth() < availableWidth()))
+ extra->doc->setTextWidth(availableWidth());
else
extra->doc->setTextWidth(extra->doc->idealWidth()); // ### Text does not align if width is not set (QTextDoc bug)
@@ -505,7 +585,7 @@ void QQuickTextPrivate::updateSize()
size = QSizeF(extra->doc->idealWidth(),dsize.height());
QFontMetricsF fm(font);
- updateBaseline(fm.ascent(), q->height() - size.height());
+ updateBaseline(fm.ascent(), q->height() - size.height() - vPadding);
//### need to confirm cost of always setting these for richText
internalWidthUpdate = true;
@@ -513,11 +593,11 @@ void QQuickTextPrivate::updateSize()
if (!q->widthValid())
iWidth = size.width();
if (iWidth > -1)
- q->setImplicitSize(iWidth, size.height());
+ q->setImplicitSize(iWidth + hPadding, size.height() + vPadding);
internalWidthUpdate = false;
if (iWidth == -1)
- q->setImplicitHeight(size.height());
+ q->setImplicitHeight(size.height() + vPadding);
}
if (layedOutTextRect.size() != previousSize)
@@ -623,7 +703,7 @@ void QQuickTextPrivate::setupCustomLineGeometry(QTextLine &line, qreal &height,
// use the text item's width by default if it has one and wrap is on or text must be aligned
if (q->widthValid() && (q->wrapMode() != QQuickText::NoWrap ||
q->effectiveHAlign() != QQuickText::AlignLeft))
- textLine->setWidth(q->width());
+ textLine->setWidth(availableWidth());
else
textLine->setWidth(INT_MAX);
if (lineHeight() != 1.0)
@@ -635,10 +715,10 @@ void QQuickTextPrivate::setupCustomLineGeometry(QTextLine &line, qreal &height,
}
void QQuickTextPrivate::elideFormats(
- const int start, const int length, int offset, QList<QTextLayout::FormatRange> *elidedFormats)
+ const int start, const int length, int offset, QVector<QTextLayout::FormatRange> *elidedFormats)
{
const int end = start + length;
- QList<QTextLayout::FormatRange> formats = layout.additionalFormats();
+ const QVector<QTextLayout::FormatRange> formats = layout.formats();
for (int i = 0; i < formats.count(); ++i) {
QTextLayout::FormatRange format = formats.at(i);
const int formatLength = qMin(format.start + format.length, end) - qMax(format.start, start);
@@ -691,10 +771,11 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
&& (q->heightValid() || maximumLineCountValid);
if ((!requireImplicitSize || (implicitWidthValid && implicitHeightValid))
- && ((singlelineElide && q->width() <= 0.) || (multilineElide && q->heightValid() && q->height() <= 0.))) {
+ && ((singlelineElide && availableWidth() <= 0.)
+ || (multilineElide && q->heightValid() && availableHeight() <= 0.))) {
// we are elided and we have a zero width or height
- widthExceeded = q->widthValid() && q->width() <= 0.;
- heightExceeded = q->heightValid() && q->height() <= 0.;
+ widthExceeded = q->widthValid() && availableWidth() <= 0.;
+ heightExceeded = q->heightValid() && availableHeight() <= 0.;
if (!truncated) {
truncated = true;
@@ -730,7 +811,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
lineWidth = (q->widthValid() || implicitWidthValid) && q->width() > 0
? q->width()
: FLT_MAX;
- qreal maxHeight = q->heightValid() ? q->height() : FLT_MAX;
+ qreal maxHeight = q->heightValid() ? availableHeight() : FLT_MAX;
const bool customLayout = isLineLaidOutConnected();
const bool wasTruncated = truncated;
@@ -751,8 +832,8 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
int scaledFontSize = largeFont;
bool widthChanged = false;
- widthExceeded = q->width() <= 0 && (singlelineElide || canWrap || horizontalFit);
- heightExceeded = q->height() <= 0 && (multilineElide || verticalFit);
+ widthExceeded = availableWidth() <= 0 && (singlelineElide || canWrap || horizontalFit);
+ heightExceeded = availableHeight() <= 0 && (multilineElide || verticalFit);
QRectF br;
@@ -922,7 +1003,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
bool wasInLayout = internalWidthUpdate;
internalWidthUpdate = true;
- q->setImplicitSize(naturalWidth, naturalHeight);
+ q->setImplicitSize(naturalWidth + q->leftPadding() + q->rightPadding(), naturalHeight + q->topPadding() + q->bottomPadding());
internalWidthUpdate = wasInLayout;
// Update any variables that are dependent on the validity of the width or height.
@@ -939,8 +1020,11 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
const qreal oldWidth = lineWidth;
const qreal oldHeight = maxHeight;
- lineWidth = q->widthValid() && q->width() > 0 ? q->width() : naturalWidth;
- maxHeight = q->heightValid() ? q->height() : FLT_MAX;
+ const qreal availWidth = availableWidth();
+ const qreal availHeight = availableHeight();
+
+ lineWidth = q->widthValid() && availWidth > 0 ? availWidth : naturalWidth;
+ maxHeight = q->heightValid() ? availHeight : FLT_MAX;
// If the width of the item has changed and it's possible the result of wrapping,
// eliding, scaling has changed, or the text is not left aligned do another layout.
@@ -993,7 +1077,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
&& (q->heightValid() || (maximumLineCountValid && canWrap));
const qreal oldHeight = maxHeight;
- maxHeight = q->heightValid() ? q->height() : FLT_MAX;
+ maxHeight = q->heightValid() ? availableHeight() : FLT_MAX;
// If the height of the item has changed and it's possible the result of eliding,
// line count truncation or scaling has changed, do another layout.
if ((maxHeight < qMin(oldHeight, naturalHeight) || (heightExceeded && maxHeight > oldHeight))
@@ -1073,7 +1157,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
elideLayout->setCacheEnabled(true);
}
if (styledText) {
- QList<QTextLayout::FormatRange> formats;
+ QVector<QTextLayout::FormatRange> formats;
switch (elideMode) {
case QQuickText::ElideRight:
elideFormats(elideStart, elideText.length() - 1, 0, &formats);
@@ -1096,7 +1180,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
default:
break;
}
- elideLayout->setAdditionalFormats(formats);
+ elideLayout->setFormats(formats);
}
elideLayout->setFont(layout.font());
@@ -1361,6 +1445,16 @@ QQuickText::~QQuickText()
*/
/*!
+ \qmlproperty string QtQuick::Text::font.styleName
+ \since 5.6
+
+ Sets the style name of the font.
+
+ The style name is case insensitive. If set, the font will be matched against style name instead
+ of the font properties \l weight, \l bold and \l italic.
+*/
+
+/*!
\qmlproperty bool QtQuick::Text::font.bold
Sets whether the font weight is bold.
@@ -2279,7 +2373,7 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data
d->updateType = QQuickTextPrivate::UpdateNone;
- const qreal dy = QQuickTextUtil::alignedY(d->layedOutTextRect.height() + d->lineHeightOffset(), height(), d->vAlign);
+ const qreal dy = QQuickTextUtil::alignedY(d->layedOutTextRect.height() + d->lineHeightOffset(), d->availableHeight(), d->vAlign) + topPadding();
QQuickTextNode *node = 0;
if (!oldNode)
@@ -2296,11 +2390,11 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data
const QColor linkColor = QColor::fromRgba(d->linkColor);
if (d->richText) {
- const qreal dx = QQuickTextUtil::alignedX(d->layedOutTextRect.width(), width(), effectiveHAlign());
+ const qreal dx = QQuickTextUtil::alignedX(d->layedOutTextRect.width(), d->availableWidth(), effectiveHAlign()) + leftPadding();
d->ensureDoc();
node->addTextDocument(QPointF(dx, dy), d->extra->doc, color, d->style, styleColor, linkColor);
} else if (d->layedOutTextRect.width() > 0) {
- const qreal dx = QQuickTextUtil::alignedX(d->lineWidth, width(), effectiveHAlign());
+ const qreal dx = QQuickTextUtil::alignedX(d->lineWidth, d->availableWidth(), effectiveHAlign()) + leftPadding();
int unelidedLineCount = d->lineCount;
if (d->elideLayout)
unelidedLineCount -= 1;
@@ -2570,7 +2664,7 @@ QString QQuickTextPrivate::anchorAt(const QTextLayout *layout, const QPointF &mo
QTextLine line = layout->lineAt(i);
if (line.naturalTextRect().contains(mousePos)) {
int charPos = line.xToCursor(mousePos.x(), QTextLine::CursorOnCharacter);
- foreach (const QTextLayout::FormatRange &formatRange, layout->additionalFormats()) {
+ foreach (const QTextLayout::FormatRange &formatRange, layout->formats()) {
if (formatRange.format.isAnchor()
&& charPos >= formatRange.start
&& charPos < formatRange.start + formatRange.length) {
@@ -2587,14 +2681,15 @@ QString QQuickTextPrivate::anchorAt(const QPointF &mousePos) const
{
Q_Q(const QQuickText);
QPointF translatedMousePos = mousePos;
- translatedMousePos.ry() -= QQuickTextUtil::alignedY(layedOutTextRect.height() + lineHeightOffset(), q->height(), vAlign);
+ translatedMousePos.rx() -= q->leftPadding();
+ translatedMousePos.ry() -= q->topPadding() + QQuickTextUtil::alignedY(layedOutTextRect.height() + lineHeightOffset(), availableHeight(), vAlign);
if (styledText) {
QString link = anchorAt(&layout, translatedMousePos);
if (link.isEmpty() && elideLayout)
link = anchorAt(elideLayout, translatedMousePos);
return link;
} else if (richText && extra.isAllocated() && extra->doc) {
- translatedMousePos.rx() -= QQuickTextUtil::alignedX(layedOutTextRect.width(), q->width(), q->effectiveHAlign());
+ translatedMousePos.rx() -= QQuickTextUtil::alignedX(layedOutTextRect.width(), availableWidth(), q->effectiveHAlign());
return extra->doc->documentLayout()->anchorAt(translatedMousePos);
}
return QString();
@@ -2812,4 +2907,125 @@ void QQuickText::invalidateFontCaches()
}
}
+/*!
+ \since 5.6
+ \qmlproperty real QtQuick::Text::padding
+ \qmlproperty real QtQuick::Text::topPadding
+ \qmlproperty real QtQuick::Text::leftPadding
+ \qmlproperty real QtQuick::Text::bottomPadding
+ \qmlproperty real QtQuick::Text::rightPadding
+
+ These properties hold the padding around the content. This space is reserved
+ in addition to the contentWidth and contentHeight.
+*/
+qreal QQuickText::padding() const
+{
+ Q_D(const QQuickText);
+ return d->padding();
+}
+
+void QQuickText::setPadding(qreal padding)
+{
+ Q_D(QQuickText);
+ if (qFuzzyCompare(d->padding(), padding))
+ return;
+
+ d->extra.value().padding = padding;
+ d->updateSize();
+ emit paddingChanged();
+ if (!d->extra.isAllocated() || !d->extra->explicitTopPadding)
+ emit topPaddingChanged();
+ if (!d->extra.isAllocated() || !d->extra->explicitLeftPadding)
+ emit leftPaddingChanged();
+ if (!d->extra.isAllocated() || !d->extra->explicitRightPadding)
+ emit rightPaddingChanged();
+ if (!d->extra.isAllocated() || !d->extra->explicitBottomPadding)
+ emit bottomPaddingChanged();
+}
+
+void QQuickText::resetPadding()
+{
+ setPadding(0);
+}
+
+qreal QQuickText::topPadding() const
+{
+ Q_D(const QQuickText);
+ if (d->extra.isAllocated() && d->extra->explicitTopPadding)
+ return d->extra->topPadding;
+ return d->padding();
+}
+
+void QQuickText::setTopPadding(qreal padding)
+{
+ Q_D(QQuickText);
+ d->setTopPadding(padding);
+}
+
+void QQuickText::resetTopPadding()
+{
+ Q_D(QQuickText);
+ d->setTopPadding(0, true);
+}
+
+qreal QQuickText::leftPadding() const
+{
+ Q_D(const QQuickText);
+ if (d->extra.isAllocated() && d->extra->explicitLeftPadding)
+ return d->extra->leftPadding;
+ return d->padding();
+}
+
+void QQuickText::setLeftPadding(qreal padding)
+{
+ Q_D(QQuickText);
+ d->setLeftPadding(padding);
+}
+
+void QQuickText::resetLeftPadding()
+{
+ Q_D(QQuickText);
+ d->setLeftPadding(0, true);
+}
+
+qreal QQuickText::rightPadding() const
+{
+ Q_D(const QQuickText);
+ if (d->extra.isAllocated() && d->extra->explicitRightPadding)
+ return d->extra->rightPadding;
+ return d->padding();
+}
+
+void QQuickText::setRightPadding(qreal padding)
+{
+ Q_D(QQuickText);
+ d->setRightPadding(padding);
+}
+
+void QQuickText::resetRightPadding()
+{
+ Q_D(QQuickText);
+ d->setRightPadding(0, true);
+}
+
+qreal QQuickText::bottomPadding() const
+{
+ Q_D(const QQuickText);
+ if (d->extra.isAllocated() && d->extra->explicitBottomPadding)
+ return d->extra->bottomPadding;
+ return d->padding();
+}
+
+void QQuickText::setBottomPadding(qreal padding)
+{
+ Q_D(QQuickText);
+ d->setBottomPadding(padding);
+}
+
+void QQuickText::resetBottomPadding()
+{
+ Q_D(QQuickText);
+ d->setBottomPadding(0, true);
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/items/qquicktext_p.h b/src/quick/items/qquicktext_p.h
index 283e3b510b..f92927c9c4 100644
--- a/src/quick/items/qquicktext_p.h
+++ b/src/quick/items/qquicktext_p.h
@@ -45,15 +45,6 @@ class QQuickTextLine;
class Q_QUICK_PRIVATE_EXPORT QQuickText : public QQuickImplicitSizeItem
{
Q_OBJECT
- Q_ENUMS(HAlignment)
- Q_ENUMS(VAlignment)
- Q_ENUMS(TextStyle)
- Q_ENUMS(TextFormat)
- Q_ENUMS(TextElideMode)
- Q_ENUMS(WrapMode)
- Q_ENUMS(LineHeightMode)
- Q_ENUMS(FontSizeMode)
- Q_ENUMS(RenderType)
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged)
@@ -84,6 +75,12 @@ class Q_QUICK_PRIVATE_EXPORT QQuickText : public QQuickImplicitSizeItem
Q_PROPERTY(RenderType renderType READ renderType WRITE setRenderType NOTIFY renderTypeChanged)
Q_PROPERTY(QString hoveredLink READ hoveredLink NOTIFY linkHovered REVISION 2)
+ Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION 6)
+ Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6)
+
public:
QQuickText(QQuickItem *parent=0);
~QQuickText();
@@ -92,21 +89,26 @@ public:
AlignRight = Qt::AlignRight,
AlignHCenter = Qt::AlignHCenter,
AlignJustify = Qt::AlignJustify };
+ Q_ENUM(HAlignment)
enum VAlignment { AlignTop = Qt::AlignTop,
AlignBottom = Qt::AlignBottom,
AlignVCenter = Qt::AlignVCenter };
+ Q_ENUM(VAlignment)
enum TextStyle { Normal,
Outline,
Raised,
Sunken };
+ Q_ENUM(TextStyle)
enum TextFormat { PlainText = Qt::PlainText,
RichText = Qt::RichText,
AutoText = Qt::AutoText,
StyledText = 4 };
+ Q_ENUM(TextFormat)
enum TextElideMode { ElideLeft = Qt::ElideLeft,
ElideRight = Qt::ElideRight,
ElideMiddle = Qt::ElideMiddle,
ElideNone = Qt::ElideNone };
+ Q_ENUM(TextElideMode)
enum WrapMode { NoWrap = QTextOption::NoWrap,
WordWrap = QTextOption::WordWrap,
@@ -114,15 +116,19 @@ public:
WrapAtWordBoundaryOrAnywhere = QTextOption::WrapAtWordBoundaryOrAnywhere, // COMPAT
Wrap = QTextOption::WrapAtWordBoundaryOrAnywhere
};
+ Q_ENUM(WrapMode)
enum RenderType { QtRendering,
NativeRendering
};
+ Q_ENUM(RenderType)
enum LineHeightMode { ProportionalHeight, FixedHeight };
+ Q_ENUM(LineHeightMode)
enum FontSizeMode { FixedSize = 0x0, HorizontalFit = 0x01, VerticalFit = 0x02,
Fit = HorizontalFit | VerticalFit };
+ Q_ENUM(FontSizeMode)
QString text() const;
void setText(const QString &);
@@ -204,6 +210,26 @@ public:
Q_REVISION(3) Q_INVOKABLE QString linkAt(qreal x, qreal y) const;
+ qreal padding() const;
+ void setPadding(qreal padding);
+ void resetPadding();
+
+ qreal topPadding() const;
+ void setTopPadding(qreal padding);
+ void resetTopPadding();
+
+ qreal leftPadding() const;
+ void setLeftPadding(qreal padding);
+ void resetLeftPadding();
+
+ qreal rightPadding() const;
+ void setRightPadding(qreal padding);
+ void resetRightPadding();
+
+ qreal bottomPadding() const;
+ void setBottomPadding(qreal padding);
+ void resetBottomPadding();
+
Q_SIGNALS:
void textChanged(const QString &text);
void linkActivated(const QString &link);
@@ -231,6 +257,11 @@ Q_SIGNALS:
void lineLaidOut(QQuickTextLine *line);
void baseUrlChanged();
void renderTypeChanged();
+ Q_REVISION(6) void paddingChanged();
+ Q_REVISION(6) void topPaddingChanged();
+ Q_REVISION(6) void leftPaddingChanged();
+ Q_REVISION(6) void rightPaddingChanged();
+ Q_REVISION(6) void bottomPaddingChanged();
protected:
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h
index cd14008728..f43df691b5 100644
--- a/src/quick/items/qquicktext_p_p.h
+++ b/src/quick/items/qquicktext_p_p.h
@@ -78,7 +78,7 @@ public:
int lineHeightOffset() const;
QString elidedText(qreal lineWidth, const QTextLine &line, QTextLine *nextLine = 0) const;
- void elideFormats(int start, int length, int offset, QList<QTextLayout::FormatRange> *elidedFormats);
+ void elideFormats(int start, int length, int offset, QVector<QTextLayout::FormatRange> *elidedFormats);
void processHoverEvent(QHoverEvent *event);
@@ -87,6 +87,15 @@ public:
struct ExtraData {
ExtraData();
+ qreal padding;
+ qreal topPadding;
+ qreal leftPadding;
+ qreal rightPadding;
+ qreal bottomPadding;
+ bool explicitTopPadding : 1;
+ bool explicitLeftPadding : 1;
+ bool explicitRightPadding : 1;
+ bool explicitBottomPadding : 1;
qreal lineHeight;
QQuickTextDocumentWithImageResources *doc;
QString activeLink;
@@ -160,6 +169,15 @@ public:
qreal getImplicitWidth() const Q_DECL_OVERRIDE;
qreal getImplicitHeight() const Q_DECL_OVERRIDE;
+ qreal availableWidth() const;
+ qreal availableHeight() const;
+
+ inline qreal padding() const { return extra.isAllocated() ? extra->padding : 0.0; }
+ void setTopPadding(qreal value, bool reset = false);
+ void setLeftPadding(qreal value, bool reset = false);
+ void setRightPadding(qreal value, bool reset = false);
+ void setBottomPadding(qreal value, bool reset = false);
+
void ensureDoc();
QRectF setupTextLayout(qreal * const baseline);
diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp
index 6929bb44a2..7bc5fab677 100644
--- a/src/quick/items/qquicktextcontrol.cpp
+++ b/src/quick/items/qquicktextcontrol.cpp
@@ -1313,7 +1313,7 @@ void QQuickTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
QTextLayout *layout = block.layout();
if (isGettingInput)
layout->setPreeditArea(cursor.position() - block.position(), e->preeditString());
- QList<QTextLayout::FormatRange> overrides;
+ QVector<QTextLayout::FormatRange> overrides;
const int oldPreeditCursor = preeditCursor;
preeditCursor = e->preeditString().length();
hasImState = !e->preeditString().isEmpty();
@@ -1336,7 +1336,7 @@ void QQuickTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
}
}
}
- layout->setAdditionalFormats(overrides);
+ layout->setFormats(overrides);
cursor.endEditBlock();
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index cd1cf5eef1..dc4e301a36 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -172,6 +172,13 @@ QQuickTextEdit::QQuickTextEdit(QQuickItem *parent)
d->init();
}
+QQuickTextEdit::QQuickTextEdit(QQuickTextEditPrivate &dd, QQuickItem *parent)
+: QQuickImplicitSizeItem(dd, parent)
+{
+ Q_D(QQuickTextEdit);
+ d->init();
+}
+
QString QQuickTextEdit::text() const
{
Q_D(const QQuickTextEdit);
@@ -199,6 +206,17 @@ QString QQuickTextEdit::text() const
*/
/*!
+ \qmlproperty string QtQuick::TextEdit::font.styleName
+ \since 5.6
+
+ Sets the style name of the font.
+
+ The style name is case insensitive. If set, the font will be matched against style name instead
+ of the font properties \l weight, \l bold and \l italic.
+*/
+
+
+/*!
\qmlproperty bool QtQuick::TextEdit::font.bold
Sets whether the font weight is bold.
@@ -699,6 +717,62 @@ Qt::InputMethodHints QQuickTextEditPrivate::effectiveInputMethodHints() const
}
#endif
+void QQuickTextEditPrivate::setTopPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickTextEdit);
+ qreal oldPadding = q->topPadding();
+ if (!reset || extra.isAllocated()) {
+ extra.value().topPadding = value;
+ extra.value().explicitTopPadding = !reset;
+ }
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding()))) {
+ q->updateSize();
+ emit q->topPaddingChanged();
+ }
+}
+
+void QQuickTextEditPrivate::setLeftPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickTextEdit);
+ qreal oldPadding = q->leftPadding();
+ if (!reset || extra.isAllocated()) {
+ extra.value().leftPadding = value;
+ extra.value().explicitLeftPadding = !reset;
+ }
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding()))) {
+ q->updateSize();
+ emit q->leftPaddingChanged();
+ }
+}
+
+void QQuickTextEditPrivate::setRightPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickTextEdit);
+ qreal oldPadding = q->rightPadding();
+ if (!reset || extra.isAllocated()) {
+ extra.value().rightPadding = value;
+ extra.value().explicitRightPadding = !reset;
+ }
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding()))) {
+ q->updateSize();
+ emit q->rightPaddingChanged();
+ }
+}
+
+void QQuickTextEditPrivate::setBottomPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickTextEdit);
+ qreal oldPadding = q->bottomPadding();
+ if (!reset || extra.isAllocated()) {
+ extra.value().bottomPadding = value;
+ extra.value().explicitBottomPadding = !reset;
+ }
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding()))) {
+ q->updateSize();
+ emit q->bottomPaddingChanged();
+ }
+}
+
QQuickTextEdit::VAlignment QQuickTextEdit::vAlign() const
{
Q_D(const QQuickTextEdit);
@@ -1658,6 +1732,8 @@ void QQuickTextEdit::mousePressEvent(QMouseEvent *event)
#ifndef QT_NO_IM
if (hasActiveFocus() && hadActiveFocus && !isReadOnly())
qGuiApp->inputMethod()->show();
+#else
+ Q_UNUSED(hadActiveFocus);
#endif
}
if (!event->isAccepted())
@@ -1793,6 +1869,14 @@ void QQuickTextEdit::invalidateFontCaches()
}
}
+inline void resetEngine(QQuickTextNodeEngine *engine, const QColor& textColor, const QColor& selectedTextColor, const QColor& selectionColor)
+{
+ *engine = QQuickTextNodeEngine();
+ engine->setTextColor(textColor);
+ engine->setSelectedTextColor(selectedTextColor);
+ engine->setSelectionColor(selectionColor);
+}
+
QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData)
{
Q_UNUSED(updatePaintNodeData);
@@ -1818,6 +1902,8 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
while (nodeIterator != d->textNodeMap.end() && !(*nodeIterator)->dirty())
++nodeIterator;
+ QQuickTextNodeEngine engine;
+ QQuickTextNodeEngine frameDecorationsEngine;
if (!oldNode || nodeIterator < d->textNodeMap.end()) {
@@ -1837,6 +1923,7 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
// FIXME: the text decorations could probably be handled separately (only updated for affected textFrames)
rootNode->resetFrameDecorations(d->createTextNode());
+ resetEngine(&frameDecorationsEngine, d->color, d->selectedTextColor, d->selectionColor);
QQuickTextNode *node = 0;
@@ -1856,11 +1943,12 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
while (!frames.isEmpty()) {
QTextFrame *textFrame = frames.takeFirst();
frames.append(textFrame->childFrames());
- rootNode->frameDecorationsNode->m_engine->addFrameDecorations(d->document, textFrame);
+ frameDecorationsEngine.addFrameDecorations(d->document, textFrame);
if (textFrame->lastPosition() < firstDirtyPos || (firstCleanNode && textFrame->firstPosition() >= firstCleanNode->startPos()))
continue;
node = d->createTextNode();
+ resetEngine(&engine, d->color, d->selectedTextColor, d->selectionColor);
if (textFrame->firstPosition() > textFrame->lastPosition()
&& textFrame->frameFormat().position() != QTextFrameFormat::InFlow) {
@@ -1869,8 +1957,8 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
ProtectedLayoutAccessor *a = static_cast<ProtectedLayoutAccessor *>(d->document->documentLayout());
QTextCharFormat format = a->formatAccessor(pos);
QTextBlock block = textFrame->firstCursorPosition().block();
- node->m_engine->setCurrentLine(block.layout()->lineForTextPosition(pos - block.position()));
- node->m_engine->addTextObject(QPointF(0, 0), format, QQuickTextNodeEngine::Unselected, d->document,
+ engine.setCurrentLine(block.layout()->lineForTextPosition(pos - block.position()));
+ engine.addTextObject(QPointF(0, 0), format, QQuickTextNodeEngine::Unselected, d->document,
pos, textFrame->frameFormat().position());
nodeStart = pos;
} else {
@@ -1888,13 +1976,13 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
if (block.position() < firstDirtyPos)
continue;
- if (!node->m_engine->hasContents()) {
+ if (!engine.hasContents()) {
nodeOffset = d->document->documentLayout()->blockBoundingRect(block).topLeft();
updateNodeTransform(node, nodeOffset);
nodeStart = block.position();
}
- node->m_engine->addTextBlock(d->document, block, -nodeOffset, d->color, QColor(), selectionStart(), selectionEnd() - 1);
+ engine.addTextBlock(d->document, block, -nodeOffset, d->color, QColor(), selectionStart(), selectionEnd() - 1);
currentNodeSize += block.length();
if ((it.atEnd()) || (firstCleanNode && block.next().position() >= firstCleanNode->startPos())) // last node that needed replacing or last block of the frame
@@ -1903,15 +1991,16 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
QList<int>::const_iterator lowerBound = std::lower_bound(frameBoundaries.constBegin(), frameBoundaries.constEnd(), block.next().position());
if (currentNodeSize > nodeBreakingSize || lowerBound == frameBoundaries.constEnd() || *lowerBound > nodeStart) {
currentNodeSize = 0;
- d->addCurrentTextNodeToRoot(rootNode, node, nodeIterator, nodeStart);
+ d->addCurrentTextNodeToRoot(&engine, rootNode, node, nodeIterator, nodeStart);
node = d->createTextNode();
+ resetEngine(&engine, d->color, d->selectedTextColor, d->selectionColor);
nodeStart = block.next().position();
}
}
}
- d->addCurrentTextNodeToRoot(rootNode, node, nodeIterator, nodeStart);
+ d->addCurrentTextNodeToRoot(&engine, rootNode, node, nodeIterator, nodeStart);
}
- rootNode->frameDecorationsNode->m_engine->addToSceneGraph(rootNode->frameDecorationsNode, QQuickText::Normal, QColor());
+ frameDecorationsEngine.addToSceneGraph(rootNode->frameDecorationsNode, QQuickText::Normal, QColor());
// Now prepend the frame decorations since we want them rendered first, with the text nodes and cursor in front.
rootNode->prependChildNode(rootNode->frameDecorationsNode);
@@ -2016,6 +2105,19 @@ bool QQuickTextEdit::isInputMethodComposing() const
#endif // QT_NO_IM
}
+QQuickTextEditPrivate::ExtraData::ExtraData()
+ : padding(0)
+ , topPadding(0)
+ , leftPadding(0)
+ , rightPadding(0)
+ , bottomPadding(0)
+ , explicitTopPadding(false)
+ , explicitLeftPadding(false)
+ , explicitRightPadding(false)
+ , explicitBottomPadding(false)
+{
+}
+
void QQuickTextEditPrivate::init()
{
Q_Q(QQuickTextEdit);
@@ -2099,7 +2201,7 @@ void QQuickTextEdit::markDirtyNodesForRange(int start, int end, int charDelta)
}
// mark the affected nodes as dirty
- while (it != d->textNodeMap.constEnd()) {
+ while (it != d->textNodeMap.end()) {
if ((*it)->startPos() <= end)
(*it)->setDirty();
else if (charDelta)
@@ -2225,7 +2327,7 @@ void QQuickTextEdit::updateSize()
return;
}
- qreal naturalWidth = d->implicitWidth;
+ qreal naturalWidth = d->implicitWidth - leftPadding() - rightPadding();
qreal newWidth = d->document->idealWidth();
// ### assumes that if the width is set, the text will fill to edges
@@ -2243,13 +2345,13 @@ void QQuickTextEdit::updateSize()
const bool wasInLayout = d->inLayout;
d->inLayout = true;
- setImplicitWidth(naturalWidth);
+ setImplicitWidth(naturalWidth + leftPadding() + rightPadding());
d->inLayout = wasInLayout;
if (d->inLayout) // probably the result of a binding loop, but by letting it
return; // get this far we'll get a warning to that effect.
}
if (d->document->textWidth() != width()) {
- d->document->setTextWidth(width());
+ d->document->setTextWidth(width() - leftPadding() - rightPadding());
newWidth = d->document->idealWidth();
}
//### need to confirm cost of always setting these
@@ -2264,12 +2366,12 @@ void QQuickTextEdit::updateSize()
// ### Setting the implicitWidth triggers another updateSize(), and unless there are bindings nothing has changed.
if (!widthValid() && !d->requireImplicitWidth)
- setImplicitSize(newWidth, newHeight);
+ setImplicitSize(newWidth + leftPadding() + rightPadding(), newHeight + topPadding() + bottomPadding());
else
- setImplicitHeight(newHeight);
+ setImplicitHeight(newHeight + topPadding() + bottomPadding());
- d->xoff = qMax(qreal(0), QQuickTextUtil::alignedX(d->document->size().width(), width(), effectiveHAlign()));
- d->yoff = QQuickTextUtil::alignedY(d->document->size().height(), height(), d->vAlign);
+ d->xoff = leftPadding() + qMax(qreal(0), QQuickTextUtil::alignedX(d->document->size().width(), width() - leftPadding() - rightPadding(), effectiveHAlign()));
+ d->yoff = topPadding() + QQuickTextUtil::alignedY(d->document->size().height(), height() - topPadding() - bottomPadding(), d->vAlign);
setBaselineOffset(fm.ascent() + d->yoff + d->textMargin);
QSizeF size(newWidth, newHeight);
@@ -2416,16 +2518,19 @@ void QQuickTextEditPrivate::handleFocusEvent(QFocusEvent *event)
qGuiApp->inputMethod()->show();
q->connect(QGuiApplication::inputMethod(), SIGNAL(inputDirectionChanged(Qt::LayoutDirection)),
q, SLOT(q_updateAlignment()));
+#endif
} else {
+#ifndef QT_NO_IM
q->disconnect(QGuiApplication::inputMethod(), SIGNAL(inputDirectionChanged(Qt::LayoutDirection)),
q, SLOT(q_updateAlignment()));
#endif
+ emit q->editingFinished();
}
}
-void QQuickTextEditPrivate::addCurrentTextNodeToRoot(QSGTransformNode *root, QQuickTextNode *node, TextNodeIterator &it, int startPos)
+void QQuickTextEditPrivate::addCurrentTextNodeToRoot(QQuickTextNodeEngine *engine, QSGTransformNode *root, QQuickTextNode *node, TextNodeIterator &it, int startPos)
{
- node->m_engine->addToSceneGraph(node, QQuickText::Normal, QColor());
+ engine->addToSceneGraph(node, QQuickText::Normal, QColor());
it = textNodeMap.insert(it, new TextNode(startPos, node));
++it;
root->appendChildNode(node);
@@ -2436,7 +2541,6 @@ QQuickTextNode *QQuickTextEditPrivate::createTextNode()
Q_Q(QQuickTextEdit);
QQuickTextNode* node = new QQuickTextNode(q);
node->setUseNativeRenderer(renderType == QQuickTextEdit::NativeRendering);
- node->initEngine(color, selectedTextColor, selectionColor);
return node;
}
@@ -2588,6 +2692,15 @@ bool QQuickTextEditPrivate::isLinkHoveredConnected()
*/
/*!
+ \qmlsignal QtQuick::TextEdit::editingFinished()
+ \since 5.6
+
+ This signal is emitted when the text edit loses focus.
+
+ The corresponding handler is \c onEditingFinished.
+*/
+
+/*!
\qmlproperty string QtQuick::TextEdit::hoveredLink
\since 5.2
@@ -2680,7 +2793,132 @@ void QQuickTextEdit::append(const QString &text)
QString QQuickTextEdit::linkAt(qreal x, qreal y) const
{
Q_D(const QQuickTextEdit);
- return d->control->anchorAt(QPointF(x, y));
+ return d->control->anchorAt(QPointF(x + topPadding(), y + leftPadding()));
+}
+
+/*!
+ \since 5.6
+ \qmlproperty real QtQuick::TextEdit::padding
+ \qmlproperty real QtQuick::TextEdit::topPadding
+ \qmlproperty real QtQuick::TextEdit::leftPadding
+ \qmlproperty real QtQuick::TextEdit::bottomPadding
+ \qmlproperty real QtQuick::TextEdit::rightPadding
+
+ These properties hold the padding around the content. This space is reserved
+ in addition to the contentWidth and contentHeight.
+*/
+qreal QQuickTextEdit::padding() const
+{
+ Q_D(const QQuickTextEdit);
+ return d->padding();
+}
+
+void QQuickTextEdit::setPadding(qreal padding)
+{
+ Q_D(QQuickTextEdit);
+ if (qFuzzyCompare(d->padding(), padding))
+ return;
+
+ d->extra.value().padding = padding;
+ updateSize();
+ if (isComponentComplete()) {
+ d->updateType = QQuickTextEditPrivate::UpdatePaintNode;
+ update();
+ }
+ emit paddingChanged();
+ if (!d->extra.isAllocated() || !d->extra->explicitTopPadding)
+ emit topPaddingChanged();
+ if (!d->extra.isAllocated() || !d->extra->explicitLeftPadding)
+ emit leftPaddingChanged();
+ if (!d->extra.isAllocated() || !d->extra->explicitRightPadding)
+ emit rightPaddingChanged();
+ if (!d->extra.isAllocated() || !d->extra->explicitBottomPadding)
+ emit bottomPaddingChanged();
+}
+
+void QQuickTextEdit::resetPadding()
+{
+ setPadding(0);
+}
+
+qreal QQuickTextEdit::topPadding() const
+{
+ Q_D(const QQuickTextEdit);
+ if (d->extra.isAllocated() && d->extra->explicitTopPadding)
+ return d->extra->topPadding;
+ return d->padding();
+}
+
+void QQuickTextEdit::setTopPadding(qreal padding)
+{
+ Q_D(QQuickTextEdit);
+ d->setTopPadding(padding);
+}
+
+void QQuickTextEdit::resetTopPadding()
+{
+ Q_D(QQuickTextEdit);
+ d->setTopPadding(0, true);
+}
+
+qreal QQuickTextEdit::leftPadding() const
+{
+ Q_D(const QQuickTextEdit);
+ if (d->extra.isAllocated() && d->extra->explicitLeftPadding)
+ return d->extra->leftPadding;
+ return d->padding();
+}
+
+void QQuickTextEdit::setLeftPadding(qreal padding)
+{
+ Q_D(QQuickTextEdit);
+ d->setLeftPadding(padding);
+}
+
+void QQuickTextEdit::resetLeftPadding()
+{
+ Q_D(QQuickTextEdit);
+ d->setLeftPadding(0, true);
+}
+
+qreal QQuickTextEdit::rightPadding() const
+{
+ Q_D(const QQuickTextEdit);
+ if (d->extra.isAllocated() && d->extra->explicitRightPadding)
+ return d->extra->rightPadding;
+ return d->padding();
+}
+
+void QQuickTextEdit::setRightPadding(qreal padding)
+{
+ Q_D(QQuickTextEdit);
+ d->setRightPadding(padding);
+}
+
+void QQuickTextEdit::resetRightPadding()
+{
+ Q_D(QQuickTextEdit);
+ d->setRightPadding(0, true);
+}
+
+qreal QQuickTextEdit::bottomPadding() const
+{
+ Q_D(const QQuickTextEdit);
+ if (d->extra.isAllocated() && d->extra->explicitBottomPadding)
+ return d->extra->bottomPadding;
+ return d->padding();
+}
+
+void QQuickTextEdit::setBottomPadding(qreal padding)
+{
+ Q_D(QQuickTextEdit);
+ d->setBottomPadding(padding);
+}
+
+void QQuickTextEdit::resetBottomPadding()
+{
+ Q_D(QQuickTextEdit);
+ d->setBottomPadding(0, true);
}
QT_END_NAMESPACE
diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h
index bf6763f772..cfe599c0d3 100644
--- a/src/quick/items/qquicktextedit_p.h
+++ b/src/quick/items/qquicktextedit_p.h
@@ -47,12 +47,6 @@ class QTextBlock;
class Q_QUICK_PRIVATE_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem
{
Q_OBJECT
- Q_ENUMS(VAlignment)
- Q_ENUMS(HAlignment)
- Q_ENUMS(TextFormat)
- Q_ENUMS(WrapMode)
- Q_ENUMS(SelectionMode)
- Q_ENUMS(RenderType)
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
@@ -91,8 +85,13 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem
Q_PROPERTY(bool inputMethodComposing READ isInputMethodComposing NOTIFY inputMethodComposingChanged)
Q_PROPERTY(QUrl baseUrl READ baseUrl WRITE setBaseUrl RESET resetBaseUrl NOTIFY baseUrlChanged)
Q_PROPERTY(RenderType renderType READ renderType WRITE setRenderType NOTIFY renderTypeChanged)
- Q_PROPERTY(QQuickTextDocument *textDocument READ textDocument FINAL REVISION 1)
+ Q_PROPERTY(QQuickTextDocument *textDocument READ textDocument CONSTANT FINAL REVISION 1)
Q_PROPERTY(QString hoveredLink READ hoveredLink NOTIFY linkHovered REVISION 2)
+ Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION 6)
+ Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6)
public:
QQuickTextEdit(QQuickItem *parent=0);
@@ -103,18 +102,21 @@ public:
AlignHCenter = Qt::AlignHCenter,
AlignJustify = Qt::AlignJustify
};
+ Q_ENUM(HAlignment)
enum VAlignment {
AlignTop = Qt::AlignTop,
AlignBottom = Qt::AlignBottom,
AlignVCenter = Qt::AlignVCenter
};
+ Q_ENUM(VAlignment)
enum TextFormat {
PlainText = Qt::PlainText,
RichText = Qt::RichText,
AutoText = Qt::AutoText
};
+ Q_ENUM(TextFormat)
enum WrapMode { NoWrap = QTextOption::NoWrap,
WordWrap = QTextOption::WordWrap,
@@ -122,15 +124,18 @@ public:
WrapAtWordBoundaryOrAnywhere = QTextOption::WrapAtWordBoundaryOrAnywhere, // COMPAT
Wrap = QTextOption::WrapAtWordBoundaryOrAnywhere
};
+ Q_ENUM(WrapMode)
enum SelectionMode {
SelectCharacters,
SelectWords
};
+ Q_ENUM(SelectionMode)
enum RenderType { QtRendering,
NativeRendering
};
+ Q_ENUM(RenderType)
QString text() const;
void setText(const QString &);
@@ -247,6 +252,26 @@ public:
Q_REVISION(3) Q_INVOKABLE QString linkAt(qreal x, qreal y) const;
+ qreal padding() const;
+ void setPadding(qreal padding);
+ void resetPadding();
+
+ qreal topPadding() const;
+ void setTopPadding(qreal padding);
+ void resetTopPadding();
+
+ qreal leftPadding() const;
+ void setLeftPadding(qreal padding);
+ void resetLeftPadding();
+
+ qreal rightPadding() const;
+ void setRightPadding(qreal padding);
+ void resetRightPadding();
+
+ qreal bottomPadding() const;
+ void setBottomPadding(qreal padding);
+ void resetBottomPadding();
+
Q_SIGNALS:
void textChanged();
void contentSizeChanged();
@@ -283,6 +308,12 @@ Q_SIGNALS:
void baseUrlChanged();
void inputMethodHintsChanged();
void renderTypeChanged();
+ Q_REVISION(6) void editingFinished();
+ Q_REVISION(6) void paddingChanged();
+ Q_REVISION(6) void topPaddingChanged();
+ Q_REVISION(6) void leftPaddingChanged();
+ Q_REVISION(6) void rightPaddingChanged();
+ Q_REVISION(6) void bottomPaddingChanged();
public Q_SLOTS:
void selectAll();
@@ -321,6 +352,8 @@ private:
void invalidateFontCaches();
protected:
+ QQuickTextEdit(QQuickTextEditPrivate &dd, QQuickItem *parent = 0);
+
void geometryChanged(const QRectF &newGeometry,
const QRectF &oldGeometry) Q_DECL_OVERRIDE;
diff --git a/src/quick/items/qquicktextedit_p_p.h b/src/quick/items/qquicktextedit_p_p.h
index 0cf0f46532..a763f9e56e 100644
--- a/src/quick/items/qquicktextedit_p_p.h
+++ b/src/quick/items/qquicktextedit_p_p.h
@@ -47,18 +47,19 @@
#include "qquicktextedit_p.h"
#include "qquickimplicitsizeitem_p_p.h"
-#include "qquicktextcontrol_p.h"
#include <QtQml/qqml.h>
#include <QtCore/qlist.h>
+#include <private/qlazilyallocated_p.h>
QT_BEGIN_NAMESPACE
class QTextLayout;
class QQuickTextDocumentWithImageResources;
class QQuickTextControl;
class QQuickTextNode;
+class QQuickTextNodeEngine;
-class QQuickTextEditPrivate : public QQuickImplicitSizeItemPrivate
+class Q_QUICK_PRIVATE_EXPORT QQuickTextEditPrivate : public QQuickImplicitSizeItemPrivate
{
public:
Q_DECLARE_PUBLIC(QQuickTextEdit)
@@ -81,10 +82,26 @@ public:
};
typedef QList<Node*>::iterator TextNodeIterator;
+ struct ExtraData {
+ ExtraData();
+
+ qreal padding;
+ qreal topPadding;
+ qreal leftPadding;
+ qreal rightPadding;
+ qreal bottomPadding;
+ bool explicitTopPadding : 1;
+ bool explicitLeftPadding : 1;
+ bool explicitRightPadding : 1;
+ bool explicitBottomPadding : 1;
+ };
+ QLazilyAllocated<ExtraData> extra;
+
QQuickTextEditPrivate()
: color(QRgb(0xFF000000)), selectionColor(QRgb(0xFF000080)), selectedTextColor(QRgb(0xFFFFFFFF))
- , textMargin(0.0), xoff(0), yoff(0), font(sourceFont), cursorComponent(0), cursorItem(0), document(0), control(0)
+ , textMargin(0.0), xoff(0), yoff(0)
+ , font(sourceFont), cursorComponent(0), cursorItem(0), document(0), control(0)
, quickDocument(0), lastSelectionStart(0), lastSelectionEnd(0), lineCount(0)
, hAlign(QQuickTextEdit::AlignLeft), vAlign(QQuickTextEdit::AlignTop)
, format(QQuickTextEdit::PlainText), wrapMode(QQuickTextEdit::NoWrap)
@@ -124,13 +141,19 @@ public:
void setNativeCursorEnabled(bool) {}
void handleFocusEvent(QFocusEvent *event);
- void addCurrentTextNodeToRoot(QSGTransformNode *, QQuickTextNode*, TextNodeIterator&, int startPos);
+ void addCurrentTextNodeToRoot(QQuickTextNodeEngine *, QSGTransformNode *, QQuickTextNode*, TextNodeIterator&, int startPos);
QQuickTextNode* createTextNode();
#ifndef QT_NO_IM
Qt::InputMethodHints effectiveInputMethodHints() const;
#endif
+ inline qreal padding() const { return extra.isAllocated() ? extra->padding : 0.0; }
+ void setTopPadding(qreal value, bool reset = false);
+ void setLeftPadding(qreal value, bool reset = false);
+ void setRightPadding(qreal value, bool reset = false);
+ void setBottomPadding(qreal value, bool reset = false);
+
QColor color;
QColor selectionColor;
QColor selectedTextColor;
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index 5c67d914a5..c29acf3c83 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -90,6 +90,13 @@ QQuickTextInput::QQuickTextInput(QQuickItem* parent)
d->init();
}
+QQuickTextInput::QQuickTextInput(QQuickTextInputPrivate &dd, QQuickItem *parent)
+: QQuickImplicitSizeItem(dd, parent)
+{
+ Q_D(QQuickTextInput);
+ d->init();
+}
+
QQuickTextInput::~QQuickTextInput()
{
}
@@ -222,6 +229,16 @@ QString QQuickTextInputPrivate::realText() const
*/
/*!
+ \qmlproperty string QtQuick::TextInput::font.styleName
+ \since 5.6
+
+ Sets the style name of the font.
+
+ The style name is case insensitive. If set, the font will be matched against style name instead
+ of the font properties \l weight, \l bold and \l italic.
+*/
+
+/*!
\qmlproperty bool QtQuick::TextInput::font.bold
Sets whether the font weight is bold.
@@ -786,8 +803,8 @@ QRectF QQuickTextInput::cursorRectangle() const
QTextLine l = d->m_textLayout.lineForTextPosition(c);
if (!l.isValid())
return QRectF();
- qreal x = l.cursorToX(c) - d->hscroll;
- qreal y = l.y() - d->vscroll;
+ qreal x = l.cursorToX(c) - d->hscroll + leftPadding();
+ qreal y = l.y() - d->vscroll + topPadding();
return QRectF(x, y, 1, l.height());
}
@@ -910,189 +927,6 @@ void QQuickTextInput::setAutoScroll(bool b)
emit autoScrollChanged(d->autoScroll);
}
-#ifndef QT_NO_VALIDATOR
-
-/*!
- \qmltype IntValidator
- \instantiates QIntValidator
- \inqmlmodule QtQuick
- \ingroup qtquick-text-utility
- \brief Defines a validator for integer values
-
- The IntValidator type provides a validator for integer values.
-
- If no \l locale is set IntValidator uses the \l {QLocale::setDefault()}{default locale} to
- interpret the number and will accept locale specific digits, group separators, and positive
- and negative signs. In addition, IntValidator is always guaranteed to accept a number
- formatted according to the "C" locale.
-*/
-
-
-QQuickIntValidator::QQuickIntValidator(QObject *parent)
- : QIntValidator(parent)
-{
-}
-
-/*!
- \qmlproperty string QtQuick::IntValidator::locale
-
- This property holds the name of the locale used to interpret the number.
-
- \sa {QtQml::Qt::locale()}{Qt.locale()}
-*/
-
-QString QQuickIntValidator::localeName() const
-{
- return locale().name();
-}
-
-void QQuickIntValidator::setLocaleName(const QString &name)
-{
- if (locale().name() != name) {
- setLocale(QLocale(name));
- emit localeNameChanged();
- }
-}
-
-void QQuickIntValidator::resetLocaleName()
-{
- QLocale defaultLocale;
- if (locale() != defaultLocale) {
- setLocale(defaultLocale);
- emit localeNameChanged();
- }
-}
-
-/*!
- \qmlproperty int QtQuick::IntValidator::top
-
- This property holds the validator's highest acceptable value.
- By default, this property's value is derived from the highest signed integer available (typically 2147483647).
-*/
-/*!
- \qmlproperty int QtQuick::IntValidator::bottom
-
- This property holds the validator's lowest acceptable value.
- By default, this property's value is derived from the lowest signed integer available (typically -2147483647).
-*/
-
-/*!
- \qmltype DoubleValidator
- \instantiates QDoubleValidator
- \inqmlmodule QtQuick
- \ingroup qtquick-text-utility
- \brief Defines a validator for non-integer numbers
-
- The DoubleValidator type provides a validator for non-integer numbers.
-
- Input is accepted if it contains a double that is within the valid range
- and is in the correct format.
-
- Input is accepected but invalid if it contains a double that is outside
- the range or is in the wrong format; e.g. with too many digits after the
- decimal point or is empty.
-
- Input is rejected if it is not a double.
-
- Note: If the valid range consists of just positive doubles (e.g. 0.0 to
- 100.0) and input is a negative double then it is rejected. If \l notation
- is set to DoubleValidator.StandardNotation, and the input contains more
- digits before the decimal point than a double in the valid range may have,
- it is also rejected. If \l notation is DoubleValidator.ScientificNotation,
- and the input is not in the valid range, it is accecpted but invalid. The
- value may yet become valid by changing the exponent.
-*/
-
-QQuickDoubleValidator::QQuickDoubleValidator(QObject *parent)
- : QDoubleValidator(parent)
-{
-}
-
-/*!
- \qmlproperty string QtQuick::DoubleValidator::locale
-
- This property holds the name of the locale used to interpret the number.
-
- \sa {QtQml::Qt::locale()}{Qt.locale()}
-*/
-
-QString QQuickDoubleValidator::localeName() const
-{
- return locale().name();
-}
-
-void QQuickDoubleValidator::setLocaleName(const QString &name)
-{
- if (locale().name() != name) {
- setLocale(QLocale(name));
- emit localeNameChanged();
- }
-}
-
-void QQuickDoubleValidator::resetLocaleName()
-{
- QLocale defaultLocale;
- if (locale() != defaultLocale) {
- setLocale(defaultLocale);
- emit localeNameChanged();
- }
-}
-
-#endif // QT_NO_VALIDATOR
-
-/*!
- \qmlproperty real QtQuick::DoubleValidator::top
-
- This property holds the validator's maximum acceptable value.
- By default, this property contains a value of infinity.
-*/
-/*!
- \qmlproperty real QtQuick::DoubleValidator::bottom
-
- This property holds the validator's minimum acceptable value.
- By default, this property contains a value of -infinity.
-*/
-/*!
- \qmlproperty int QtQuick::DoubleValidator::decimals
-
- This property holds the validator's maximum number of digits after the decimal point.
- By default, this property contains a value of 1000.
-*/
-/*!
- \qmlproperty enumeration QtQuick::DoubleValidator::notation
- This property holds the notation of how a string can describe a number.
-
- The possible values for this property are:
-
- \list
- \li DoubleValidator.StandardNotation
- \li DoubleValidator.ScientificNotation (default)
- \endlist
-
- If this property is set to DoubleValidator.ScientificNotation, the written number may have an exponent part (e.g. 1.5E-2).
-*/
-
-/*!
- \qmltype RegExpValidator
- \instantiates QRegExpValidator
- \inqmlmodule QtQuick
- \ingroup qtquick-text-utility
- \brief Provides a string validator
-
- The RegExpValidator type provides a validator, which counts as valid any string which
- matches a specified regular expression.
-*/
-/*!
- \qmlproperty regExp QtQuick::RegExpValidator::regExp
-
- This property holds the regular expression used for validation.
-
- Note that this property should be a regular expression in JS syntax, e.g /a/ for the regular expression
- matching "a".
-
- By default, this property contains a regular expression with the pattern .* that matches any string.
-*/
-
/*!
\qmlproperty Validator QtQuick::TextInput::validator
@@ -1489,8 +1323,9 @@ void QQuickTextInput::positionAt(QQmlV4Function *args) const
int QQuickTextInputPrivate::positionAt(qreal x, qreal y, QTextLine::CursorPosition position) const
{
- x += hscroll;
- y += vscroll;
+ Q_Q(const QQuickTextInput);
+ x += hscroll - q->leftPadding();
+ y += vscroll - q->topPadding();
QTextLine line = m_textLayout.lineAt(0);
for (int i = 1; i < m_textLayout.lineCount(); ++i) {
QTextLine nextLine = m_textLayout.lineAt(i);
@@ -1748,7 +1583,7 @@ void QQuickTextInputPrivate::ensureVisible(int position, int preeditCursor, int
{
Q_Q(QQuickTextInput);
QTextLine textLine = m_textLayout.lineForTextPosition(position + preeditCursor);
- const qreal width = qMax<qreal>(0, q->width());
+ const qreal width = qMax<qreal>(0, q->width() - q->leftPadding() - q->rightPadding());
qreal cix = 0;
qreal widthUsed = 0;
if (textLine.isValid()) {
@@ -1811,7 +1646,7 @@ void QQuickTextInputPrivate::updateVerticalScroll()
#ifndef QT_NO_IM
const int preeditLength = m_textLayout.preeditAreaText().length();
#endif
- const qreal height = qMax<qreal>(0, q->height());
+ const qreal height = qMax<qreal>(0, q->height() - q->topPadding() - q->bottomPadding());
qreal heightUsed = contentSize.height();
qreal previousScroll = vscroll;
@@ -1879,14 +1714,15 @@ void QQuickTextInput::invalidateFontCaches()
void QQuickTextInput::ensureActiveFocus()
{
- Q_D(QQuickTextInput);
-
bool hadActiveFocus = hasActiveFocus();
forceActiveFocus();
#ifndef QT_NO_IM
+ Q_D(QQuickTextInput);
// re-open input panel on press if already focused
if (hasActiveFocus() && hadActiveFocus && !d->m_readOnly)
qGuiApp->inputMethod()->show();
+#else
+ Q_UNUSED(hadActiveFocus);
#endif
}
@@ -1920,13 +1756,13 @@ QSGNode *QQuickTextInput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
node->deleteContent();
node->setMatrix(QMatrix4x4());
- QPointF offset(0, 0);
+ QPointF offset(leftPadding(), topPadding());
if (d->autoScroll && d->m_textLayout.lineCount() > 0) {
QFontMetricsF fm(d->font);
// the y offset is there to keep the baseline constant in case we have script changes in the text.
- offset = -QPointF(d->hscroll, d->vscroll + d->m_textLayout.lineAt(0).ascent() - fm.ascent());
+ offset += -QPointF(d->hscroll, d->vscroll + d->m_textLayout.lineAt(0).ascent() - fm.ascent());
} else {
- offset = -QPointF(d->hscroll, d->vscroll);
+ offset += -QPointF(d->hscroll, d->vscroll);
}
if (!d->m_textLayout.text().isEmpty()
@@ -2672,6 +2508,19 @@ bool QQuickTextInput::isInputMethodComposing() const
#endif
}
+QQuickTextInputPrivate::ExtraData::ExtraData()
+ : padding(0)
+ , topPadding(0)
+ , leftPadding(0)
+ , rightPadding(0)
+ , bottomPadding(0)
+ , explicitTopPadding(false)
+ , explicitLeftPadding(false)
+ , explicitRightPadding(false)
+ , explicitBottomPadding(false)
+{
+}
+
void QQuickTextInputPrivate::init()
{
Q_Q(QQuickTextInput);
@@ -2882,7 +2731,7 @@ qreal QQuickTextInputPrivate::getImplicitWidth() const
QTextLine line = layout.createLine();
line.setLineWidth(INT_MAX);
- d->implicitWidth = qCeil(line.naturalTextWidth());
+ d->implicitWidth = qCeil(line.naturalTextWidth()) + q->leftPadding() + q->rightPadding();
layout.endLayout();
}
@@ -2890,6 +2739,62 @@ qreal QQuickTextInputPrivate::getImplicitWidth() const
return implicitWidth;
}
+void QQuickTextInputPrivate::setTopPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickTextInput);
+ qreal oldPadding = q->topPadding();
+ if (!reset || extra.isAllocated()) {
+ extra.value().topPadding = value;
+ extra.value().explicitTopPadding = !reset;
+ }
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding()))) {
+ updateLayout();
+ emit q->topPaddingChanged();
+ }
+}
+
+void QQuickTextInputPrivate::setLeftPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickTextInput);
+ qreal oldPadding = q->leftPadding();
+ if (!reset || extra.isAllocated()) {
+ extra.value().leftPadding = value;
+ extra.value().explicitLeftPadding = !reset;
+ }
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding()))) {
+ updateLayout();
+ emit q->leftPaddingChanged();
+ }
+}
+
+void QQuickTextInputPrivate::setRightPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickTextInput);
+ qreal oldPadding = q->rightPadding();
+ if (!reset || extra.isAllocated()) {
+ extra.value().rightPadding = value;
+ extra.value().explicitRightPadding = !reset;
+ }
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding()))) {
+ updateLayout();
+ emit q->rightPaddingChanged();
+ }
+}
+
+void QQuickTextInputPrivate::setBottomPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickTextInput);
+ qreal oldPadding = q->bottomPadding();
+ if (!reset || extra.isAllocated()) {
+ extra.value().bottomPadding = value;
+ extra.value().explicitBottomPadding = !reset;
+ }
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding()))) {
+ updateLayout();
+ emit q->bottomPaddingChanged();
+ }
+}
+
void QQuickTextInputPrivate::updateLayout()
{
Q_Q(QQuickTextInput);
@@ -2915,12 +2820,12 @@ void QQuickTextInputPrivate::updateLayout()
line.setLineWidth(INT_MAX);
const bool wasInLayout = inLayout;
inLayout = true;
- q->setImplicitWidth(qCeil(line.naturalTextWidth()));
+ q->setImplicitWidth(qCeil(line.naturalTextWidth()) + q->leftPadding() + q->rightPadding());
inLayout = wasInLayout;
if (inLayout) // probably the result of a binding loop, but by letting it
return; // get this far we'll get a warning to that effect.
}
- qreal lineWidth = q->widthValid() ? q->width() : INT_MAX;
+ qreal lineWidth = q->widthValid() ? q->width() - q->leftPadding() - q->rightPadding() : INT_MAX;
qreal height = 0;
qreal width = 0;
do {
@@ -2947,9 +2852,9 @@ void QQuickTextInputPrivate::updateLayout()
q->update();
if (!requireImplicitWidth && !q->widthValid())
- q->setImplicitSize(width, height);
+ q->setImplicitSize(width + q->leftPadding() + q->rightPadding(), height + q->topPadding() + q->bottomPadding());
else
- q->setImplicitHeight(height);
+ q->setImplicitHeight(height + q->topPadding() + q->bottomPadding());
updateBaselineOffset();
@@ -2971,13 +2876,13 @@ void QQuickTextInputPrivate::updateBaselineOffset()
QFontMetricsF fm(font);
qreal yoff = 0;
if (q->heightValid()) {
- const qreal surplusHeight = q->height() - contentSize.height();
+ const qreal surplusHeight = q->height() - contentSize.height() - q->topPadding() - q->bottomPadding();
if (vAlign == QQuickTextInput::AlignBottom)
yoff = surplusHeight;
else if (vAlign == QQuickTextInput::AlignVCenter)
yoff = surplusHeight/2;
}
- q->setBaselineOffset(fm.ascent() + yoff);
+ q->setBaselineOffset(fm.ascent() + yoff + q->topPadding());
}
#ifndef QT_NO_CLIPBOARD
@@ -3345,7 +3250,7 @@ void QQuickTextInputPrivate::processInputMethodEvent(QInputMethodEvent *event)
m_preeditCursor = event->preeditString().length();
hasImState = !event->preeditString().isEmpty();
bool cursorVisible = true;
- QList<QTextLayout::FormatRange> formats;
+ QVector<QTextLayout::FormatRange> formats;
for (int i = 0; i < event->attributes().size(); ++i) {
const QInputMethodEvent::Attribute &a = event->attributes().at(i);
if (a.type == QInputMethodEvent::Cursor) {
@@ -3364,7 +3269,7 @@ void QQuickTextInputPrivate::processInputMethodEvent(QInputMethodEvent *event)
}
}
}
- m_textLayout.setAdditionalFormats(formats);
+ m_textLayout.setFormats(formats);
updateDisplayText(/*force*/ true);
if ((cursorPositionChanged && !emitCursorPositionChanged())
@@ -4273,6 +4178,21 @@ void QQuickTextInputPrivate::processKeyEvent(QKeyEvent* event)
return;
}
+ if (m_blinkPeriod > 0) {
+ if (m_blinkTimer)
+ q->killTimer(m_blinkTimer);
+
+ m_blinkTimer = q->startTimer(m_blinkPeriod / 2);
+
+ if (m_blinkStatus == 0) {
+ m_blinkStatus = 1;
+
+ updateType = UpdatePaintNode;
+ q->polish();
+ q->update();
+ }
+ }
+
if (m_echoMode == QQuickTextInput::PasswordEchoOnEdit
&& !m_passwordEchoEditing
&& !m_readOnly
@@ -4508,5 +4428,126 @@ void QQuickTextInput::ensureVisible(int position)
updateCursorRectangle(false);
}
+/*!
+ \since 5.6
+ \qmlproperty real QtQuick::TextInput::padding
+ \qmlproperty real QtQuick::TextInput::topPadding
+ \qmlproperty real QtQuick::TextInput::leftPadding
+ \qmlproperty real QtQuick::TextInput::bottomPadding
+ \qmlproperty real QtQuick::TextInput::rightPadding
+
+ These properties hold the padding around the content. This space is reserved
+ in addition to the contentWidth and contentHeight.
+*/
+qreal QQuickTextInput::padding() const
+{
+ Q_D(const QQuickTextInput);
+ return d->padding();
+}
+
+void QQuickTextInput::setPadding(qreal padding)
+{
+ Q_D(QQuickTextInput);
+ if (qFuzzyCompare(d->padding(), padding))
+ return;
+
+ d->extra.value().padding = padding;
+ d->updateLayout();
+ emit paddingChanged();
+ if (!d->extra.isAllocated() || !d->extra->explicitTopPadding)
+ emit topPaddingChanged();
+ if (!d->extra.isAllocated() || !d->extra->explicitLeftPadding)
+ emit leftPaddingChanged();
+ if (!d->extra.isAllocated() || !d->extra->explicitRightPadding)
+ emit rightPaddingChanged();
+ if (!d->extra.isAllocated() || !d->extra->explicitBottomPadding)
+ emit bottomPaddingChanged();
+}
+
+void QQuickTextInput::resetPadding()
+{
+ setPadding(0);
+}
+
+qreal QQuickTextInput::topPadding() const
+{
+ Q_D(const QQuickTextInput);
+ if (d->extra.isAllocated() && d->extra->explicitTopPadding)
+ return d->extra->topPadding;
+ return d->padding();
+}
+
+void QQuickTextInput::setTopPadding(qreal padding)
+{
+ Q_D(QQuickTextInput);
+ d->setTopPadding(padding);
+}
+
+void QQuickTextInput::resetTopPadding()
+{
+ Q_D(QQuickTextInput);
+ d->setTopPadding(0, true);
+}
+
+qreal QQuickTextInput::leftPadding() const
+{
+ Q_D(const QQuickTextInput);
+ if (d->extra.isAllocated() && d->extra->explicitLeftPadding)
+ return d->extra->leftPadding;
+ return d->padding();
+}
+
+void QQuickTextInput::setLeftPadding(qreal padding)
+{
+ Q_D(QQuickTextInput);
+ d->setLeftPadding(padding);
+}
+
+void QQuickTextInput::resetLeftPadding()
+{
+ Q_D(QQuickTextInput);
+ d->setLeftPadding(0, true);
+}
+
+qreal QQuickTextInput::rightPadding() const
+{
+ Q_D(const QQuickTextInput);
+ if (d->extra.isAllocated() && d->extra->explicitRightPadding)
+ return d->extra->rightPadding;
+ return d->padding();
+}
+
+void QQuickTextInput::setRightPadding(qreal padding)
+{
+ Q_D(QQuickTextInput);
+ d->setRightPadding(padding);
+}
+
+void QQuickTextInput::resetRightPadding()
+{
+ Q_D(QQuickTextInput);
+ d->setRightPadding(0, true);
+}
+
+qreal QQuickTextInput::bottomPadding() const
+{
+ Q_D(const QQuickTextInput);
+ if (d->extra.isAllocated() && d->extra->explicitBottomPadding)
+ return d->extra->bottomPadding;
+ return d->padding();
+}
+
+void QQuickTextInput::setBottomPadding(qreal padding)
+{
+ Q_D(QQuickTextInput);
+ d->setBottomPadding(padding);
+}
+
+void QQuickTextInput::resetBottomPadding()
+{
+ Q_D(QQuickTextInput);
+ d->setBottomPadding(0, true);
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/items/qquicktextinput_p.h b/src/quick/items/qquicktextinput_p.h
index 3bcbe0fa25..b91149f5f3 100644
--- a/src/quick/items/qquicktextinput_p.h
+++ b/src/quick/items/qquicktextinput_p.h
@@ -45,13 +45,6 @@ class QValidator;
class Q_QUICK_PRIVATE_EXPORT QQuickTextInput : public QQuickImplicitSizeItem
{
Q_OBJECT
- Q_ENUMS(HAlignment)
- Q_ENUMS(VAlignment)
- Q_ENUMS(WrapMode)
- Q_ENUMS(EchoMode)
- Q_ENUMS(SelectionMode)
- Q_ENUMS(CursorPosition)
- Q_ENUMS(RenderType)
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
Q_PROPERTY(int length READ length NOTIFY textChanged)
@@ -96,6 +89,12 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTextInput : public QQuickImplicitSizeItem
Q_PROPERTY(qreal contentHeight READ contentHeight NOTIFY contentSizeChanged)
Q_PROPERTY(RenderType renderType READ renderType WRITE setRenderType NOTIFY renderTypeChanged)
+ Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION 6)
+ Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6)
+
public:
QQuickTextInput(QQuickItem * parent=0);
~QQuickTextInput();
@@ -108,18 +107,21 @@ public:
Password,
PasswordEchoOnEdit
};
+ Q_ENUM(EchoMode)
enum HAlignment {
AlignLeft = Qt::AlignLeft,
AlignRight = Qt::AlignRight,
AlignHCenter = Qt::AlignHCenter
};
+ Q_ENUM(HAlignment)
enum VAlignment {
AlignTop = Qt::AlignTop,
AlignBottom = Qt::AlignBottom,
AlignVCenter = Qt::AlignVCenter
};
+ Q_ENUM(VAlignment)
enum WrapMode {
NoWrap = QTextOption::NoWrap,
@@ -128,20 +130,24 @@ public:
WrapAtWordBoundaryOrAnywhere = QTextOption::WrapAtWordBoundaryOrAnywhere, // COMPAT
Wrap = QTextOption::WrapAtWordBoundaryOrAnywhere
};
+ Q_ENUM(WrapMode)
enum SelectionMode {
SelectCharacters,
SelectWords
};
+ Q_ENUM(SelectionMode)
enum CursorPosition {
CursorBetweenCharacters,
CursorOnCharacter
};
+ Q_ENUM(CursorPosition)
enum RenderType { QtRendering,
NativeRendering
};
+ Q_ENUM(RenderType)
//Auxilliary functions needed to control the TextInput from QML
Q_INVOKABLE void positionAt(QQmlV4Function *args) const;
@@ -260,6 +266,26 @@ public:
qreal contentWidth() const;
qreal contentHeight() const;
+ qreal padding() const;
+ void setPadding(qreal padding);
+ void resetPadding();
+
+ qreal topPadding() const;
+ void setTopPadding(qreal padding);
+ void resetTopPadding();
+
+ qreal leftPadding() const;
+ void setLeftPadding(qreal padding);
+ void resetLeftPadding();
+
+ qreal rightPadding() const;
+ void setRightPadding(qreal padding);
+ void resetRightPadding();
+
+ qreal bottomPadding() const;
+ void setBottomPadding(qreal padding);
+ void resetBottomPadding();
+
Q_SIGNALS:
void textChanged();
void cursorPositionChanged();
@@ -300,12 +326,19 @@ Q_SIGNALS:
void contentSizeChanged();
void inputMethodHintsChanged();
void renderTypeChanged();
+ Q_REVISION(6) void paddingChanged();
+ Q_REVISION(6) void topPaddingChanged();
+ Q_REVISION(6) void leftPaddingChanged();
+ Q_REVISION(6) void rightPaddingChanged();
+ Q_REVISION(6) void bottomPaddingChanged();
private:
void invalidateFontCaches();
void ensureActiveFocus();
protected:
+ QQuickTextInput(QQuickTextInputPrivate &dd, QQuickItem *parent = 0);
+
void geometryChanged(const QRectF &newGeometry,
const QRectF &oldGeometry) Q_DECL_OVERRIDE;
@@ -360,46 +393,8 @@ private:
Q_DECLARE_PRIVATE(QQuickTextInput)
};
-#ifndef QT_NO_VALIDATOR
-class Q_AUTOTEST_EXPORT QQuickIntValidator : public QIntValidator
-{
- Q_OBJECT
- Q_PROPERTY(QString locale READ localeName WRITE setLocaleName RESET resetLocaleName NOTIFY localeNameChanged)
-public:
- QQuickIntValidator(QObject *parent = 0);
-
- QString localeName() const;
- void setLocaleName(const QString &name);
- void resetLocaleName();
-
-Q_SIGNALS:
- void localeNameChanged();
-};
-
-class Q_AUTOTEST_EXPORT QQuickDoubleValidator : public QDoubleValidator
-{
- Q_OBJECT
- Q_PROPERTY(QString locale READ localeName WRITE setLocaleName RESET resetLocaleName NOTIFY localeNameChanged)
-public:
- QQuickDoubleValidator(QObject *parent = 0);
-
- QString localeName() const;
- void setLocaleName(const QString &name);
- void resetLocaleName();
-
-Q_SIGNALS:
- void localeNameChanged();
-};
-#endif
-
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickTextInput)
-#ifndef QT_NO_VALIDATOR
-QML_DECLARE_TYPE(QValidator)
-QML_DECLARE_TYPE(QQuickIntValidator)
-QML_DECLARE_TYPE(QQuickDoubleValidator)
-QML_DECLARE_TYPE(QRegExpValidator)
-#endif
#endif // QQUICKTEXTINPUT_P_H
diff --git a/src/quick/items/qquicktextinput_p_p.h b/src/quick/items/qquicktextinput_p_p.h
index 3038573bb3..cf0a6f5273 100644
--- a/src/quick/items/qquicktextinput_p_p.h
+++ b/src/quick/items/qquicktextinput_p_p.h
@@ -47,6 +47,7 @@
#include <QtGui/qpalette.h>
#include <QtGui/qtextlayout.h>
#include <QtGui/qstylehints.h>
+#include <private/qlazilyallocated_p.h>
#include "qplatformdefs.h"
@@ -64,13 +65,28 @@ QT_BEGIN_NAMESPACE
class QQuickTextNode;
-class Q_AUTOTEST_EXPORT QQuickTextInputPrivate : public QQuickImplicitSizeItemPrivate
+class Q_QUICK_PRIVATE_EXPORT QQuickTextInputPrivate : public QQuickImplicitSizeItemPrivate
{
public:
Q_DECLARE_PUBLIC(QQuickTextInput)
typedef QQuickTextInput Public;
+ struct ExtraData {
+ ExtraData();
+
+ qreal padding;
+ qreal topPadding;
+ qreal leftPadding;
+ qreal rightPadding;
+ qreal bottomPadding;
+ bool explicitTopPadding : 1;
+ bool explicitLeftPadding : 1;
+ bool explicitRightPadding : 1;
+ bool explicitBottomPadding : 1;
+ };
+ QLazilyAllocated<ExtraData> extra;
+
QQuickTextInputPrivate()
: hscroll(0)
, vscroll(0)
@@ -420,6 +436,12 @@ public:
qreal getImplicitWidth() const Q_DECL_OVERRIDE;
+ inline qreal padding() const { return extra.isAllocated() ? extra->padding : 0.0; }
+ void setTopPadding(qreal value, bool reset = false);
+ void setLeftPadding(qreal value, bool reset = false);
+ void setRightPadding(qreal value, bool reset = false);
+ void setBottomPadding(qreal value, bool reset = false);
+
private:
void removeSelectedText();
void internalSetText(const QString &txt, int pos = -1, bool edited = true);
diff --git a/src/quick/items/qquicktextnode.cpp b/src/quick/items/qquicktextnode.cpp
index 010a443d18..d40dedd798 100644
--- a/src/quick/items/qquicktextnode.cpp
+++ b/src/quick/items/qquicktextnode.cpp
@@ -186,17 +186,6 @@ void QQuickTextNode::clearCursor()
m_cursorNode = 0;
}
-void QQuickTextNode::initEngine(const QColor& textColor, const QColor& selectedTextColor, const QColor& selectionColor, const QColor& anchorColor, const QPointF &position)
-{
- m_engine.reset(new QQuickTextNodeEngine);
- m_engine->m_hasContents = false;
- m_engine->setTextColor(textColor);
- m_engine->setSelectedTextColor(selectedTextColor);
- m_engine->setSelectionColor(selectionColor);
- m_engine->setAnchorColor(anchorColor);
- m_engine->setPosition(position);
-}
-
void QQuickTextNode::addRectangleNode(const QRectF &rect, const QColor &color)
{
QSGRenderContext *sg = QQuickItemPrivate::get(m_ownerElement)->sceneGraphRenderContext();
@@ -224,7 +213,12 @@ void QQuickTextNode::addTextDocument(const QPointF &position, QTextDocument *tex
const QColor &selectionColor, const QColor &selectedTextColor,
int selectionStart, int selectionEnd)
{
- initEngine(textColor, selectedTextColor, selectionColor, anchorColor);
+ QQuickTextNodeEngine engine;
+ engine.setTextColor(textColor);
+ engine.setSelectedTextColor(selectedTextColor);
+ engine.setSelectionColor(selectionColor);
+ engine.setAnchorColor(anchorColor);
+ engine.setPosition(position);
QList<QTextFrame *> frames;
frames.append(textDocument->rootFrame());
@@ -232,7 +226,7 @@ void QQuickTextNode::addTextDocument(const QPointF &position, QTextDocument *tex
QTextFrame *textFrame = frames.takeFirst();
frames.append(textFrame->childFrames());
- m_engine->addFrameDecorations(textDocument, textFrame);
+ engine.addFrameDecorations(textDocument, textFrame);
if (textFrame->firstPosition() > textFrame->lastPosition()
&& textFrame->frameFormat().position() != QTextFrameFormat::InFlow) {
@@ -242,23 +236,23 @@ void QQuickTextNode::addTextDocument(const QPointF &position, QTextDocument *tex
QRectF rect = a->frameBoundingRect(textFrame);
QTextBlock block = textFrame->firstCursorPosition().block();
- m_engine->setCurrentLine(block.layout()->lineForTextPosition(pos - block.position()));
- m_engine->addTextObject(rect.topLeft(), format, QQuickTextNodeEngine::Unselected, textDocument,
+ engine.setCurrentLine(block.layout()->lineForTextPosition(pos - block.position()));
+ engine.addTextObject(rect.topLeft(), format, QQuickTextNodeEngine::Unselected, textDocument,
pos, textFrame->frameFormat().position());
} else {
QTextFrame::iterator it = textFrame->begin();
while (!it.atEnd()) {
- Q_ASSERT(!m_engine->currentLine().isValid());
+ Q_ASSERT(!engine.currentLine().isValid());
QTextBlock block = it.currentBlock();
- m_engine->addTextBlock(textDocument, block, position, textColor, anchorColor, selectionStart, selectionEnd);
+ engine.addTextBlock(textDocument, block, position, textColor, anchorColor, selectionStart, selectionEnd);
++it;
}
}
}
- m_engine->addToSceneGraph(this, style, styleColor);
+ engine.addToSceneGraph(this, style, styleColor);
}
void QQuickTextNode::addTextLayout(const QPointF &position, QTextLayout *textLayout, const QColor &color,
@@ -268,7 +262,12 @@ void QQuickTextNode::addTextLayout(const QPointF &position, QTextLayout *textLay
int selectionStart, int selectionEnd,
int lineStart, int lineCount)
{
- initEngine(color, selectedTextColor, selectionColor, anchorColor, position);
+ QQuickTextNodeEngine engine;
+ engine.setTextColor(color);
+ engine.setSelectedTextColor(selectedTextColor);
+ engine.setSelectionColor(selectionColor);
+ engine.setAnchorColor(anchorColor);
+ engine.setPosition(position);
#ifndef QT_NO_IM
int preeditLength = textLayout->preeditAreaText().length();
@@ -276,7 +275,7 @@ void QQuickTextNode::addTextLayout(const QPointF &position, QTextLayout *textLay
#endif
QVarLengthArray<QTextLayout::FormatRange> colorChanges;
- m_engine->mergeFormats(textLayout, &colorChanges);
+ engine.mergeFormats(textLayout, &colorChanges);
lineCount = lineCount >= 0
? qMin(lineStart + lineCount, textLayout->lineCount())
@@ -297,11 +296,11 @@ void QQuickTextNode::addTextLayout(const QPointF &position, QTextLayout *textLay
}
#endif
- m_engine->setCurrentLine(line);
- m_engine->addGlyphsForRanges(colorChanges, start, end, selectionStart, selectionEnd);
+ engine.setCurrentLine(line);
+ engine.addGlyphsForRanges(colorChanges, start, end, selectionStart, selectionEnd);
}
- m_engine->addToSceneGraph(this, style, styleColor);
+ engine.addToSceneGraph(this, style, styleColor);
}
void QQuickTextNode::deleteContent()
diff --git a/src/quick/items/qquicktextnode_p.h b/src/quick/items/qquicktextnode_p.h
index c7b9804ea6..31cc23bf2a 100644
--- a/src/quick/items/qquicktextnode_p.h
+++ b/src/quick/items/qquicktextnode_p.h
@@ -101,14 +101,10 @@ public:
void setUseNativeRenderer(bool on) { m_useNativeRenderer = on; }
private:
- void initEngine(const QColor &textColor, const QColor &selectedTextColor, const QColor &selectionColor, const QColor& anchorColor = QColor()
- , const QPointF &position = QPointF());
-
QSGRectangleNode *m_cursorNode;
QList<QSGTexture *> m_textures;
QQuickItem *m_ownerElement;
bool m_useNativeRenderer;
- QScopedPointer<QQuickTextNodeEngine> m_engine;
friend class QQuickTextEdit;
friend class QQuickTextEditPrivate;
diff --git a/src/quick/items/qquicktextnodeengine.cpp b/src/quick/items/qquicktextnodeengine.cpp
index efe79b382e..2b7f94d8bf 100644
--- a/src/quick/items/qquicktextnodeengine.cpp
+++ b/src/quick/items/qquicktextnodeengine.cpp
@@ -882,7 +882,7 @@ void QQuickTextNodeEngine::mergeFormats(QTextLayout *textLayout, QVarLengthArray
if (textLayout == 0)
return;
- QList<QTextLayout::FormatRange> additionalFormats = textLayout->additionalFormats();
+ QVector<QTextLayout::FormatRange> additionalFormats = textLayout->formats();
for (int i=0; i<additionalFormats.size(); ++i) {
QTextLayout::FormatRange additionalFormat = additionalFormats.at(i);
if (additionalFormat.format.hasProperty(QTextFormat::ForegroundBrush)
diff --git a/src/quick/items/qquicktextnodeengine_p.h b/src/quick/items/qquicktextnodeengine_p.h
index 2f6cacf601..f9ebe43183 100644
--- a/src/quick/items/qquicktextnodeengine_p.h
+++ b/src/quick/items/qquicktextnodeengine_p.h
@@ -231,8 +231,6 @@ private:
QList<TextDecoration> m_lines;
QVector<BinaryTreeNode> m_processedNodes;
- QList<QPair<QRectF, QImage> > m_images;
-
bool m_hasSelection : 1;
bool m_hasContents : 1;
friend class QQuickTextNode;
diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp
index 5b5413a4ba..0b3cfa17b5 100644
--- a/src/quick/items/qquickview.cpp
+++ b/src/quick/items/qquickview.cpp
@@ -38,8 +38,9 @@
#include "qquickitem_p.h"
#include "qquickitemchangelistener_p.h"
+#include <private/qqmldebugconnector_p.h>
#include <private/qquickprofiler_p.h>
-#include <private/qqmlinspectorservice_p.h>
+#include <private/qqmldebugserviceinterfaces_p.h>
#include <private/qqmlmemoryprofiler_p.h>
#include <QtQml/qqmlengine.h>
@@ -86,8 +87,9 @@ void QQuickViewPrivate::init(QQmlEngine* e)
rootItemMarker.set(v4, v);
}
- if (QQmlDebugService::isDebuggingEnabled())
- QQmlInspectorService::instance()->addView(q);
+ QQmlInspectorService *service = QQmlDebugConnector::service<QQmlInspectorService>();
+ if (service)
+ service->addView(q);
}
QQuickViewPrivate::QQuickViewPrivate()
@@ -97,8 +99,9 @@ QQuickViewPrivate::QQuickViewPrivate()
QQuickViewPrivate::~QQuickViewPrivate()
{
- if (QQmlDebugService::isDebuggingEnabled())
- QQmlInspectorService::instance()->removeView(q_func());
+ QQmlInspectorService *service = QQmlDebugConnector::service<QQmlInspectorService>();
+ if (service)
+ service->removeView(q_func());
}
void QQuickViewPrivate::execute()
@@ -345,6 +348,9 @@ QQuickView::Status QQuickView::status() const
if (!d->component)
return QQuickView::Null;
+ if (d->component->status() == QQmlComponent::Ready && !d->root)
+ return QQuickView::Error;
+
return QQuickView::Status(d->component->status());
}
@@ -364,6 +370,10 @@ QList<QQmlError> QQuickView::errors() const
QQmlError error;
error.setDescription(QLatin1String("QQuickView: invalid qml engine."));
errs << error;
+ } else if (d->component->status() == QQmlComponent::Ready && !d->root) {
+ QQmlError error;
+ error.setDescription(QLatin1String("QQuickView: invalid root object."));
+ errs << error;
}
return errs;
@@ -501,14 +511,15 @@ void QQuickViewPrivate::setRootObject(QObject *obj)
if (QQuickItem *sgItem = qobject_cast<QQuickItem *>(obj)) {
root = sgItem;
sgItem->setParentItem(q->QQuickWindow::contentItem());
+ } else if (qobject_cast<QWindow *>(obj)) {
+ qWarning() << "QQuickView does not support using windows as a root item." << endl
+ << endl
+ << "If you wish to create your root window from QML, consider using QQmlApplicationEngine instead." << endl;
} else {
qWarning() << "QQuickView only supports loading of root objects that derive from QQuickItem." << endl
<< endl
- << "If your example is using QML 2, (such as qmlscene) and the .qml file you" << endl
- << "loaded has 'import QtQuick 1.0' or 'import Qt 4.7', this error will occur." << endl
- << endl
- << "To load files with 'import QtQuick 1.0' or 'import Qt 4.7', use the" << endl
- << "QDeclarativeView class in the Qt Quick 1 module." << endl;
+ << "Ensure your QML code is written for QtQuick 2, and uses a root that is or" << endl
+ << "inherits from QtQuick's Item (not a Timer, QtObject, etc)." << endl;
delete obj;
root = 0;
}
diff --git a/src/quick/items/qquickview.h b/src/quick/items/qquickview.h
index f094c5a216..80da0ba4f1 100644
--- a/src/quick/items/qquickview.h
+++ b/src/quick/items/qquickview.h
@@ -53,7 +53,6 @@ class Q_QUICK_EXPORT QQuickView : public QQuickWindow
Q_PROPERTY(ResizeMode resizeMode READ resizeMode WRITE setResizeMode)
Q_PROPERTY(Status status READ status NOTIFY statusChanged)
Q_PROPERTY(QUrl source READ source WRITE setSource DESIGNABLE true)
- Q_ENUMS(ResizeMode Status)
public:
explicit QQuickView(QWindow *parent = 0);
QQuickView(QQmlEngine* engine, QWindow *parent);
@@ -68,10 +67,12 @@ public:
QQuickItem *rootObject() const;
enum ResizeMode { SizeViewToRootObject, SizeRootObjectToView };
+ Q_ENUM(ResizeMode)
ResizeMode resizeMode() const;
void setResizeMode(ResizeMode);
enum Status { Null, Ready, Loading, Error };
+ Q_ENUM(Status)
Status status() const;
QList<QQmlError> errors() const;
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 5958edf29f..99dbf1d83e 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -64,7 +64,6 @@
#include <QtQuick/private/qquickpixmapcache_p.h>
-#include <private/qqmlprofilerservice_p.h>
#include <private/qqmlmemoryprofiler_p.h>
#include <private/qopenglvertexarrayobject_p.h>
@@ -83,8 +82,8 @@ bool QQuickWindowPrivate::defaultAlphaBuffer = false;
void QQuickWindowPrivate::updateFocusItemTransform()
{
- Q_Q(QQuickWindow);
#ifndef QT_NO_IM
+ Q_Q(QQuickWindow);
QQuickItem *focus = q->activeFocusItem();
if (focus && QGuiApplication::focusObject() == focus) {
QQuickItemPrivate *focusPrivate = QQuickItemPrivate::get(focus);
@@ -259,8 +258,7 @@ void QQuickWindowPrivate::polishItems()
// the user.
int recursionSafeguard = INT_MAX;
while (!itemsToPolish.isEmpty() && --recursionSafeguard > 0) {
- QQuickItem *item = *itemsToPolish.begin();
- itemsToPolish.remove(item);
+ QQuickItem *item = itemsToPolish.takeLast();
QQuickItemPrivate::get(item)->polishScheduled = false;
item->updatePolish();
}
@@ -2385,7 +2383,9 @@ bool QQuickWindowPrivate::sendFilteredTouchEvent(QQuickItem *target, QQuickItem
if (target->childMouseEventFilter(item, targetEvent.data())) {
qCDebug(DBG_TOUCH) << " - first chance intercepted on childMouseEventFilter by " << target;
QVector<int> touchIds;
- for (int i = 0; i < targetEvent->touchPoints().size(); ++i)
+ const int touchPointCount = targetEvent->touchPoints().size();
+ touchIds.reserve(touchPointCount);
+ for (int i = 0; i < touchPointCount; ++i)
touchIds.append(targetEvent->touchPoints().at(i).id());
target->grabTouchPoints(touchIds);
if (mouseGrabberItem) {
@@ -2729,7 +2729,7 @@ static inline QSGNode *qquickitem_before_paintNode(QQuickItemPrivate *d)
QQuickItem *before = 0;
for (int i=0; i<childItems.size(); ++i) {
QQuickItemPrivate *dd = QQuickItemPrivate::get(childItems.at(i));
- // Perform the same check as the in buildOrderNodeList below.
+ // Perform the same check as the in fetchNextNode below.
if (dd->z() < 0 && (dd->explicitVisible || (dd->extra.isAllocated() && dd->extra->effectRefCount)))
before = childItems.at(i);
else
@@ -2738,13 +2738,9 @@ static inline QSGNode *qquickitem_before_paintNode(QQuickItemPrivate *d)
return Q_UNLIKELY(before) ? QQuickItemPrivate::get(before)->itemNode() : 0;
}
-static QVector<QSGNode *> buildOrderedNodeList(QQuickItemPrivate *itemPriv)
+static QSGNode *fetchNextNode(QQuickItemPrivate *itemPriv, int &ii, bool &returnedPaintNode)
{
QList<QQuickItem *> orderedChildren = itemPriv->paintOrderChildItems();
- QVector<QSGNode *> desiredNodes;
- desiredNodes.reserve(orderedChildren.size() + 1); // + 1 for the paintNode
-
- int ii = 0;
for (; ii < orderedChildren.count() && orderedChildren.at(ii)->z() < 0; ++ii) {
QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(orderedChildren.at(ii));
@@ -2752,11 +2748,14 @@ static QVector<QSGNode *> buildOrderedNodeList(QQuickItemPrivate *itemPriv)
(!childPrivate->extra.isAllocated() || !childPrivate->extra->effectRefCount))
continue;
- desiredNodes.append(childPrivate->itemNode());
+ ii++;
+ return childPrivate->itemNode();
}
- if (itemPriv->paintNode)
- desiredNodes.append(itemPriv->paintNode);
+ if (itemPriv->paintNode && !returnedPaintNode) {
+ returnedPaintNode = true;
+ return itemPriv->paintNode;
+ }
for (; ii < orderedChildren.count(); ++ii) {
QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(orderedChildren.at(ii));
@@ -2764,10 +2763,11 @@ static QVector<QSGNode *> buildOrderedNodeList(QQuickItemPrivate *itemPriv)
(!childPrivate->extra.isAllocated() || !childPrivate->extra->effectRefCount))
continue;
- desiredNodes.append(childPrivate->itemNode());
+ ii++;
+ return childPrivate->itemNode();
}
- return desiredNodes;
+ return 0;
}
void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item)
@@ -2870,7 +2870,10 @@ void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item)
}
if (dirty & QQuickItemPrivate::ChildrenUpdateMask) {
- QVector<QSGNode *> desiredNodes = buildOrderedNodeList(itemPriv);
+ int ii = 0;
+ bool fetchedPaintNode = false;
+ QList<QQuickItem *> orderedChildren = itemPriv->paintOrderChildItems();
+ int desiredNodesSize = orderedChildren.size() + (itemPriv->paintNode ? 1 : 0);
// now start making current state match the promised land of
// desiredNodes. in the case of our current state matching desiredNodes
@@ -2888,14 +2891,9 @@ void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item)
int added = 0;
int removed = 0;
int replaced = 0;
-#if defined(CHILDRENUPDATE_DEBUG)
- // This is slow! Do not do this in a normal/profiling build!
- int initialCount = groupNode->childCount();
-#endif
-
- while (currentNode && desiredNodesProcessed < desiredNodes.size()) {
- QSGNode *desiredNode = desiredNodes.at(desiredNodesProcessed);
+ QSGNode *desiredNode = 0;
+ while (currentNode && (desiredNode = fetchNextNode(itemPriv, ii, fetchedPaintNode))) {
// uh oh... reality and our utopic paradise are diverging!
// we need to reconcile this...
if (currentNode != desiredNode) {
@@ -2919,9 +2917,8 @@ void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item)
// if we didn't process as many nodes as in the new list, then we have
// more nodes at the end of desiredNodes to append to our list.
// this will be the case when adding new nodes, for instance.
- if (desiredNodesProcessed < desiredNodes.size()) {
- for (int i = desiredNodesProcessed; i < desiredNodes.size(); ++i) {
- QSGNode *desiredNode = desiredNodes.at(i);
+ if (desiredNodesProcessed < desiredNodesSize) {
+ while ((desiredNode = fetchNextNode(itemPriv, ii, fetchedPaintNode))) {
if (desiredNode->parent())
desiredNode->parent()->removeChildNode(desiredNode);
groupNode->appendChildNode(desiredNode);
@@ -2938,10 +2935,6 @@ void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item)
removed++;
}
}
-
-#if defined(CHILDRENUPDATE_DEBUG)
- qDebug() << "Done children update for " << itemPriv << "- before:" << initialCount << "after:" << groupNode->childCount() << "added:" << added << "removed:" << removed << "replaced:" << replaced;
-#endif
}
if ((dirty & QQuickItemPrivate::Size) && itemPriv->clipNode()) {
@@ -3307,12 +3300,7 @@ QOpenGLFramebufferObject *QQuickWindow::renderTarget() const
QImage QQuickWindow::grabWindow()
{
Q_D(QQuickWindow);
- if (!isVisible()) {
-
- if (d->context->openglContext()) {
- qWarning("QQuickWindow::grabWindow: scene graph already in use");
- return QImage();
- }
+ if (!isVisible() && !d->context->openglContext()) {
if (!handle() || !size().isValid()) {
qWarning("QQuickWindow::grabWindow: window must be created and have a valid size");
@@ -3382,6 +3370,11 @@ QQmlIncubationController *QQuickWindow::incubationController() const
will delete the GL texture when the texture object is deleted.
\value TextureCanUseAtlas The image can be uploaded into a texture atlas.
+
+ \value TextureIsOpaque The texture will return false for
+ QSGTexture::hasAlphaChannel() and will not be blended. This flag was added
+ in Qt 5.6.
+
*/
/*!
@@ -3586,12 +3579,21 @@ QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image) const
The caller of the function is responsible for deleting the returned texture.
The actual GL texture will be deleted when the texture object is deleted.
- When \a options contains TextureCanUseAtlas the engine may put the image
+ When \a options contains TextureCanUseAtlas, the engine may put the image
into a texture atlas. Textures in an atlas need to rely on
QSGTexture::normalizedTextureSubRect() for their geometry and will not
support QSGTexture::Repeat. Other values from CreateTextureOption are
ignored.
+ When \a options contains TextureIsOpaque, the engine will create an RGB
+ texture which returns false for QSGTexture::hasAlphaChannel(). Opaque
+ textures will in most cases be faster to render. When this flag is not set,
+ the texture will have an alpha channel based on the image's format.
+
+ When \a options contains TextureHasMipmaps, the engine will create a
+ texture which can use mipmap filtering. Mipmapped textures can not be in
+ an atlas.
+
The returned texture will be using \c GL_TEXTURE_2D as texture target and
\c GL_RGBA as internal format. Reimplement QSGTexture to create textures
with different parameters.
@@ -3613,14 +3615,13 @@ QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image) const
QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image, CreateTextureOptions options) const
{
Q_D(const QQuickWindow);
- if (d->context) {
- if (options & TextureCanUseAtlas)
- return d->context->createTexture(image);
- else
- return d->context->createTextureNoAtlas(image);
- }
- else
- return 0;
+ if (!d->context)
+ return 0;
+ uint flags = 0;
+ if (options & TextureCanUseAtlas) flags |= QSGRenderContext::CreateTexture_Atlas;
+ if (options & TextureHasMipmaps) flags |= QSGRenderContext::CreateTexture_Mipmap;
+ if (!(options & TextureIsOpaque)) flags |= QSGRenderContext::CreateTexture_Alpha;
+ return d->context->createTexture(image, flags);
}
@@ -4115,6 +4116,7 @@ void QQuickWindow::resetOpenGLState()
\value BeforeRenderingStage Before rendering.
\value AfterRenderingStage After rendering.
\value AfterSwapStage After the frame is swapped.
+ \value NoStage As soon as possible. This value was added in Qt 5.6.
\sa {Scene Graph and Rendering}
*/
@@ -4140,8 +4142,17 @@ void QQuickWindow::resetOpenGLState()
If the rendering is happening on a different thread, then the job
will happen on the rendering thread.
- \note This function does not trigger rendering; the job
- will be stored run until rendering is triggered elsewhere.
+ If \a stage is \l NoStage, \a job will be run at the earliest opportunity
+ whenever the render thread is not busy rendering a frame. If there is no
+ OpenGL context available or the window is not exposed at the time the job is
+ either posted or handled, it is deleted without executing the run() method.
+ If a non-threaded renderer is in use, the run() method of the job is executed
+ synchronously.
+ The OpenGL context is changed to the renderer context before executing a
+ \l NoStage job.
+
+ \note This function does not trigger rendering; the jobs targeting any other
+ stage than NoStage will be stored run until rendering is triggered elsewhere.
To force the job to run earlier, call QQuickWindow::update();
\sa beforeRendering(), afterRendering(), beforeSynchronizing(),
@@ -4153,16 +4164,22 @@ void QQuickWindow::scheduleRenderJob(QRunnable *job, RenderStage stage)
Q_D(QQuickWindow);
d->renderJobMutex.lock();
- if (stage == BeforeSynchronizingStage)
+ if (stage == BeforeSynchronizingStage) {
d->beforeSynchronizingJobs << job;
- else if (stage == AfterSynchronizingStage)
+ } else if (stage == AfterSynchronizingStage) {
d->afterSynchronizingJobs << job;
- else if (stage == BeforeRenderingStage)
+ } else if (stage == BeforeRenderingStage) {
d->beforeRenderingJobs << job;
- else if (stage == AfterRenderingStage)
+ } else if (stage == AfterRenderingStage) {
d->afterRenderingJobs << job;
- else if (stage == AfterSwapStage)
+ } else if (stage == AfterSwapStage) {
d->afterSwapJobs << job;
+ } else if (stage == NoStage) {
+ if (isExposed())
+ d->windowManager->postJob(this, job);
+ else
+ delete job;
+ }
d->renderJobMutex.unlock();
}
diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h
index f7a1956120..d5bf9fba81 100644
--- a/src/quick/items/qquickwindow.h
+++ b/src/quick/items/qquickwindow.h
@@ -69,7 +69,8 @@ public:
TextureHasAlphaChannel = 0x0001,
TextureHasMipmaps = 0x0002,
TextureOwnsGLTexture = 0x0004,
- TextureCanUseAtlas = 0x0008
+ TextureCanUseAtlas = 0x0008,
+ TextureIsOpaque = 0x0010
};
enum RenderStage {
@@ -77,7 +78,8 @@ public:
AfterSynchronizingStage,
BeforeRenderingStage,
AfterRenderingStage,
- AfterSwapStage
+ AfterSwapStage,
+ NoStage
};
Q_DECLARE_FLAGS(CreateTextureOptions, CreateTextureOption)
@@ -85,7 +87,7 @@ public:
enum SceneGraphError {
ContextNotAvailable = 1
};
- Q_ENUMS(SceneGraphError)
+ Q_ENUM(SceneGraphError)
QQuickWindow(QWindow *parent = 0);
explicit QQuickWindow(QQuickRenderControl *renderControl);
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index 605a36fb1d..0d33d2398a 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -200,7 +200,7 @@ public:
QQuickItem *dirtyItemList;
QList<QSGNode *> cleanupNodeList;
- QSet<QQuickItem *> itemsToPolish;
+ QVector<QQuickItem *> itemsToPolish;
void updateDirtyNodes();
void cleanupNodes();
diff --git a/src/quick/qtquick2.cpp b/src/quick/qtquick2.cpp
index 524ee02952..ecf6865895 100644
--- a/src/quick/qtquick2.cpp
+++ b/src/quick/qtquick2.cpp
@@ -38,7 +38,8 @@
#include <private/qquickitemsmodule_p.h>
#include <private/qquickaccessiblefactory_p.h>
-#include <private/qqmlenginedebugservice_p.h>
+#include <private/qqmldebugconnector_p.h>
+#include <private/qqmldebugserviceinterfaces_p.h>
#include <private/qqmldebugstatesdelegate_p.h>
#include <private/qqmlbinding_p.h>
#include <private/qqmlcontext_p.h>
@@ -133,7 +134,6 @@ void QQmlQtQuick2DebugStatesDelegate::updateBinding(QQmlContext *context,
QQmlContextData::get(context), fileName,
line, column);
newBinding->setTarget(property);
- newBinding->setNotifyOnValueChanged(true);
}
state->changeBindingInRevertList(object, propertyName, newBinding);
@@ -187,11 +187,13 @@ void QQmlQtQuick2Module::defineModule()
QAccessible::installFactory(&qQuickAccessibleFactory);
#endif
- if (QQmlDebugService::isDebuggingEnabled()) {
- QQmlEngineDebugService::instance()->setStatesDelegate(
- new QQmlQtQuick2DebugStatesDelegate);
- QQuickProfiler::initialize();
- }
+ QQmlEngineDebugService *debugService = QQmlDebugConnector::service<QQmlEngineDebugService>();
+ if (debugService)
+ debugService->setStatesDelegate(new QQmlQtQuick2DebugStatesDelegate);
+
+ QQmlProfilerService *profilerService = QQmlDebugConnector::service<QQmlProfilerService>();
+ if (profilerService)
+ QQuickProfiler::initialize(profilerService);
}
void QQmlQtQuick2Module::undefineModule()
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index 42b9f526d0..8632ea0b52 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -198,9 +198,9 @@ ShaderManager::Shader *ShaderManager::prepareMaterialNoRewrite(QSGMaterial *mate
void ShaderManager::invalidated()
{
- qDeleteAll(stockShaders.values());
+ qDeleteAll(stockShaders);
stockShaders.clear();
- qDeleteAll(rewrittenShaders.values());
+ qDeleteAll(rewrittenShaders);
rewrittenShaders.clear();
delete blitProgram;
blitProgram = 0;
@@ -487,6 +487,11 @@ void Updater::visitGeometryNode(Node *n)
if (e->batch)
renderer->invalidateBatchAndOverlappingRenderOrders(e->batch);
}
+ if (n->dirtyState & QSGNode::DirtyMaterial) {
+ Element *e = n->element();
+ if (e->batch && e->batch->isMaterialCompatible(e) == BatchBreaksOnCompare)
+ renderer->invalidateBatchAndOverlappingRenderOrders(e->batch);
+ }
}
SHADOWNODE_TRAVERSE(n) visitNode(*child);
@@ -1081,6 +1086,9 @@ void Renderer::nodeWasRemoved(Node *node)
if (e) {
e->removed = true;
m_elementsToDelete.add(e);
+
+ if (m_renderNodeElements.isEmpty())
+ m_useDepthBuffer = context()->openglContext()->format().depthBufferSize() > 0;
}
}
@@ -1213,10 +1221,7 @@ void Renderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state)
if (e->isMaterialBlended != blended) {
m_rebuild |= Renderer::FullRebuild;
e->isMaterialBlended = blended;
- } else if (e->batch) {
- if (e->batch->isMaterialCompatible(e) == BatchBreaksOnCompare)
- invalidateBatchAndOverlappingRenderOrders(e->batch);
- } else {
+ } else if (!e->batch) {
m_rebuild |= Renderer::BuildBatches;
}
}
@@ -2554,8 +2559,15 @@ void Renderer::render()
QSGNodeDumper::dump(rootNode());
}
- if (Q_UNLIKELY(debug_render() || debug_build())) {
+ QElapsedTimer timer;
+ quint64 timeRenderLists = 0;
+ quint64 timePrepareOpaque = 0;
+ quint64 timePrepareAlpha = 0;
+ quint64 timeSorting = 0;
+ quint64 timeUploadOpaque = 0;
+ quint64 timeUploadAlpha = 0;
+ if (Q_UNLIKELY(debug_render() || debug_build())) {
QByteArray type("rebuild:");
if (m_rebuild == 0)
type += " none";
@@ -2571,6 +2583,7 @@ void Renderer::render()
}
qDebug() << "Renderer::render()" << this << type;
+ timer.start();
}
if (m_vao)
@@ -2597,6 +2610,7 @@ void Renderer::render()
}
}
}
+ if (Q_UNLIKELY(debug_render())) timeRenderLists = timer.restart();
for (int i=0; i<m_opaqueBatches.size(); ++i)
m_opaqueBatches.at(i)->cleanupRemovedElements();
@@ -2609,7 +2623,9 @@ void Renderer::render()
if (m_rebuild & BuildBatches) {
prepareOpaqueBatches();
+ if (Q_UNLIKELY(debug_render())) timePrepareOpaque = timer.restart();
prepareAlphaBatches();
+ if (Q_UNLIKELY(debug_render())) timePrepareAlpha = timer.restart();
if (Q_UNLIKELY(debug_build())) {
qDebug() << "Opaque Batches:";
@@ -2629,8 +2645,11 @@ void Renderer::render()
}
}
}
+ } else {
+ if (Q_UNLIKELY(debug_render())) timePrepareOpaque = timePrepareAlpha = timer.restart();
}
+
deleteRemovedElements();
if (m_rebuild != 0) {
@@ -2646,6 +2665,8 @@ void Renderer::render()
m_zRange = 1.0 / (m_nextRenderOrder);
}
+ if (Q_UNLIKELY(debug_render())) timeSorting = timer.restart();
+
int largestVBO = 0;
#ifdef QSG_SEPARATE_INDEX_BUFFER
int largestIBO = 0;
@@ -2660,6 +2681,8 @@ void Renderer::render()
#endif
uploadBatch(b);
}
+ if (Q_UNLIKELY(debug_render())) timeUploadOpaque = timer.restart();
+
if (Q_UNLIKELY(debug_upload())) qDebug() << "Uploading Alpha Batches:";
for (int i=0; i<m_alphaBatches.size(); ++i) {
@@ -2670,6 +2693,7 @@ void Renderer::render()
largestIBO = qMax(b->ibo.size, largestIBO);
#endif
}
+ if (Q_UNLIKELY(debug_render())) timeUploadAlpha = timer.restart();
if (largestVBO * 2 < m_vertexUploadPool.size())
m_vertexUploadPool.resize(largestVBO * 2);
@@ -2680,6 +2704,15 @@ void Renderer::render()
renderBatches();
+ if (Q_UNLIKELY(debug_render())) {
+ qDebug(" -> times: build: %d, prepare(opaque/alpha): %d/%d, sorting: %d, upload(opaque/alpha): %d/%d, render: %d",
+ (int) timeRenderLists,
+ (int) timePrepareOpaque, (int) timePrepareAlpha,
+ (int) timeSorting,
+ (int) timeUploadOpaque, (int) timeUploadAlpha,
+ (int) timer.elapsed());
+ }
+
m_rebuild = 0;
m_renderOrderRebuildLower = -1;
m_renderOrderRebuildUpper = -1;
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
index 6b494dbaeb..d19fa0e17d 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
@@ -100,6 +100,7 @@ template <typename Type, int PageSize> class Allocator
{
public:
Allocator()
+ : m_freePage(0)
{
pages.push_back(new AllocatorPage<Type, PageSize>());
}
@@ -112,14 +113,21 @@ public:
Type *allocate()
{
AllocatorPage<Type, PageSize> *p = 0;
- for (int i=0; i<pages.size(); ++i) {
+ for (int i = m_freePage; i < pages.size(); i++) {
if (pages.at(i)->available > 0) {
p = pages.at(i);
+ m_freePage = i;
break;
}
}
+
+ // we couldn't find a free page from m_freePage to the last page.
+ // either there is no free pages, or there weren't any in the area we
+ // scanned: rescanning is expensive, so let's just assume there isn't
+ // one. when an item is released, we'll reset m_freePage anyway.
if (!p) {
p = new AllocatorPage<Type, PageSize>();
+ m_freePage = pages.count();
pages.push_back(p);
}
uint pos = p->blocks[PageSize - p->available];
@@ -151,6 +159,9 @@ public:
delete page;
page = pages.back();
}
+
+ // Reset the free page to force a scan for a new free point.
+ m_freePage = 0;
}
void release(Type *t)
@@ -172,6 +183,7 @@ public:
}
QVector<AllocatorPage<Type, PageSize> *> pages;
+ int m_freePage;
};
@@ -500,8 +512,8 @@ public:
ShaderManager(QSGRenderContext *ctx) : blitProgram(0), visualizeProgram(0), context(ctx) { }
~ShaderManager() {
- qDeleteAll(rewrittenShaders.values());
- qDeleteAll(stockShaders.values());
+ qDeleteAll(rewrittenShaders);
+ qDeleteAll(stockShaders);
}
public Q_SLOTS:
diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp
index 4f5c4efe14..bf97133e97 100644
--- a/src/quick/scenegraph/qsgadaptationlayer.cpp
+++ b/src/quick/scenegraph/qsgadaptationlayer.cpp
@@ -165,7 +165,9 @@ void QSGDistanceFieldGlyphCache::update()
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphAdaptationLayerFrame);
QList<QDistanceField> distanceFields;
- for (int i = 0; i < m_pendingGlyphs.size(); ++i) {
+ const int pendingGlyphsSize = m_pendingGlyphs.size();
+ distanceFields.reserve(pendingGlyphsSize);
+ for (int i = 0; i < pendingGlyphsSize; ++i) {
GlyphData &gd = glyphData(m_pendingGlyphs.at(i));
distanceFields.append(QDistanceField(gd.path,
m_pendingGlyphs.at(i),
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index 418d571ae6..150f8475d8 100644
--- a/src/quick/scenegraph/qsgcontext.cpp
+++ b/src/quick/scenegraph/qsgcontext.cpp
@@ -41,7 +41,6 @@
#include <QtQuick/private/qsgdefaultglyphnode_p.h>
#include <QtQuick/private/qsgdistancefieldglyphnode_p.h>
#include <QtQuick/private/qsgdistancefieldglyphnode_p_p.h>
-#include <QtQuick/private/qsgshareddistancefieldglyphcache_p.h>
#include <QtQuick/private/qsgatlastexture_p.h>
#include <QtQuick/private/qsgrenderloop_p.h>
#include <QtQuick/private/qsgdefaultlayer_p.h>
@@ -60,15 +59,10 @@
#include <QtQuick/private/qsgtexture_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtCore/private/qabstractanimation_p.h>
-#include <qpa/qplatformintegration.h>
-
-#include <qpa/qplatformsharedgraphicscache.h>
#include <private/qobject_p.h>
#include <qmutex.h>
-#include <private/qqmlprofilerservice_p.h>
-
DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
/*
@@ -572,35 +566,7 @@ QSGDistanceFieldGlyphCache *QSGRenderContext::distanceFieldGlyphCache(const QRaw
QSGDistanceFieldGlyphCache *cache = m_distanceFieldCacheManager->cache(font);
if (!cache) {
- QPlatformIntegration *platformIntegration = QGuiApplicationPrivate::platformIntegration();
- if (platformIntegration != 0
- && platformIntegration->hasCapability(QPlatformIntegration::SharedGraphicsCache)) {
- QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine;
- if (!fe->faceId().filename.isEmpty()) {
- QByteArray keyName = fe->faceId().filename;
- if (font.style() != QFont::StyleNormal)
- keyName += QByteArray(" I");
- if (font.weight() != QFont::Normal)
- keyName += ' ' + QByteArray::number(font.weight());
- keyName += QByteArray(" DF");
- QPlatformSharedGraphicsCache *sharedGraphicsCache =
- platformIntegration->createPlatformSharedGraphicsCache(keyName);
-
- if (sharedGraphicsCache != 0) {
- sharedGraphicsCache->ensureCacheInitialized(keyName,
- QPlatformSharedGraphicsCache::OpenGLTexture,
- QPlatformSharedGraphicsCache::Alpha8);
-
- cache = new QSGSharedDistanceFieldGlyphCache(keyName,
- sharedGraphicsCache,
- m_distanceFieldCacheManager,
- openglContext(),
- font);
- }
- }
- }
- if (!cache)
- cache = new QSGDefaultDistanceFieldGlyphCache(m_distanceFieldCacheManager, openglContext(), font);
+ cache = new QSGDefaultDistanceFieldGlyphCache(m_distanceFieldCacheManager, openglContext(), font);
m_distanceFieldCacheManager->insertCache(font, cache);
}
@@ -676,7 +642,7 @@ void QSGRenderContext::invalidate()
qDeleteAll(m_texturesToDelete);
m_texturesToDelete.clear();
- qDeleteAll(m_textures.values());
+ qDeleteAll(m_textures);
m_textures.clear();
/* The cleanup of the atlas textures is a bit intriguing.
@@ -767,22 +733,26 @@ QSGDepthStencilBufferManager *QSGRenderContext::depthStencilBufferManager()
will be called with \a image as argument.
*/
-QSGTexture *QSGRenderContext::createTexture(const QImage &image) const
+QSGTexture *QSGRenderContext::createTexture(const QImage &image, uint flags) const
{
- if (!openglContext())
- return 0;
- QSGTexture *t = m_atlasManager->create(image);
- if (t)
- return t;
- return createTextureNoAtlas(image);
-}
+ bool atlas = flags & CreateTexture_Atlas;
+ bool mipmap = flags & CreateTexture_Mipmap;
+ bool alpha = flags & CreateTexture_Alpha;
-QSGTexture *QSGRenderContext::createTextureNoAtlas(const QImage &image) const
-{
- QSGPlainTexture *t = new QSGPlainTexture();
- if (!image.isNull())
- t->setImage(image);
- return t;
+ // The atlas implementation is only supported from the render thread and
+ // does not support mipmaps.
+ if (!mipmap && atlas && openglContext() && QThread::currentThread() == openglContext()->thread()) {
+ QSGTexture *t = m_atlasManager->create(image, alpha);
+ if (t)
+ return t;
+ }
+
+ QSGPlainTexture *texture = new QSGPlainTexture();
+ texture->setImage(image);
+ if (texture->hasAlphaChannel() && !alpha)
+ texture->setHasAlphaChannel(false);
+
+ return texture;
}
/*!
diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h
index d1897f20f9..49b6f6e2a0 100644
--- a/src/quick/scenegraph/qsgcontext_p.h
+++ b/src/quick/scenegraph/qsgcontext_p.h
@@ -88,6 +88,12 @@ class Q_QUICK_PRIVATE_EXPORT QSGRenderContext : public QObject
{
Q_OBJECT
public:
+ enum CreateTextureFlags {
+ CreateTexture_Alpha = 0x1,
+ CreateTexture_Atlas = 0x2,
+ CreateTexture_Mipmap = 0x4
+ };
+
QSGRenderContext(QSGContext *context);
~QSGRenderContext();
@@ -107,8 +113,8 @@ public:
virtual QSGDistanceFieldGlyphCache *distanceFieldGlyphCache(const QRawFont &font);
QSGTexture *textureForFactory(QQuickTextureFactory *factory, QQuickWindow *window);
- virtual QSGTexture *createTexture(const QImage &image) const;
- virtual QSGTexture *createTextureNoAtlas(const QImage &image) const;
+ virtual QSGTexture *createTexture(const QImage &image, uint flags = CreateTexture_Alpha) const;
+
virtual QSGRenderer *createRenderer();
virtual void compile(QSGMaterialShader *shader, QSGMaterial *material, const char *vertexCode = 0, const char *fragmentCode = 0);
diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
index c84e6628a5..14bc0fad07 100644
--- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
+++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
@@ -104,8 +104,11 @@ char const *const *QSGTextMaskShader::attributeNames() const
}
QSGTextMaskShader::QSGTextMaskShader(QFontEngine::GlyphFormat glyphFormat)
- : QSGMaterialShader(*new QSGMaterialShaderPrivate),
- m_glyphFormat(glyphFormat)
+ : QSGMaterialShader(*new QSGMaterialShaderPrivate)
+ , m_matrix_id(-1)
+ , m_color_id(-1)
+ , m_textureScale_id(-1)
+ , m_glyphFormat(glyphFormat)
{
setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/scenegraph/shaders/textmask.vert"));
setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/textmask.frag"));
@@ -435,7 +438,9 @@ void QSGTextMaskMaterial::populate(const QPointF &p,
{
Q_ASSERT(m_font.isValid());
QVector<QFixedPoint> fixedPointPositions;
- for (int i=0; i<glyphPositions.size(); ++i)
+ const int glyphPositionsSize = glyphPositions.size();
+ fixedPointPositions.reserve(glyphPositionsSize);
+ for (int i=0; i < glyphPositionsSize; ++i)
fixedPointPositions.append(QFixedPoint::fromPointF(glyphPositions.at(i)));
QTextureGlyphCache *cache = glyphCache();
diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp b/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp
index 7e602fc0bd..4630e45ecf 100644
--- a/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp
+++ b/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp
@@ -200,9 +200,11 @@ void QSGDistanceFieldGlyphNode::updateGeometry()
const QVector<QPointF> positions = m_glyphs.positions();
qreal fontPixelSize = m_glyphs.rawFont().pixelSize();
- QVector<QSGGeometry::TexturedPoint2D> vp;
+ // The template parameters here are assuming that most strings are short, 64
+ // characters or less.
+ QVarLengthArray<QSGGeometry::TexturedPoint2D, 256> vp;
vp.reserve(indexes.size() * 4);
- QVector<ushort> ip;
+ QVarLengthArray<ushort, 384> ip;
ip.reserve(indexes.size() * 6);
qreal maxTexMargin = m_glyph_cache->distanceFieldRadius();
diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp
index 422e31ad96..6f4b85a5b9 100644
--- a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp
+++ b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp
@@ -80,6 +80,11 @@ QSGDistanceFieldTextMaterialShader::QSGDistanceFieldTextMaterialShader()
: QSGMaterialShader(),
m_fontScale(1.0)
, m_matrixScale(1.0)
+ , m_matrix_id(-1)
+ , m_textureScale_id(-1)
+ , m_alphaMin_id(-1)
+ , m_alphaMax_id(-1)
+ , m_color_id(-1)
, m_lastAlphaMin(-1)
, m_lastAlphaMax(-1)
{
@@ -260,6 +265,7 @@ protected:
DistanceFieldStyledTextMaterialShader::DistanceFieldStyledTextMaterialShader()
: QSGDistanceFieldTextMaterialShader()
+ , m_styleColor_id(-1)
{
}
@@ -330,6 +336,8 @@ protected:
DistanceFieldOutlineTextMaterialShader::DistanceFieldOutlineTextMaterialShader()
: DistanceFieldStyledTextMaterialShader()
+ , m_outlineAlphaMax0_id(-1)
+ , m_outlineAlphaMax1_id(-1)
{
setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/distancefieldoutlinetext.frag"));
}
@@ -411,6 +419,7 @@ protected:
DistanceFieldShiftedStyleTextMaterialShader::DistanceFieldShiftedStyleTextMaterialShader()
: DistanceFieldStyledTextMaterialShader()
+ , m_shift_id(-1)
{
setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/scenegraph/shaders/distancefieldshiftedtext.vert"));
setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/distancefieldshiftedtext.frag"));
@@ -489,6 +498,8 @@ private:
QSGHiQSubPixelDistanceFieldTextMaterialShader::QSGHiQSubPixelDistanceFieldTextMaterialShader()
: QSGDistanceFieldTextMaterialShader()
+ , m_fontScale_id(-1)
+ , m_vecDelta_id(-1)
{
setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/scenegraph/shaders/hiqsubpixeldistancefieldtext.vert"));
setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/hiqsubpixeldistancefieldtext.frag"));
diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp
index 4d3f34c71c..3059b750f2 100644
--- a/src/quick/scenegraph/qsgrenderloop.cpp
+++ b/src/quick/scenegraph/qsgrenderloop.cpp
@@ -102,6 +102,22 @@ void QSGRenderLoop::cleanup()
s_instance = 0;
}
+/*!
+ * Non-threaded render loops immediately run the job if there is a context.
+ */
+void QSGRenderLoop::postJob(QQuickWindow *window, QRunnable *job)
+{
+ Q_ASSERT(window);
+ Q_ASSERT(job);
+
+ if (window->openglContext()) {
+ window->openglContext()->makeCurrent(window);
+ job->run();
+ }
+
+ delete job;
+}
+
class QSGGuiThreadRenderLoop : public QSGRenderLoop
{
Q_OBJECT
diff --git a/src/quick/scenegraph/qsgrenderloop_p.h b/src/quick/scenegraph/qsgrenderloop_p.h
index 4293015b96..3336731fda 100644
--- a/src/quick/scenegraph/qsgrenderloop_p.h
+++ b/src/quick/scenegraph/qsgrenderloop_p.h
@@ -45,6 +45,7 @@ class QQuickWindow;
class QSGContext;
class QSGRenderContext;
class QAnimationDriver;
+class QRunnable;
class Q_QUICK_PRIVATE_EXPORT QSGRenderLoop : public QObject
{
@@ -72,6 +73,7 @@ public:
virtual QSGRenderContext *createRenderContext(QSGContext *) const = 0;
virtual void releaseResources(QQuickWindow *window) = 0;
+ virtual void postJob(QQuickWindow *window, QRunnable *job);
void addWindow(QQuickWindow *win) { m_windows.insert(win); }
void removeWindow(QQuickWindow *win) { m_windows.remove(win); }
diff --git a/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp
deleted file mode 100644
index f1cc9d1a86..0000000000
--- a/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp
+++ /dev/null
@@ -1,655 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#define EGL_EGLEXT_PROTOTYPES
-#define GL_GLEXT_PROTOTYPES
-#if defined(QSGSHAREDDISTANCEFIELDGLYPHCACHE_DEBUG)
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#endif
-
-#include "qsgshareddistancefieldglyphcache_p.h"
-
-#include <QtCore/qhash.h>
-#include <QtCore/qthread.h>
-#include <QtCore/qcoreapplication.h>
-
-#include <qpa/qplatformsharedgraphicscache.h>
-
-#include <QtQuick/qquickwindow.h>
-
-// #define QSGSHAREDDISTANCEFIELDGLYPHCACHE_DEBUG
-
-QT_BEGIN_NAMESPACE
-
-namespace {
-
- class QSGInvokeEvent: public QEvent
- {
- public:
- QSGInvokeEvent(QPlatformSharedGraphicsCache *cache,
- const QByteArray &cacheId = QByteArray(),
- const QVector<quint32> &glyphIds = QVector<quint32>(),
- bool inSceneGraphUpdate = false)
- : QEvent(User)
- , m_cache(cache)
- , m_cacheId(cacheId)
- , m_glyphIds(glyphIds)
- , m_inSceneGraphUpdate(inSceneGraphUpdate)
- {}
-
- bool inSceneGraphUpdate() const { return m_inSceneGraphUpdate; }
- QPlatformSharedGraphicsCache *cache() const { return m_cache; }
-
- virtual void invoke() = 0;
- protected:
- QPlatformSharedGraphicsCache *m_cache;
- QByteArray m_cacheId;
- QVector<quint32> m_glyphIds;
- bool m_inSceneGraphUpdate;
- };
-
- class QSGReleaseItemsEvent: public QSGInvokeEvent
- {
- public:
- QSGReleaseItemsEvent(QPlatformSharedGraphicsCache *cache,
- const QByteArray &cacheId,
- const QVector<quint32> &glyphIds,
- bool inSceneGraphUpdate)
- : QSGInvokeEvent(cache, cacheId, glyphIds, inSceneGraphUpdate)
- {
- }
-
- void invoke()
- {
- m_cache->releaseItems(m_cacheId, m_glyphIds);
- }
- };
-
- class QSGRequestItemsEvent: public QSGInvokeEvent
- {
- public:
- QSGRequestItemsEvent(QPlatformSharedGraphicsCache *cache,
- const QByteArray &cacheId,
- const QVector<quint32> &glyphIds,
- bool inSceneGraphUpdate)
- : QSGInvokeEvent(cache, cacheId, glyphIds, inSceneGraphUpdate)
- {
- }
-
- void invoke()
- {
- m_cache->requestItems(m_cacheId, m_glyphIds);
- }
- };
-
- class QSGInsertItemsEvent: public QSGInvokeEvent
- {
- public:
- QSGInsertItemsEvent(QPlatformSharedGraphicsCache *cache,
- const QByteArray &cacheId,
- const QVector<quint32> &glyphIds,
- const QVector<QImage> &images,
- bool inSceneGraphUpdate)
- : QSGInvokeEvent(cache, cacheId, glyphIds, inSceneGraphUpdate)
- , m_images(images)
- {
- }
-
- void invoke()
- {
- m_cache->insertItems(m_cacheId, m_glyphIds, m_images);
- }
-
- private:
- QVector<QImage> m_images;
- };
-
- class QSGEndRequestBatchEvent: public QSGInvokeEvent
- {
- public:
- QSGEndRequestBatchEvent(QPlatformSharedGraphicsCache *cache)
- : QSGInvokeEvent(cache)
- {
- }
-
- void invoke()
- {
- if (m_cache->requestBatchStarted())
- m_cache->endRequestBatch();
- }
- };
-
- class QSGMainThreadInvoker: public QObject
- {
- public:
- bool event(QEvent *e)
- {
- if (e->type() == QEvent::User) {
- Q_ASSERT(QThread::currentThread() == QCoreApplication::instance()->thread());
-
- QSGInvokeEvent *invokeEvent = static_cast<QSGInvokeEvent *>(e);
- if (invokeEvent->inSceneGraphUpdate()) {
- QPlatformSharedGraphicsCache *cache = invokeEvent->cache();
- if (!cache->requestBatchStarted())
- cache->beginRequestBatch();
- }
-
- static_cast<QSGInvokeEvent *>(e)->invoke();
- return true;
- }
- return QObject::event(e);
- }
-
- static QSGMainThreadInvoker *instance()
- {
- if (m_invoker == 0) {
- m_invoker = new QSGMainThreadInvoker;
- m_invoker->moveToThread(QCoreApplication::instance()->thread());
- }
-
- return m_invoker;
- }
-
- private:
- static QSGMainThreadInvoker *m_invoker;
- };
-
- QSGMainThreadInvoker* QSGMainThreadInvoker::m_invoker = 0;
-}
-
-QSGSharedDistanceFieldGlyphCache::QSGSharedDistanceFieldGlyphCache(const QByteArray &cacheId,
- QPlatformSharedGraphicsCache *sharedGraphicsCache,
- QSGDistanceFieldGlyphCacheManager *man,
- QOpenGLContext *c,
- const QRawFont &font)
- : QSGDistanceFieldGlyphCache(man, c, font)
- , m_cacheId(cacheId)
- , m_sharedGraphicsCache(sharedGraphicsCache)
- , m_isInSceneGraphUpdate(false)
- , m_hasPostedEvents(false)
-{
-#if defined(QSGSHAREDDISTANCEFIELDGLYPHCACHE_DEBUG)
- qDebug("QSGSharedDistanceFieldGlyphCache with id %s created in thread %p",
- cacheId.constData(), QThread::currentThreadId());
-#endif
-
- Q_ASSERT(sizeof(glyph_t) == sizeof(quint32));
- Q_ASSERT(sharedGraphicsCache != 0);
-
- connect(sharedGraphicsCache, SIGNAL(itemsMissing(QByteArray,QVector<quint32>)),
- this, SLOT(reportItemsMissing(QByteArray,QVector<quint32>)),
- Qt::DirectConnection);
- connect(sharedGraphicsCache, SIGNAL(itemsAvailable(QByteArray,void*,QVector<quint32>,QVector<QPoint>)),
- this, SLOT(reportItemsAvailable(QByteArray,void*,QVector<quint32>,QVector<QPoint>)),
- Qt::DirectConnection);
- connect(sharedGraphicsCache, SIGNAL(itemsUpdated(QByteArray,void*,QVector<quint32>,QVector<QPoint>)),
- this, SLOT(reportItemsUpdated(QByteArray,void*,QVector<quint32>,QVector<QPoint>)),
- Qt::DirectConnection);
- connect(sharedGraphicsCache, SIGNAL(itemsInvalidated(QByteArray,QVector<quint32>)),
- this, SLOT(reportItemsInvalidated(QByteArray,QVector<quint32>)),
- Qt::DirectConnection);
-
- Q_ASSERT(c);
- QQuickWindow *window = static_cast<QQuickWindow *>(c->surface());
- Q_ASSERT(window != 0);
-
- connect(window, SIGNAL(beforeSynchronizing()), this, SLOT(sceneGraphUpdateStarted()),
- Qt::DirectConnection);
- connect(window, SIGNAL(beforeRendering()), this, SLOT(sceneGraphUpdateDone()),
- Qt::DirectConnection);
-}
-
-QSGSharedDistanceFieldGlyphCache::~QSGSharedDistanceFieldGlyphCache()
-{
- {
- QHash<glyph_t, void *>::const_iterator it = m_bufferForGlyph.constBegin();
- while (it != m_bufferForGlyph.constEnd()) {
- m_sharedGraphicsCache->dereferenceBuffer(it.value());
- ++it;
- }
- }
-
- {
- QHash<quint32, PendingGlyph>::const_iterator it = m_pendingReadyGlyphs.constBegin();
- while (it != m_pendingReadyGlyphs.constEnd()) {
- m_sharedGraphicsCache->dereferenceBuffer(it.value().buffer);
- ++it;
- }
- }
-}
-
-void QSGSharedDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs)
-{
- typedef QSet<glyph_t>::const_iterator GlyphSetConstIt;
-
- QMutexLocker locker(&m_pendingGlyphsMutex);
-
-#if defined(QSGSHAREDDISTANCEFIELDGLYPHCACHE_DEBUG)
- qDebug("QSGSharedDistanceFieldGlyphCache::requestGlyphs() called for %s (%d glyphs)",
- m_cacheId.constData(), glyphs.size());
-#endif
-
- m_requestedGlyphsThatHaveNotBeenReturned.unite(glyphs);
- m_requestedGlyphs.unite(glyphs);
-
- QVector<quint32> glyphsVector;
- glyphsVector.reserve(glyphs.size());
-
- for (GlyphSetConstIt it = glyphs.constBegin(), cend = glyphs.constEnd(); it != cend; ++it) {
- Q_ASSERT(!m_bufferForGlyph.contains(*it));
- glyphsVector.append(*it);
- }
-
- m_hasPostedEvents = true;
- QSGMainThreadInvoker *invoker = QSGMainThreadInvoker::instance();
- QCoreApplication::postEvent(invoker, new QSGRequestItemsEvent(m_sharedGraphicsCache,
- m_cacheId,
- glyphsVector,
- m_isInSceneGraphUpdate));
-}
-
-void QSGSharedDistanceFieldGlyphCache::waitForGlyphs()
-{
- Q_ASSERT(!m_isInSceneGraphUpdate);
- if (m_isInSceneGraphUpdate) {
- qWarning("QSGSharedDistanceFieldGlyphCache::waitForGlyphs: Called from inside "
- "scenegraph update. Will freeze.");
- }
-
- {
- QMutexLocker locker(&m_pendingGlyphsMutex);
- while (!m_requestedGlyphsThatHaveNotBeenReturned.isEmpty())
- m_pendingGlyphsCondition.wait(&m_pendingGlyphsMutex);
- }
-}
-
-void QSGSharedDistanceFieldGlyphCache::storeGlyphs(const QList<QDistanceField> &glyphs)
-{
- {
- QMutexLocker locker(&m_pendingGlyphsMutex);
-#if defined(QSGSHAREDDISTANCEFIELDGLYPHCACHE_DEBUG)
- qDebug("QSGSharedDistanceFieldGlyphCache::storeGlyphs() called for %s (%d glyphs)",
- m_cacheId.constData(), glyphs.size());
-#endif
-
- int glyphCount = glyphs.size();
- QVector<quint32> glyphIds(glyphCount);
- QVector<QImage> images(glyphCount);
- for (int i = 0; i < glyphs.size(); ++i) {
- const QDistanceField &df = glyphs.at(i);
- m_requestedGlyphsThatHaveNotBeenReturned.insert(df.glyph());
- glyphIds[i] = df.glyph();
- // ### TODO: Handle QDistanceField in QPlatformSharedGraphicsCache
- images[i] = df.toImage(QImage::Format_Indexed8);
- }
-
- m_hasPostedEvents = true;
- QSGMainThreadInvoker *invoker = QSGMainThreadInvoker::instance();
- QCoreApplication::postEvent(invoker, new QSGInsertItemsEvent(m_sharedGraphicsCache,
- m_cacheId,
- glyphIds,
- images,
- m_isInSceneGraphUpdate));
- }
-
- processPendingGlyphs();
-}
-
-void QSGSharedDistanceFieldGlyphCache::referenceGlyphs(const QSet<glyph_t> &glyphs)
-{
- Q_UNUSED(glyphs);
-
- // Intentionally empty. Not required in this implementation, since the glyphs are reference
- // counted outside and releaseGlyphs() will only be called when there are no more references.
-}
-
-void QSGSharedDistanceFieldGlyphCache::releaseGlyphs(const QSet<glyph_t> &glyphs)
-{
- typedef QSet<glyph_t>::const_iterator GlyphSetConstIt;
-
-#if defined(QSGSHAREDDISTANCEFIELDGLYPHCACHE_DEBUG)
- qDebug("QSGSharedDistanceFieldGlyphCache::releaseGlyphs() called for %s (%d glyphs)",
- m_cacheId.constData(), glyphs.size());
-#endif
-
- m_requestedGlyphs.subtract(glyphs);
-
- QVector<quint32> glyphsVector;
- glyphsVector.reserve(glyphs.size());
-
- for (GlyphSetConstIt glyphsIt = glyphs.constBegin(), cend = glyphs.constEnd(); glyphsIt != cend; ++glyphsIt) {
- QHash<glyph_t, void *>::iterator bufferIt = m_bufferForGlyph.find(*glyphsIt);
- if (bufferIt != m_bufferForGlyph.end()) {
- void *buffer = bufferIt.value();
- removeGlyph(*glyphsIt);
- m_bufferForGlyph.erase(bufferIt);
- Q_ASSERT(!m_bufferForGlyph.contains(*glyphsIt));
-
- if (!m_sharedGraphicsCache->dereferenceBuffer(buffer)) {
-#if !defined(QT_NO_DEBUG)
- bufferIt = m_bufferForGlyph.begin();
- while (bufferIt != m_bufferForGlyph.end()) {
- Q_ASSERT(bufferIt.value() != buffer);
- ++bufferIt;
- }
-#endif
- }
- }
-
- glyphsVector.append(*glyphsIt);
- }
-
- m_hasPostedEvents = true;
- QSGMainThreadInvoker *mainThreadInvoker = QSGMainThreadInvoker::instance();
- QCoreApplication::postEvent(mainThreadInvoker, new QSGReleaseItemsEvent(m_sharedGraphicsCache,
- m_cacheId,
- glyphsVector,
- m_isInSceneGraphUpdate));
-}
-
-void QSGSharedDistanceFieldGlyphCache::registerOwnerElement(QQuickItem *ownerElement)
-{
- Owner &owner = m_registeredOwners[ownerElement];
- if (owner.ref == 0) {
- owner.item = ownerElement;
-
- bool ok = connect(this, SIGNAL(glyphsPending()), ownerElement, SLOT(triggerPreprocess()));
- Q_ASSERT_X(ok, Q_FUNC_INFO, "QML element that owns a glyph node must have triggerPreprocess() slot");
- Q_UNUSED(ok);
- }
- ++owner.ref;
-}
-
-void QSGSharedDistanceFieldGlyphCache::unregisterOwnerElement(QQuickItem *ownerElement)
-{
- QHash<QQuickItem *, Owner>::iterator it = m_registeredOwners.find(ownerElement);
- if (it != m_registeredOwners.end() && --it->ref <= 0) {
- if (it->item)
- disconnect(this, SIGNAL(glyphsPending()), ownerElement, SLOT(triggerPreprocess()));
- m_registeredOwners.erase(it);
- }
-}
-
-namespace {
- struct TextureContent {
- QSize size;
- QVector<glyph_t> glyphs;
- };
-}
-
-void QSGSharedDistanceFieldGlyphCache::processPendingGlyphs()
-{
- Q_ASSERT(QThread::currentThread() == thread());
-
- waitForGlyphs();
-
- {
- QMutexLocker locker(&m_pendingGlyphsMutex);
- if (m_pendingMissingGlyphs.isEmpty()
- && m_pendingReadyGlyphs.isEmpty()
- && m_pendingInvalidatedGlyphs.isEmpty()) {
- return;
- }
-
- {
- QVector<glyph_t> pendingMissingGlyphs;
- pendingMissingGlyphs.reserve(m_pendingMissingGlyphs.size());
-
- QSet<glyph_t>::const_iterator it = m_pendingMissingGlyphs.constBegin();
- while (it != m_pendingMissingGlyphs.constEnd()) {
- pendingMissingGlyphs.append(*it);
- ++it;
- }
-
- markGlyphsToRender(pendingMissingGlyphs);
- }
-
- {
- QVector<glyph_t> filteredPendingInvalidatedGlyphs;
- filteredPendingInvalidatedGlyphs.reserve(m_pendingInvalidatedGlyphs.size());
-
- QSet<glyph_t>::const_iterator it = m_pendingInvalidatedGlyphs.constBegin();
- while (it != m_pendingInvalidatedGlyphs.constEnd()) {
- bool rerequestGlyph = false;
-
- // The glyph was invalidated right after being posted as ready, we throw away
- // the ready glyph and rerequest it to be certain
- QHash<quint32, PendingGlyph>::iterator pendingGlyphIt = m_pendingReadyGlyphs.find(*it);
- if (pendingGlyphIt != m_pendingReadyGlyphs.end()) {
- m_sharedGraphicsCache->dereferenceBuffer(pendingGlyphIt.value().buffer);
- pendingGlyphIt = m_pendingReadyGlyphs.erase(pendingGlyphIt);
- rerequestGlyph = true;
- }
-
- void *bufferId = m_bufferForGlyph.value(*it, 0);
- if (bufferId != 0) {
- m_sharedGraphicsCache->dereferenceBuffer(bufferId);
- m_bufferForGlyph.remove(*it);
- rerequestGlyph = true;
- }
-
- if (rerequestGlyph)
- filteredPendingInvalidatedGlyphs.append(*it);
-
- ++it;
- }
-
- // If this cache is still using the glyphs, reset the texture held by them, and mark them
- // to be rendered again since they are still needed.
- if (!filteredPendingInvalidatedGlyphs.isEmpty()) {
- setGlyphsTexture(filteredPendingInvalidatedGlyphs, Texture());
- markGlyphsToRender(filteredPendingInvalidatedGlyphs);
- }
- }
-
- {
- QList<GlyphPosition> glyphPositions;
-
- QHash<void *, TextureContent> textureContentForBuffer;
- {
- QHash<quint32, PendingGlyph>::iterator it = m_pendingReadyGlyphs.begin();
- while (it != m_pendingReadyGlyphs.end()) {
- void *currentGlyphBuffer = m_bufferForGlyph.value(it.key(), 0);
- if (currentGlyphBuffer != 0) {
- if (!m_sharedGraphicsCache->dereferenceBuffer(currentGlyphBuffer)) {
- Q_ASSERT(!textureContentForBuffer.contains(currentGlyphBuffer));
- }
- }
-
- PendingGlyph &pendingGlyph = it.value();
-
- // We don't ref or deref the buffer here, since it was already referenced when
- // added to the pending ready glyphs
- m_bufferForGlyph[it.key()] = pendingGlyph.buffer;
-
- textureContentForBuffer[pendingGlyph.buffer].size = pendingGlyph.bufferSize;
- textureContentForBuffer[pendingGlyph.buffer].glyphs.append(it.key());
-
- GlyphPosition glyphPosition;
- glyphPosition.glyph = it.key();
- glyphPosition.position = pendingGlyph.position;
-
- glyphPositions.append(glyphPosition);
-
- ++it;
- }
- }
-
- setGlyphsPosition(glyphPositions);
-
- {
- QHash<void *, TextureContent>::const_iterator it = textureContentForBuffer.constBegin();
- while (it != textureContentForBuffer.constEnd()) {
- Texture texture;
- texture.textureId = m_sharedGraphicsCache->textureIdForBuffer(it.key());
- texture.size = m_sharedGraphicsCache->sizeOfBuffer(it.key());
-
- setGlyphsTexture(it.value().glyphs, texture);
-
- ++it;
- }
- }
- }
-
- m_pendingMissingGlyphs.clear();
- m_pendingInvalidatedGlyphs.clear();
- m_pendingReadyGlyphs.clear();
- }
-}
-
-void QSGSharedDistanceFieldGlyphCache::reportItemsAvailable(const QByteArray &cacheId,
- void *bufferId,
- const QVector<quint32> &itemIds,
- const QVector<QPoint> &positions)
-{
- bool requestedItemsInList = false;
- {
- QMutexLocker locker(&m_pendingGlyphsMutex);
- if (m_cacheId != cacheId)
- return;
-
-#if defined(QSGSHAREDDISTANCEFIELDGLYPHCACHE_DEBUG)
- qDebug("QSGSharedDistanceFieldGlyphCache::reportItemsAvailable() called for %s (%d glyphs)",
- cacheId.constData(), itemIds.size());
-#endif
-
- for (int i=0; i<itemIds.size(); ++i) {
- if (m_requestedGlyphsThatHaveNotBeenReturned.contains(itemIds.at(i))) {
- requestedItemsInList = true;
- break;
- }
- }
- }
-
- if (requestedItemsInList)
- reportItemsUpdated(cacheId, bufferId,itemIds, positions);
-}
-
-void QSGSharedDistanceFieldGlyphCache::reportItemsUpdated(const QByteArray &cacheId,
- void *bufferId,
- const QVector<quint32> &itemIds,
- const QVector<QPoint> &positions)
-{
- {
- QMutexLocker locker(&m_pendingGlyphsMutex);
- if (m_cacheId != cacheId)
- return;
-
- Q_ASSERT(itemIds.size() == positions.size());
-
-#if defined(QSGSHAREDDISTANCEFIELDGLYPHCACHE_DEBUG)
- qDebug("QSGSharedDistanceFieldGlyphCache::reportItemsUpdated() called for %s (%d glyphs)",
- cacheId.constData(), itemIds.size());
-#endif
-
- for (int i=0; i<itemIds.size(); ++i) {
- if (m_requestedGlyphs.contains(itemIds.at(i))) {
- PendingGlyph &pendingGlyph = m_pendingReadyGlyphs[itemIds.at(i)];
- void *oldBuffer = pendingGlyph.buffer;
-
- pendingGlyph.buffer = bufferId;
- pendingGlyph.position = positions.at(i);
-
- m_sharedGraphicsCache->referenceBuffer(bufferId);
- if (oldBuffer != 0)
- m_sharedGraphicsCache->dereferenceBuffer(oldBuffer);
-
- m_requestedGlyphsThatHaveNotBeenReturned.remove(itemIds.at(i));
- }
- }
- }
-
- m_pendingGlyphsCondition.wakeAll();
- emit glyphsPending();
-}
-
-void QSGSharedDistanceFieldGlyphCache::reportItemsInvalidated(const QByteArray &cacheId,
- const QVector<quint32> &itemIds)
-{
- {
- QMutexLocker locker(&m_pendingGlyphsMutex);
- if (m_cacheId != cacheId)
- return;
-
- for (int i=0; i<itemIds.size(); ++i) {
- if (m_requestedGlyphs.contains(itemIds.at(i)))
- m_pendingInvalidatedGlyphs.insert(itemIds.at(i));
- }
- }
-
- emit glyphsPending();
-}
-
-
-void QSGSharedDistanceFieldGlyphCache::reportItemsMissing(const QByteArray &cacheId,
- const QVector<quint32> &itemIds)
-{
- {
- QMutexLocker locker(&m_pendingGlyphsMutex);
- if (m_cacheId != cacheId)
- return;
-
-#if defined(QSGSHAREDDISTANCEFIELDGLYPHCACHE_DEBUG)
- qDebug("QSGSharedDistanceFieldGlyphCache::reportItemsMissing() called for %s (%d glyphs)",
- cacheId.constData(), itemIds.size());
-#endif
-
- for (int i=0; i<itemIds.size(); ++i) {
- if (m_requestedGlyphsThatHaveNotBeenReturned.remove(itemIds.at(i)))
- m_pendingMissingGlyphs.insert(itemIds.at(i));
- }
- }
-
- m_pendingGlyphsCondition.wakeAll();
- emit glyphsPending();
-}
-
-void QSGSharedDistanceFieldGlyphCache::sceneGraphUpdateStarted()
-{
- m_isInSceneGraphUpdate = true;
- m_hasPostedEvents = false;
-}
-
-void QSGSharedDistanceFieldGlyphCache::sceneGraphUpdateDone()
-{
- m_isInSceneGraphUpdate = false;
-
- if (m_hasPostedEvents) {
- QSGMainThreadInvoker *invoker = QSGMainThreadInvoker::instance();
- QCoreApplication::postEvent(invoker, new QSGEndRequestBatchEvent(m_sharedGraphicsCache));
- m_hasPostedEvents = false;
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h
deleted file mode 100644
index aee77c49c6..0000000000
--- a/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGSHAREDDISTANCEFIELDGLYPHCACHE_H
-#define QSGSHAREDDISTANCEFIELDGLYPHCACHE_H
-
-#include <QtCore/qwaitcondition.h>
-#include <private/qsgadaptationlayer_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPlatformSharedGraphicsCache;
-class QSGSharedDistanceFieldGlyphCache : public QObject, public QSGDistanceFieldGlyphCache
-{
- Q_OBJECT
-public:
- explicit QSGSharedDistanceFieldGlyphCache(const QByteArray &cacheId,
- QPlatformSharedGraphicsCache *sharedGraphicsCache,
- QSGDistanceFieldGlyphCacheManager *man,
- QOpenGLContext *c,
- const QRawFont &font);
- ~QSGSharedDistanceFieldGlyphCache();
-
- void registerOwnerElement(QQuickItem *ownerElement);
- void unregisterOwnerElement(QQuickItem *ownerElement);
- void processPendingGlyphs();
-
- void requestGlyphs(const QSet<glyph_t> &glyphs);
- void referenceGlyphs(const QSet<glyph_t> &glyphs);
- void storeGlyphs(const QList<QDistanceField> &glyphs);
- void releaseGlyphs(const QSet<glyph_t> &glyphs);
-
-Q_SIGNALS:
- void glyphsPending();
-
-private Q_SLOTS:
- void reportItemsMissing(const QByteArray &cacheId, const QVector<quint32> &itemIds);
- void reportItemsAvailable(const QByteArray &cacheId,
- void *bufferId,
- const QVector<quint32> &itemIds,
- const QVector<QPoint> &positions);
- void reportItemsUpdated(const QByteArray &cacheId,
- void *bufferId,
- const QVector<quint32> &itemIds,
- const QVector<QPoint> &positions);
- void reportItemsInvalidated(const QByteArray &cacheId, const QVector<quint32> &itemIds);
-
- void sceneGraphUpdateStarted();
- void sceneGraphUpdateDone();
-
-private:
- void waitForGlyphs();
- void saveTexture(GLuint textureId, int width, int height);
-
- QSet<quint32> m_requestedGlyphsThatHaveNotBeenReturned;
- QSet<quint32> m_requestedGlyphs;
- QWaitCondition m_pendingGlyphsCondition;
- QByteArray m_cacheId;
- QPlatformSharedGraphicsCache *m_sharedGraphicsCache;
- QMutex m_pendingGlyphsMutex;
-
- QSet<glyph_t> m_pendingInvalidatedGlyphs;
- QSet<glyph_t> m_pendingMissingGlyphs;
-
- struct PendingGlyph
- {
- PendingGlyph() : buffer(0) {}
-
- void *buffer;
- QSize bufferSize;
- QPoint position;
- };
-
- struct Owner
- {
- Owner() : ref(0) {}
- Owner(const Owner &o) : item(o.item), ref(o.ref) {}
- Owner &operator =(const Owner &o) { item = o.item; ref = o.ref; return *this; }
-
- QPointer<QQuickItem> item;
- int ref;
- };
-
- QHash<quint32, PendingGlyph> m_pendingReadyGlyphs;
- QHash<glyph_t, void *> m_bufferForGlyph;
- QHash<QQuickItem *, Owner> m_registeredOwners;
-
- bool m_isInSceneGraphUpdate;
- bool m_hasPostedEvents;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGSHAREDDISTANCEFIELDGLYPHCACHE_H
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index 2cebbaf484..4b78fefa99 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -54,7 +54,8 @@
#include <private/qquickanimatorcontroller_p.h>
#include <private/qquickprofiler_p.h>
-#include <private/qqmldebugservice_p.h>
+#include <private/qqmldebugserviceinterfaces_p.h>
+#include <private/qqmldebugconnector_p.h>
#include <private/qquickshadereffectnode_p.h>
@@ -147,6 +148,9 @@ const QEvent::Type WM_TryRelease = QEvent::Type(QEvent::User + 4);
// called.
const QEvent::Type WM_Grab = QEvent::Type(QEvent::User + 5);
+// Passed by the window when there is a render job to run
+const QEvent::Type WM_PostJob = QEvent::Type(QEvent::User + 6);
+
template <typename T> T *windowFor(const QList<T> &list, QQuickWindow *window)
{
for (int i=0; i<list.size(); ++i) {
@@ -200,6 +204,14 @@ public:
QImage *image;
};
+class WMJobEvent : public WMWindowEvent
+{
+public:
+ WMJobEvent(QQuickWindow *c, QRunnable *postedJob)
+ : WMWindowEvent(c, WM_PostJob), job(postedJob) {}
+ ~WMJobEvent() { delete job; }
+ QRunnable *job;
+};
class QSGRenderThreadEventQueue : public QQueue<QEvent *>
{
@@ -345,7 +357,6 @@ bool QSGRenderThread::event(QEvent *e)
if (window) {
QQuickWindowPrivate::get(window)->fireAboutToStop();
qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- window removed";
- gl->doneCurrent();
window = 0;
}
waitCondition.wakeOne();
@@ -396,20 +407,21 @@ bool QSGRenderThread::event(QEvent *e)
case WM_Grab: {
qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "WM_Grab";
WMGrabEvent *ce = static_cast<WMGrabEvent *>(e);
- Q_ASSERT(ce->window == window);
+ Q_ASSERT(ce->window);
+ Q_ASSERT(ce->window == window || !window);
mutex.lock();
- if (window) {
- gl->makeCurrent(window);
+ if (ce->window) {
+ gl->makeCurrent(ce->window);
qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- sync scene graph";
- QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
+ QQuickWindowPrivate *d = QQuickWindowPrivate::get(ce->window);
d->syncSceneGraph();
qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- rendering scene graph";
- QQuickWindowPrivate::get(window)->renderSceneGraph(windowSize);
+ QQuickWindowPrivate::get(ce->window)->renderSceneGraph(ce->window->size());
qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- grabbing result";
- *ce->image = qt_gl_read_framebuffer(windowSize * window->effectiveDevicePixelRatio(), false, false);
+ *ce->image = qt_gl_read_framebuffer(windowSize * ce->window->effectiveDevicePixelRatio(), false, false);
}
qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- waking gui to handle result";
waitCondition.wakeOne();
@@ -417,6 +429,20 @@ bool QSGRenderThread::event(QEvent *e)
return true;
}
+ case WM_PostJob: {
+ qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "WM_PostJob";
+ WMJobEvent *ce = static_cast<WMJobEvent *>(e);
+ Q_ASSERT(ce->window == window);
+ if (window) {
+ gl->makeCurrent(window);
+ ce->job->run();
+ delete ce->job;
+ ce->job = 0;
+ qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- job done";
+ }
+ return true;
+ }
+
case WM_RequestRepaint:
qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "WM_RequestPaint";
// When GUI posts this event, it is followed by a polishAndSync, so we mustn't
@@ -666,7 +692,7 @@ void QSGRenderThread::run()
qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "run()";
animatorDriver = sgrc->sceneGraphContext()->createAnimationDriver(0);
animatorDriver->install();
- if (QQmlDebugService::isDebuggingEnabled())
+ if (QQmlDebugConnector::service<QQmlProfilerService>())
QQuickProfiler::registerAnimationCallback();
while (active) {
@@ -993,20 +1019,20 @@ void QSGThreadedRenderLoop::maybeUpdate(Window *w)
if (!QCoreApplication::instance())
return;
+ if (!w || !w->thread->isRunning())
+ return;
+
QThread *current = QThread::currentThread();
if (current != QCoreApplication::instance()->thread() && (current != w->thread || !m_lockedForSync)) {
qWarning() << "Updates can only be scheduled from GUI thread or from QQuickItem::updatePaintNode()";
return;
}
- if (!w || !w->thread->isRunning()) {
- return;
- }
qCDebug(QSG_LOG_RENDERLOOP) << "update from item" << w->window;
// Call this function from the Gui thread later as startTimer cannot be
// called from the render thread.
- if (QThread::currentThread() == w->thread) {
+ if (current == w->thread) {
qCDebug(QSG_LOG_RENDERLOOP) << "- on render thread";
w->updateDuringSync = true;
return;
@@ -1242,6 +1268,18 @@ QImage QSGThreadedRenderLoop::grab(QQuickWindow *window)
return result;
}
+/*!
+ * Posts a new job event to the render thread.
+ * Returns true if posting succeeded.
+ */
+void QSGThreadedRenderLoop::postJob(QQuickWindow *window, QRunnable *job)
+{
+ Window *w = windowFor(m_windows, window);
+ if (w && w->thread && w->thread->window)
+ w->thread->postEvent(new WMJobEvent(window, job));
+ else
+ delete job;
+}
#include "qsgthreadedrenderloop.moc"
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop_p.h b/src/quick/scenegraph/qsgthreadedrenderloop_p.h
index d5ffbf10a3..67df9dcd31 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop_p.h
+++ b/src/quick/scenegraph/qsgthreadedrenderloop_p.h
@@ -71,6 +71,7 @@ public:
void releaseResources(QQuickWindow *window);
bool event(QEvent *);
+ void postJob(QQuickWindow *window, QRunnable *job);
bool interleaveIncubation() const;
diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri
index 480ac5e569..84cc2ba135 100644
--- a/src/quick/scenegraph/scenegraph.pri
+++ b/src/quick/scenegraph/scenegraph.pri
@@ -79,7 +79,6 @@ HEADERS += \
$$PWD/qsgdefaultglyphnode_p_p.h \
$$PWD/qsgdefaultimagenode_p.h \
$$PWD/qsgdefaultrectanglenode_p.h \
- $$PWD/qsgshareddistancefieldglyphcache_p.h \
$$PWD/qsgrenderloop_p.h \
$$PWD/qsgthreadedrenderloop_p.h \
$$PWD/qsgwindowsrenderloop_p.h \
@@ -96,7 +95,6 @@ SOURCES += \
$$PWD/qsgdistancefieldglyphnode_p.cpp \
$$PWD/qsgdefaultimagenode.cpp \
$$PWD/qsgdefaultrectanglenode.cpp \
- $$PWD/qsgshareddistancefieldglyphcache.cpp \
$$PWD/qsgrenderloop.cpp \
$$PWD/qsgthreadedrenderloop.cpp \
$$PWD/qsgwindowsrenderloop.cpp \
diff --git a/src/quick/scenegraph/util/qsgatlastexture.cpp b/src/quick/scenegraph/util/qsgatlastexture.cpp
index b862fa6a2b..8c649fb6bd 100644
--- a/src/quick/scenegraph/util/qsgatlastexture.cpp
+++ b/src/quick/scenegraph/util/qsgatlastexture.cpp
@@ -112,13 +112,15 @@ void Manager::invalidate()
}
}
-QSGTexture *Manager::create(const QImage &image)
+QSGTexture *Manager::create(const QImage &image, bool hasAlphaChannel)
{
- QSGTexture *t = 0;
+ Texture *t = 0;
if (image.width() < m_atlas_size_limit && image.height() < m_atlas_size_limit) {
if (!m_atlas)
m_atlas = new Atlas(m_atlas_size);
t = m_atlas->create(image);
+ if (!hasAlphaChannel && t->hasAlphaChannel())
+ t->setHasAlphaChannel(false);
}
return t;
}
diff --git a/src/quick/scenegraph/util/qsgatlastexture_p.h b/src/quick/scenegraph/util/qsgatlastexture_p.h
index 399d5fd669..c0f6ab912d 100644
--- a/src/quick/scenegraph/util/qsgatlastexture_p.h
+++ b/src/quick/scenegraph/util/qsgatlastexture_p.h
@@ -58,7 +58,7 @@ public:
Manager();
~Manager();
- QSGTexture *create(const QImage &image);
+ QSGTexture *create(const QImage &image, bool hasAlphaChannel);
void invalidate();
private:
@@ -114,6 +114,7 @@ public:
int textureId() const { return m_atlas->textureId(); }
QSize textureSize() const { return atlasSubRectWithoutPadding().size(); }
+ void setHasAlphaChannel(bool alpha) { m_has_alpha = alpha; }
bool hasAlphaChannel() const { return m_has_alpha; }
bool hasMipmaps() const { return false; }
bool isAtlasTexture() const { return true; }
diff --git a/src/quick/scenegraph/util/qsgengine.cpp b/src/quick/scenegraph/util/qsgengine.cpp
index c0ddf25765..8622f8edc1 100644
--- a/src/quick/scenegraph/util/qsgengine.cpp
+++ b/src/quick/scenegraph/util/qsgengine.cpp
@@ -150,7 +150,7 @@ QSGAbstractRenderer *QSGEngine::createRenderer() const
/*!
Creates a texture using the data of \a image
- Valid \a options are TextureCanUseAtlas
+ Valid \a options are TextureCanUseAtlas and TextureIsOpaque.
The caller takes ownership of the texture and the
texture should only be used with this engine.
@@ -160,13 +160,12 @@ QSGAbstractRenderer *QSGEngine::createRenderer() const
QSGTexture *QSGEngine::createTextureFromImage(const QImage &image, CreateTextureOptions options) const
{
Q_D(const QSGEngine);
- if (!d->sgRenderContext->isValid())
- return 0;
-
- if (options & TextureCanUseAtlas)
- return d->sgRenderContext->createTexture(image);
- else
- return d->sgRenderContext->createTextureNoAtlas(image);
+ if (!d->sgRenderContext->isValid())
+ return 0;
+ uint flags = 0;
+ if (options & TextureCanUseAtlas) flags |= QSGRenderContext::CreateTexture_Atlas;
+ if (!(options & TextureIsOpaque)) flags |= QSGRenderContext::CreateTexture_Alpha;
+ return d->sgRenderContext->createTexture(image, flags);
}
/*!
diff --git a/src/quick/scenegraph/util/qsgengine.h b/src/quick/scenegraph/util/qsgengine.h
index 9a74a02aa1..325d3a9ca2 100644
--- a/src/quick/scenegraph/util/qsgengine.h
+++ b/src/quick/scenegraph/util/qsgengine.h
@@ -52,7 +52,8 @@ public:
enum CreateTextureOption {
TextureHasAlphaChannel = 0x0001,
TextureOwnsGLTexture = 0x0004,
- TextureCanUseAtlas = 0x0008
+ TextureCanUseAtlas = 0x0008,
+ TextureIsOpaque = 0x0010
};
Q_DECLARE_FLAGS(CreateTextureOptions, CreateTextureOption)
diff --git a/src/quick/util/qquickanimation_p.h b/src/quick/util/qquickanimation_p.h
index 0f6224a831..c4d5cd20cd 100644
--- a/src/quick/util/qquickanimation_p.h
+++ b/src/quick/util/qquickanimation_p.h
@@ -57,7 +57,6 @@ class Q_QUICK_PRIVATE_EXPORT QQuickAbstractAnimation : public QObject, public QQ
Q_INTERFACES(QQmlParserStatus)
Q_INTERFACES(QQmlPropertyValueSource)
- Q_ENUMS(Loops)
Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged)
Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged)
Q_PROPERTY(bool alwaysRunToEnd READ alwaysRunToEnd WRITE setAlwaysRunToEnd NOTIFY alwaysRunToEndChanged)
@@ -75,6 +74,7 @@ public:
virtual ~QQuickAbstractAnimation();
enum Loops { Infinite = -2 };
+ Q_ENUM(Loops)
bool isRunning() const;
void setRunning(bool);
@@ -367,7 +367,6 @@ class Q_QUICK_PRIVATE_EXPORT QQuickRotationAnimation : public QQuickPropertyAnim
{
Q_OBJECT
Q_DECLARE_PRIVATE(QQuickRotationAnimation)
- Q_ENUMS(RotationDirection)
Q_PROPERTY(qreal from READ from WRITE setFrom)
Q_PROPERTY(qreal to READ to WRITE setTo)
@@ -384,6 +383,7 @@ public:
void setTo(qreal);
enum RotationDirection { Numerical, Shortest, Clockwise, Counterclockwise };
+ Q_ENUM(RotationDirection)
RotationDirection direction() const;
void setDirection(RotationDirection direction);
diff --git a/src/quick/util/qquickanimation_p_p.h b/src/quick/util/qquickanimation_p_p.h
index 4224c6d9ed..b40e198cc1 100644
--- a/src/quick/util/qquickanimation_p_p.h
+++ b/src/quick/util/qquickanimation_p_p.h
@@ -164,7 +164,7 @@ private:
T *m_instance;
};
-class QQuickAbstractAnimationPrivate : public QObjectPrivate, public QAnimationJobChangeListener
+class Q_QUICK_PRIVATE_EXPORT QQuickAbstractAnimationPrivate : public QObjectPrivate, public QAnimationJobChangeListener
{
Q_DECLARE_PUBLIC(QQuickAbstractAnimation)
public:
diff --git a/src/quick/util/qquickanimator_p.h b/src/quick/util/qquickanimator_p.h
index 4d3a8e9e4f..7647e582b8 100644
--- a/src/quick/util/qquickanimator_p.h
+++ b/src/quick/util/qquickanimator_p.h
@@ -136,10 +136,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickRotationAnimator : public QQuickAnimator
Q_DECLARE_PRIVATE(QQuickRotationAnimator)
Q_PROPERTY(RotationDirection direction READ direction WRITE setDirection NOTIFY directionChanged)
- Q_ENUMS(RotationDirection)
-
public:
enum RotationDirection { Numerical, Shortest, Clockwise, Counterclockwise };
+ Q_ENUM(RotationDirection)
QQuickRotationAnimator(QObject *parent = 0);
diff --git a/src/quick/util/qquickanimatorjob.cpp b/src/quick/util/qquickanimatorjob.cpp
index 2a8e3c281c..0182f8abfb 100644
--- a/src/quick/util/qquickanimatorjob.cpp
+++ b/src/quick/util/qquickanimatorjob.cpp
@@ -126,9 +126,8 @@ void QQuickAnimatorProxyJob::updateState(QAbstractAnimationJob::State newState,
m_controller->startJob(this, m_job);
} else if (newState == Stopped) {
syncBackCurrentValues();
- if (m_internalState == State_Starting)
- m_internalState = State_Stopped;
- else if (m_controller) {
+ m_internalState = State_Stopped;
+ if (m_controller) {
m_controller->stopJob(this, m_job);
}
}
diff --git a/src/quick/util/qquickanimatorjob_p.h b/src/quick/util/qquickanimatorjob_p.h
index f8f40b4705..ca70aecb8e 100644
--- a/src/quick/util/qquickanimatorjob_p.h
+++ b/src/quick/util/qquickanimatorjob_p.h
@@ -151,7 +151,6 @@ protected:
int m_duration;
- uint m_feedback : 1;
uint m_isTransform : 1;
uint m_isUniform : 1;
uint m_hasBeenRunning : 1;
diff --git a/src/quick/util/qquickfontloader_p.h b/src/quick/util/qquickfontloader_p.h
index b6ca0b3c94..507d0210ee 100644
--- a/src/quick/util/qquickfontloader_p.h
+++ b/src/quick/util/qquickfontloader_p.h
@@ -46,7 +46,6 @@ class Q_AUTOTEST_EXPORT QQuickFontLoader : public QObject
{
Q_OBJECT
Q_DECLARE_PRIVATE(QQuickFontLoader)
- Q_ENUMS(Status)
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
@@ -54,6 +53,7 @@ class Q_AUTOTEST_EXPORT QQuickFontLoader : public QObject
public:
enum Status { Null = 0, Ready, Loading, Error };
+ Q_ENUM(Status)
QQuickFontLoader(QObject *parent = 0);
~QQuickFontLoader();
diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp
index 6aa7bedc5b..0680a49d6d 100644
--- a/src/quick/util/qquickglobal.cpp
+++ b/src/quick/util/qquickglobal.cpp
@@ -285,6 +285,7 @@ public:
QV4::ScopedValue vbold(scope, obj->get((s = v4->newString(QStringLiteral("bold")))));
QV4::ScopedValue vcap(scope, obj->get((s = v4->newString(QStringLiteral("capitalization")))));
QV4::ScopedValue vfam(scope, obj->get((s = v4->newString(QStringLiteral("family")))));
+ QV4::ScopedValue vstyle(scope, obj->get((s = v4->newString(QStringLiteral("styleName")))));
QV4::ScopedValue vital(scope, obj->get((s = v4->newString(QStringLiteral("italic")))));
QV4::ScopedValue vlspac(scope, obj->get((s = v4->newString(QStringLiteral("letterSpacing")))));
QV4::ScopedValue vpixsz(scope, obj->get((s = v4->newString(QStringLiteral("pixelSize")))));
@@ -307,6 +308,10 @@ public:
retn.setFamily(vfam->toQString());
if (ok) *ok = true;
}
+ if (vstyle->isString()) {
+ retn.setStyleName(vstyle->toQString());
+ if (ok) *ok = true;
+ }
if (vital->isBoolean()) {
retn.setItalic(vital->booleanValue());
if (ok) *ok = true;
diff --git a/src/quick/util/qquickimageprovider.cpp b/src/quick/util/qquickimageprovider.cpp
index a231209cd0..89615a2079 100644
--- a/src/quick/util/qquickimageprovider.cpp
+++ b/src/quick/util/qquickimageprovider.cpp
@@ -33,6 +33,9 @@
#include "qquickimageprovider.h"
+#include "qquickpixmapcache_p.h"
+#include <QtQuick/private/qsgcontext_p.h>
+
QT_BEGIN_NAMESPACE
class QQuickImageProviderPrivate
@@ -95,6 +98,23 @@ QImage QQuickTextureFactory::image() const
return QImage();
}
+/*!
+ Returns a QQuickTextureFactory holding given the image.
+
+ \since 5.6
+ */
+
+QQuickTextureFactory *QQuickTextureFactory::textureFactoryForImage(const QImage &image)
+{
+ if (image.isNull())
+ return 0;
+ QQuickTextureFactory *texture = QSGContext::createTextureFactoryFromImage(image);
+ if (texture)
+ return texture;
+ return new QQuickDefaultTextureFactory(image);
+}
+
+
/*!
\fn QSGTexture *QQuickTextureFactory::createTexture(QQuickWindow *window) const
@@ -118,6 +138,68 @@ QImage QQuickTextureFactory::image() const
/*!
+ \class QQuickImageResponse
+ \since 5.6
+ \brief The QQuickImageResponse class provides an interface for asynchronous image loading in QQuickAsyncImageProvider.
+ \inmodule QtQuick
+
+ The purpose of an image response is to provide a way for image provider jobs to be executed
+ in an asynchronous way.
+
+ Responses are deleted via \l deleteLater once the finished() signal has been emitted.
+ If you are using QRunnable as base for your QQuickImageResponse
+ ensure automatic deletion is disabled.
+
+ \sa QQuickImageProvider
+*/
+
+/*!
+ Constructs the image response
+*/
+QQuickImageResponse::QQuickImageResponse()
+{
+}
+
+/*!
+ Destructs the image response
+*/
+QQuickImageResponse::~QQuickImageResponse()
+{
+}
+
+/*!
+ Returns the error string for the job execution. An empty string means no error.
+*/
+QString QQuickImageResponse::errorString() const
+{
+ return QString();
+}
+
+/*!
+ This method is used to communicate that the response is no longer required by the engine.
+
+ It may be reimplemented to cancel a request in the provider side, however, it is not mandatory.
+*/
+void QQuickImageResponse::cancel()
+{
+}
+
+/*!
+ \fn void QQuickImageResponse::finished()
+
+ Signals that the job execution has finished (be it successfully, because an error happened or because it was cancelled).
+ */
+
+/*!
+ \fn QQuickTextureFactory *QQuickImageResponse::textureFactory() const
+
+ Returns the texture factory for the job. You can use QQuickTextureFactory::textureFactoryForImage
+ if your provider works with QImage. This method is only called when the error string is not empty and the
+ engine takes ownership of the returned QQuickTextureFactory.
+ */
+
+
+/*!
\class QQuickImageProvider
\since 5.0
\inmodule QtQuick
@@ -213,7 +295,7 @@ QImage QQuickTextureFactory::image() const
To force asynchronous image loading, even for image sources that do not
have the \c asynchronous property set to \c true, you may pass the
- \c QQuickImageProvider::ForceAsynchronousImageLoading flag to the image
+ \c QQmlImageProviderBase::ForceAsynchronousImageLoading flag to the image
provider constructor. This ensures that all image requests for the
provider are handled in a separate thread.
@@ -223,6 +305,12 @@ QImage QQuickTextureFactory::image() const
if \l {Image::}{asynchronous} is set to \c true, the value is ignored
and the image is loaded synchronously.
+ Asynchronous image loading for providers of type other than ImageResponse are
+ executed on a single thread per engine basis. That means that a slow image provider
+ will block the loading of any other request. To avoid that we suggest using QQuickAsyncImageProvider
+ and implement threading on the provider side via a \c QThreadPool or similar.
+ See the \l {imageresponseprovider}{Image Response Provider Example} for a complete implementation.
+
\section2 Image caching
@@ -365,5 +453,41 @@ QQuickTextureFactory *QQuickImageProvider::requestTexture(const QString &id, QSi
return 0;
}
+/*!
+ \class QQuickAsyncImageProvider
+ \since 5.6
+ \inmodule QtQuick
+ \brief The QQuickAsyncImageProvider class provides an interface for for asynchronous control of QML image requests.
+
+ \sa QQuickImageProvider
+*/
+QQuickAsyncImageProvider::QQuickAsyncImageProvider()
+ : QQuickImageProvider(ImageResponse, ForceAsynchronousImageLoading)
+ , d(0) // just as a placeholder in case we need it for the future
+{
+ Q_UNUSED(d);
+}
+
+QQuickAsyncImageProvider::~QQuickAsyncImageProvider()
+{
+}
+
+/*!
+ \fn QQuickImageResponse *QQuickAsyncImageProvider::requestImageResponse(const QString &id, const QSize &requestedSize)
+
+ Implement this method to return the job that will provide the texture with \a id.
+
+ The \a id is the requested image source, with the "image:" scheme and
+ provider identifier removed. For example, if the image \l{Image::}{source}
+ was "image://myprovider/icons/home", the given \a id would be "icons/home".
+
+ The \a requestedSize corresponds to the \l {Image::sourceSize} requested by
+ an Image item. If \a requestedSize is a valid size, the image
+ returned should be of that size.
+
+ \note this method may be called by multiple threads, so ensure the
+ implementation of this method is reentrant.
+*/
+
QT_END_NAMESPACE
diff --git a/src/quick/util/qquickimageprovider.h b/src/quick/util/qquickimageprovider.h
index a2b510f606..cc03eb0fa0 100644
--- a/src/quick/util/qquickimageprovider.h
+++ b/src/quick/util/qquickimageprovider.h
@@ -43,6 +43,7 @@ QT_BEGIN_NAMESPACE
class QQuickImageProviderPrivate;
+class QQuickAsyncImageProviderPrivate;
class QSGTexture;
class QQuickWindow;
@@ -56,6 +57,25 @@ public:
virtual QSize textureSize() const = 0;
virtual int textureByteCount() const = 0;
virtual QImage image() const;
+
+ static QQuickTextureFactory *textureFactoryForImage(const QImage &image);
+};
+
+class Q_QUICK_EXPORT QQuickImageResponse : public QObject
+{
+Q_OBJECT
+public:
+ QQuickImageResponse();
+ virtual ~QQuickImageResponse();
+
+ virtual QQuickTextureFactory *textureFactory() const = 0;
+ virtual QString errorString() const;
+
+public Q_SLOTS:
+ virtual void cancel();
+
+Q_SIGNALS:
+ void finished();
};
class Q_QUICK_EXPORT QQuickImageProvider : public QQmlImageProviderBase
@@ -81,6 +101,18 @@ private:
QQuickImageProviderPrivate *d;
};
+class Q_QUICK_EXPORT QQuickAsyncImageProvider : public QQuickImageProvider
+{
+public:
+ QQuickAsyncImageProvider();
+ virtual ~QQuickAsyncImageProvider();
+
+ virtual QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize) = 0;
+
+private:
+ QQuickAsyncImageProviderPrivate *d;
+};
+
QT_END_NAMESPACE
#endif // QQUICKIMAGEPROVIDER_H
diff --git a/src/quick/util/qquickpath_p.h b/src/quick/util/qquickpath_p.h
index eea313eeb1..5230a3cdea 100644
--- a/src/quick/util/qquickpath_p.h
+++ b/src/quick/util/qquickpath_p.h
@@ -265,7 +265,7 @@ public:
: QQuickCurve(parent), _radiusX(0), _radiusY(0), _useLargeArc(false), _direction(Clockwise) {}
enum ArcDirection { Clockwise, Counterclockwise };
- Q_ENUMS(ArcDirection)
+ Q_ENUM(ArcDirection)
qreal radiusX() const;
void setRadiusX(qreal);
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp
index ddf2ae2393..6f6e91ec99 100644
--- a/src/quick/util/qquickpixmapcache.cpp
+++ b/src/quick/util/qquickpixmapcache.cpp
@@ -44,7 +44,6 @@
#include <qpa/qplatformintegration.h>
#include <QtQuick/private/qsgtexture_p.h>
-#include <QtQuick/private/qsgcontext_p.h>
#include <QQuickWindow>
#include <QCoreApplication>
@@ -67,7 +66,7 @@
#include <private/qquickprofiler_p.h>
-#define IMAGEREQUEST_MAX_REQUEST_COUNT 8
+#define IMAGEREQUEST_MAX_NETWORK_REQUEST_COUNT 8
#define IMAGEREQUEST_MAX_REDIRECT_RECURSION 16
#define CACHE_EXPIRE_TIME 30
#define CACHE_REMOVAL_FRACTION 4
@@ -115,16 +114,6 @@ QSGTexture *QQuickDefaultTextureFactory::createTexture(QQuickWindow *window) con
return t;
}
-static QQuickTextureFactory *textureFactoryForImage(const QImage &image)
-{
- if (image.isNull())
- return 0;
- QQuickTextureFactory *texture = QSGContext::createTextureFactoryFromImage(image);
- if (texture)
- return texture;
- return new QQuickDefaultTextureFactory(image);
-}
-
class QQuickPixmapReader;
class QQuickPixmapData;
class QQuickPixmapReply : public QObject
@@ -181,6 +170,7 @@ public:
virtual bool event(QEvent *e);
private slots:
void networkRequestDone();
+ void asyncResponseFinished();
private:
QQuickPixmapReader *reader;
};
@@ -205,8 +195,9 @@ protected:
private:
friend class QQuickPixmapReaderThreadObject;
void processJobs();
- void processJob(QQuickPixmapReply *, const QUrl &, const QSize &, AutoTransform);
+ void processJob(QQuickPixmapReply *, const QUrl &, const QString &, AutoTransform, QQuickImageProvider::ImageType, QQuickImageProvider *);
void networkRequestDone(QNetworkReply *);
+ void asyncResponseFinished(QQuickImageResponse *);
QList<QQuickPixmapReply*> jobs;
QList<QQuickPixmapReply*> cancelled;
@@ -220,7 +211,8 @@ private:
QNetworkAccessManager *networkAccessManager();
QNetworkAccessManager *accessManager;
- QHash<QNetworkReply*,QQuickPixmapReply*> replies;
+ QHash<QNetworkReply*,QQuickPixmapReply*> networkJobs;
+ QHash<QQuickImageResponse*,QQuickPixmapReply*> asyncResponses;
static int replyDownloadProgress;
static int replyFinished;
@@ -439,8 +431,8 @@ QQuickPixmapReader::~QQuickPixmapReader()
delete reply;
}
jobs.clear();
- QList<QQuickPixmapReply*> activeJobs = replies.values();
- foreach (QQuickPixmapReply *reply, activeJobs) {
+ QList<QQuickPixmapReply*> activeJobs = networkJobs.values() + asyncResponses.values();
+ foreach (QQuickPixmapReply *reply, activeJobs ) {
if (reply->loading) {
cancelled.append(reply);
reply->data = 0;
@@ -455,7 +447,7 @@ QQuickPixmapReader::~QQuickPixmapReader()
void QQuickPixmapReader::networkRequestDone(QNetworkReply *reply)
{
- QQuickPixmapReply *job = replies.take(reply);
+ QQuickPixmapReply *job = networkJobs.take(reply);
if (job) {
job->redirectCount++;
@@ -472,7 +464,7 @@ void QQuickPixmapReader::networkRequestDone(QNetworkReply *reply)
QMetaObject::connect(reply, replyDownloadProgress, job, downloadProgress);
QMetaObject::connect(reply, replyFinished, threadObject, threadNetworkRequestDone);
- replies.insert(reply, job);
+ networkJobs.insert(reply, job);
return;
}
}
@@ -494,7 +486,7 @@ void QQuickPixmapReader::networkRequestDone(QNetworkReply *reply)
// send completion event to the QQuickPixmapReply
mutex.lock();
if (!cancelled.contains(job))
- job->postReply(error, errorString, readSize, textureFactoryForImage(image));
+ job->postReply(error, errorString, readSize, QQuickTextureFactory::textureFactoryForImage(image));
mutex.unlock();
}
reply->deleteLater();
@@ -503,6 +495,34 @@ void QQuickPixmapReader::networkRequestDone(QNetworkReply *reply)
threadObject->processJobs();
}
+void QQuickPixmapReader::asyncResponseFinished(QQuickImageResponse *response)
+{
+ QQuickPixmapReply *job = asyncResponses.take(response);
+
+ if (job) {
+ QQuickTextureFactory *t = 0;
+ QQuickPixmapReply::ReadError error = QQuickPixmapReply::NoError;
+ QString errorString;
+ QSize readSize;
+ if (!response->errorString().isEmpty()) {
+ error = QQuickPixmapReply::Loading;
+ errorString = response->errorString();
+ } else {
+ t = response->textureFactory();
+ }
+ mutex.lock();
+ if (!cancelled.contains(job))
+ job->postReply(error, errorString, t ? t->textureSize() : QSize(), t);
+ else
+ delete t;
+ mutex.unlock();
+ }
+ response->deleteLater();
+
+ // kick off event loop again incase we have dropped below max request count
+ threadObject->processJobs();
+}
+
QQuickPixmapReaderThreadObject::QQuickPixmapReaderThreadObject(QQuickPixmapReader *i)
: reader(i)
{
@@ -529,6 +549,12 @@ void QQuickPixmapReaderThreadObject::networkRequestDone()
reader->networkRequestDone(reply);
}
+void QQuickPixmapReaderThreadObject::asyncResponseFinished()
+{
+ QQuickImageResponse *response = static_cast<QQuickImageResponse *>(sender());
+ reader->asyncResponseFinished(response);
+}
+
void QQuickPixmapReader::processJobs()
{
QMutexLocker locker(&mutex);
@@ -538,16 +564,22 @@ void QQuickPixmapReader::processJobs()
return; // Nothing else to do
// Clean cancelled jobs
- if (cancelled.count()) {
+ if (!cancelled.isEmpty()) {
for (int i = 0; i < cancelled.count(); ++i) {
QQuickPixmapReply *job = cancelled.at(i);
- QNetworkReply *reply = replies.key(job, 0);
+ QNetworkReply *reply = networkJobs.key(job, 0);
if (reply) {
- replies.remove(reply);
+ networkJobs.remove(reply);
if (reply->isRunning()) {
// cancel any jobs already started
reply->close();
}
+ } else {
+ QQuickImageResponse *asyncResponse = asyncResponses.key(job);
+ if (asyncResponse) {
+ asyncResponses.remove(asyncResponse);
+ asyncResponse->cancel();
+ }
}
PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingError>(job->url));
// deleteLater, since not owned by this thread
@@ -560,27 +592,34 @@ void QQuickPixmapReader::processJobs()
// Find a job we can use
bool usableJob = false;
for (int i = jobs.count() - 1; !usableJob && i >= 0; i--) {
- QQuickPixmapReply *runningJob = jobs[i];
- const QUrl url = runningJob->url;
+ QQuickPixmapReply *job = jobs[i];
+ const QUrl url = job->url;
+ QString localFile;
+ QQuickImageProvider::ImageType imageType = QQuickImageProvider::Invalid;
+ QQuickImageProvider *provider = 0;
if (url.scheme() == QLatin1String("image")) {
+ provider = static_cast<QQuickImageProvider *>(engine->imageProvider(imageProviderId(url)));
+ if (provider)
+ imageType = provider->imageType();
+
usableJob = true;
} else {
- const QString localFile = QQmlFile::urlToLocalFileOrQrc(url);
- usableJob = !localFile.isEmpty() || replies.count() < IMAGEREQUEST_MAX_REQUEST_COUNT;
+ localFile = QQmlFile::urlToLocalFileOrQrc(url);
+ usableJob = !localFile.isEmpty() || networkJobs.count() < IMAGEREQUEST_MAX_NETWORK_REQUEST_COUNT;
}
+
if (usableJob) {
jobs.removeAt(i);
- runningJob->loading = true;
+ job->loading = true;
PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingStarted>(url));
- QSize requestSize = runningJob->requestSize;
- AutoTransform autoTransform = runningJob->autoTransform;
+ AutoTransform autoTransform = job->autoTransform;
locker.unlock();
- processJob(runningJob, url, requestSize, autoTransform);
+ processJob(job, url, localFile, autoTransform, imageType, provider);
locker.relock();
}
}
@@ -591,79 +630,97 @@ void QQuickPixmapReader::processJobs()
}
}
-void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &url,
- const QSize &requestSize, AutoTransform autoTransform)
+void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &url, const QString &localFile,
+ AutoTransform autoTransform, QQuickImageProvider::ImageType imageType, QQuickImageProvider *provider)
{
// fetch
if (url.scheme() == QLatin1String("image")) {
// Use QQuickImageProvider
QSize readSize;
- QQuickImageProvider::ImageType imageType = QQuickImageProvider::Invalid;
- QQuickImageProvider *provider = static_cast<QQuickImageProvider *>(engine->imageProvider(imageProviderId(url)));
- if (provider)
- imageType = provider->imageType();
+ switch (imageType) {
+ case QQuickImageProvider::Invalid:
+ {
+ QString errorStr = QQuickPixmap::tr("Invalid image provider: %1").arg(url.toString());
+ mutex.lock();
+ if (!cancelled.contains(runningJob))
+ runningJob->postReply(QQuickPixmapReply::Loading, errorStr, readSize, 0);
+ mutex.unlock();
+ break;
+ }
- if (imageType == QQuickImageProvider::Invalid) {
- QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::Loading;
- QString errorStr = QQuickPixmap::tr("Invalid image provider: %1").arg(url.toString());
- QImage image;
- mutex.lock();
- if (!cancelled.contains(runningJob))
- runningJob->postReply(errorCode, errorStr, readSize, textureFactoryForImage(image));
- mutex.unlock();
- } else if (imageType == QQuickImageProvider::Image) {
- QImage image = provider->requestImage(imageId(url), &readSize, requestSize);
- QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::NoError;
- QString errorStr;
- if (image.isNull()) {
- errorCode = QQuickPixmapReply::Loading;
- errorStr = QQuickPixmap::tr("Failed to get image from provider: %1").arg(url.toString());
+ case QQuickImageProvider::Image:
+ {
+ QImage image = provider->requestImage(imageId(url), &readSize, runningJob->requestSize);
+ QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::NoError;
+ QString errorStr;
+ if (image.isNull()) {
+ errorCode = QQuickPixmapReply::Loading;
+ errorStr = QQuickPixmap::tr("Failed to get image from provider: %1").arg(url.toString());
+ }
+ mutex.lock();
+ if (!cancelled.contains(runningJob))
+ runningJob->postReply(errorCode, errorStr, readSize, QQuickTextureFactory::textureFactoryForImage(image));
+ mutex.unlock();
+ break;
}
- mutex.lock();
- if (!cancelled.contains(runningJob))
- runningJob->postReply(errorCode, errorStr, readSize, textureFactoryForImage(image));
- mutex.unlock();
- } else if (imageType == QQuickImageProvider::Pixmap) {
- const QPixmap pixmap = provider->requestPixmap(imageId(url), &readSize, requestSize);
- QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::NoError;
- QString errorStr;
- if (pixmap.isNull()) {
- errorCode = QQuickPixmapReply::Loading;
- errorStr = QQuickPixmap::tr("Failed to get image from provider: %1").arg(url.toString());
+
+ case QQuickImageProvider::Pixmap:
+ {
+ const QPixmap pixmap = provider->requestPixmap(imageId(url), &readSize, runningJob->requestSize);
+ QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::NoError;
+ QString errorStr;
+ if (pixmap.isNull()) {
+ errorCode = QQuickPixmapReply::Loading;
+ errorStr = QQuickPixmap::tr("Failed to get image from provider: %1").arg(url.toString());
+ }
+ mutex.lock();
+ if (!cancelled.contains(runningJob))
+ runningJob->postReply(errorCode, errorStr, readSize, QQuickTextureFactory::textureFactoryForImage(pixmap.toImage()));
+ mutex.unlock();
+ break;
}
- mutex.lock();
- if (!cancelled.contains(runningJob))
- runningJob->postReply(errorCode, errorStr, readSize, textureFactoryForImage(pixmap.toImage()));
- mutex.unlock();
- } else {
- QQuickTextureFactory *t = provider->requestTexture(imageId(url), &readSize, requestSize);
- QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::NoError;
- QString errorStr;
- if (!t) {
- errorCode = QQuickPixmapReply::Loading;
- errorStr = QQuickPixmap::tr("Failed to get texture from provider: %1").arg(url.toString());
+
+ case QQuickImageProvider::Texture:
+ {
+ QQuickTextureFactory *t = provider->requestTexture(imageId(url), &readSize, runningJob->requestSize);
+ QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::NoError;
+ QString errorStr;
+ if (!t) {
+ errorCode = QQuickPixmapReply::Loading;
+ errorStr = QQuickPixmap::tr("Failed to get texture from provider: %1").arg(url.toString());
+ }
+ mutex.lock();
+ if (!cancelled.contains(runningJob))
+ runningJob->postReply(errorCode, errorStr, readSize, t);
+ else
+ delete t;
+ mutex.unlock();
+ break;
}
- mutex.lock();
- if (!cancelled.contains(runningJob))
- runningJob->postReply(errorCode, errorStr, readSize, t);
- else
- delete t;
- mutex.unlock();
+ case QQuickImageProvider::ImageResponse:
+ {
+ QQuickAsyncImageProvider *asyncProvider = static_cast<QQuickAsyncImageProvider*>(provider);
+ QQuickImageResponse *response = asyncProvider->requestImageResponse(imageId(url), runningJob->requestSize);
+
+ QObject::connect(response, SIGNAL(finished()), threadObject, SLOT(asyncResponseFinished()));
+
+ asyncResponses.insert(response, runningJob);
+ break;
+ }
}
} else {
- QString lf = QQmlFile::urlToLocalFileOrQrc(url);
- if (!lf.isEmpty()) {
+ if (!localFile.isEmpty()) {
// Image is local - load/decode immediately
QImage image;
QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::NoError;
QString errorStr;
- QFile f(lf);
+ QFile f(localFile);
QSize readSize;
if (f.open(QIODevice::ReadOnly)) {
- if (!readImage(url, &f, &image, &errorStr, &readSize, requestSize, autoTransform))
+ if (!readImage(url, &f, &image, &errorStr, &readSize, runningJob->requestSize, autoTransform))
errorCode = QQuickPixmapReply::Loading;
} else {
errorStr = QQuickPixmap::tr("Cannot open: %1").arg(url.toString());
@@ -671,7 +728,7 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u
}
mutex.lock();
if (!cancelled.contains(runningJob))
- runningJob->postReply(errorCode, errorStr, readSize, textureFactoryForImage(image));
+ runningJob->postReply(errorCode, errorStr, readSize, QQuickTextureFactory::textureFactoryForImage(image));
mutex.unlock();
} else {
// Network resource
@@ -682,7 +739,7 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u
QMetaObject::connect(reply, replyDownloadProgress, runningJob, downloadProgress);
QMetaObject::connect(reply, replyFinished, threadObject, threadNetworkRequestDone);
- replies.insert(reply, runningJob);
+ networkJobs.insert(reply, runningJob);
}
}
}
@@ -775,8 +832,6 @@ inline uint qHash(const QQuickPixmapKey &key)
return qHash(*key.url) ^ (key.size->width()*7) ^ (key.size->height()*17) ^ (key.autoTransform * 0x5c5c5c5c);
}
-class QSGContext;
-
class QQuickPixmapStore : public QObject
{
Q_OBJECT
@@ -1084,7 +1139,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
QImage image = provider->requestImage(imageId(url), &readSize, requestSize);
if (!image.isNull()) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, textureFactoryForImage(image), readSize, requestSize, autoTransform, UsePluginDefault);
+ return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, autoTransform, UsePluginDefault);
}
}
case QQuickImageProvider::Pixmap:
@@ -1092,9 +1147,14 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
QPixmap pixmap = provider->requestPixmap(imageId(url), &readSize, requestSize);
if (!pixmap.isNull()) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, textureFactoryForImage(pixmap.toImage()), readSize, requestSize, autoTransform, UsePluginDefault);
+ return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(pixmap.toImage()), readSize, requestSize, autoTransform, UsePluginDefault);
}
}
+ case QQuickImageProvider::ImageResponse:
+ {
+ // Fall through, ImageResponse providers never get here
+ Q_ASSERT(imageType != QQuickImageProvider::ImageResponse && "Sync call to ImageResponse provider");
+ }
}
// provider has bad image type, or provider returned null image
@@ -1115,7 +1175,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
AutoTransform appliedTransform = autoTransform;
if (readImage(url, &f, &image, &errorString, &readSize, requestSize, appliedTransform)) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, textureFactoryForImage(image), readSize, requestSize, autoTransform, appliedTransform);
+ return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, autoTransform, appliedTransform);
}
errorString = QQuickPixmap::tr("Invalid image data: %1").arg(url.toString());
@@ -1252,7 +1312,7 @@ void QQuickPixmap::setImage(const QImage &p)
clear();
if (!p.isNull())
- d = new QQuickPixmapData(this, textureFactoryForImage(p));
+ d = new QQuickPixmapData(this, QQuickTextureFactory::textureFactoryForImage(p));
}
void QQuickPixmap::setPixmap(const QQuickPixmap &other)
diff --git a/src/quick/util/qquickprofiler.cpp b/src/quick/util/qquickprofiler.cpp
index d9132a9cb2..77ffda474a 100644
--- a/src/quick/util/qquickprofiler.cpp
+++ b/src/quick/util/qquickprofiler.cpp
@@ -33,8 +33,7 @@
#include "qquickprofiler_p.h"
#include <QCoreApplication>
-#include <private/qqmldebugservice_p.h>
-#include <private/qqmlprofilerservice_p.h>
+#include <private/qqmldebugserviceinterfaces_p.h>
QT_BEGIN_NAMESPACE
@@ -113,18 +112,22 @@ void QQuickProfilerData::toByteArrays(QList<QByteArray> &messages) const
qint64 QQuickProfiler::sendMessages(qint64 until, QList<QByteArray> &messages)
{
QMutexLocker lock(&m_dataMutex);
- while (next < m_data.size() && m_data[next].time <= until) {
- m_data[next++].toByteArrays(messages);
+ while (next < m_data.size()) {
+ if (m_data[next].time <= until)
+ m_data[next++].toByteArrays(messages);
+ else
+ return m_data[next].time;
}
- return next < m_data.size() ? m_data[next].time : -1;
+ m_data.clear();
+ next = 0;
+ return -1;
}
-void QQuickProfiler::initialize()
+void QQuickProfiler::initialize(QQmlProfilerService *service)
{
Q_ASSERT(s_instance == 0);
- QQmlProfilerService *service = QQmlProfilerService::instance();
s_instance = new QQuickProfiler(service);
- QQmlProfilerService::instance()->addGlobalProfiler(s_instance);
+ service->addGlobalProfiler(s_instance);
}
void animationTimerCallback(qint64 delta)
@@ -196,17 +199,12 @@ void QQuickProfiler::stopProfilingImpl()
{
QMutexLocker lock(&m_dataMutex);
featuresEnabled = 0;
- next = 0;
}
service->dataReady(this);
}
void QQuickProfiler::reportDataImpl()
{
- {
- QMutexLocker lock(&m_dataMutex);
- next = 0;
- }
service->dataReady(this);
}
diff --git a/src/quick/util/qquickprofiler_p.h b/src/quick/util/qquickprofiler_p.h
index aaed4bd60e..6b6e7fa062 100644
--- a/src/quick/util/qquickprofiler_p.h
+++ b/src/quick/util/qquickprofiler_p.h
@@ -318,7 +318,7 @@ public:
return featuresEnabled & (1 << QQuickProfiler::ProfileSceneGraph);
}
- static void initialize();
+ static void initialize(QQmlProfilerService *service);
virtual ~QQuickProfiler();
diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp
index 6c333c6b13..58d78a5d84 100644
--- a/src/quick/util/qquickpropertychanges.cpp
+++ b/src/quick/util/qquickpropertychanges.cpp
@@ -145,12 +145,12 @@ public:
QQmlBoundSignalExpressionPointer reverseExpression;
QQmlBoundSignalExpressionPointer rewindExpression;
- virtual void execute(Reason) {
+ virtual void execute() {
QQmlPropertyPrivate::setSignalExpression(property, expression);
}
virtual bool isReversable() { return true; }
- virtual void reverse(Reason) {
+ virtual void reverse() {
QQmlPropertyPrivate::setSignalExpression(property, reverseExpression);
}
@@ -464,10 +464,10 @@ QQuickPropertyChanges::ActionList QQuickPropertyChanges::actions()
// XXX TODO: add a static QQmlJavaScriptExpression::evaluate(QString)
// so that we can avoid creating then destroying the binding in this case.
a.toValue = newBinding->evaluate();
- newBinding->destroy();
+ delete newBinding;
} else {
newBinding->setTarget(prop);
- a.toBinding = QQmlAbstractBinding::getPointer(newBinding);
+ a.toBinding = newBinding;
a.deletableToBinding = true;
}
@@ -558,11 +558,7 @@ void QQuickPropertyChanges::changeValue(const QString &name, const QVariant &val
if (entry.name == name) {
expressionIterator.remove();
if (state() && state()->isStateActive()) {
- QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::binding(d->property(name));
- if (oldBinding) {
- QQmlPropertyPrivate::setBinding(d->property(name), 0);
- oldBinding->destroy();
- }
+ QQmlPropertyPrivate::removeBinding(d->property(name));
d->property(name).write(value);
}
@@ -624,15 +620,9 @@ void QQuickPropertyChanges::changeExpression(const QString &name, const QString
if (entry.name == name) {
entry.expression = expression;
if (state() && state()->isStateActive()) {
- QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::binding(d->property(name));
- if (oldBinding) {
- QQmlPropertyPrivate::setBinding(d->property(name), 0);
- oldBinding->destroy();
- }
-
QQmlBinding *newBinding = new QQmlBinding(expression, object(), qmlContext(this));
newBinding->setTarget(d->property(name));
- QQmlPropertyPrivate::setBinding(d->property(name), newBinding, QQmlPropertyPrivate::DontRemoveBinding | QQmlPropertyPrivate::BypassInterceptor);
+ QQmlPropertyPrivate::setBinding(newBinding, QQmlPropertyPrivate::None, QQmlPropertyPrivate::DontRemoveBinding | QQmlPropertyPrivate::BypassInterceptor);
}
return;
}
@@ -651,7 +641,7 @@ void QQuickPropertyChanges::changeExpression(const QString &name, const QString
QQmlBinding *newBinding = new QQmlBinding(expression, object(), qmlContext(this));
newBinding->setTarget(d->property(name));
- QQmlPropertyPrivate::setBinding(d->property(name), newBinding, QQmlPropertyPrivate::DontRemoveBinding | QQmlPropertyPrivate::BypassInterceptor);
+ QQmlPropertyPrivate::setBinding(newBinding, QQmlPropertyPrivate::None, QQmlPropertyPrivate::DontRemoveBinding | QQmlPropertyPrivate::BypassInterceptor);
} else {
QQuickStateAction action;
action.restore = restoreEntryValues();
@@ -666,10 +656,10 @@ void QQuickPropertyChanges::changeExpression(const QString &name, const QString
// XXX TODO: add a static QQmlJavaScriptExpression::evaluate(QString)
// so that we can avoid creating then destroying the binding in this case.
action.toValue = newBinding->evaluate();
- newBinding->destroy();
+ delete newBinding;
} else {
- newBinding->setTarget(d->property(name));
- action.toBinding = QQmlAbstractBinding::getPointer(newBinding);
+ newBinding->setTarget(action.property);
+ action.toBinding = newBinding;
action.deletableToBinding = true;
state()->addEntryToRevertList(action);
@@ -677,7 +667,7 @@ void QQuickPropertyChanges::changeExpression(const QString &name, const QString
if (oldBinding)
oldBinding->setEnabled(false, QQmlPropertyPrivate::DontRemoveBinding | QQmlPropertyPrivate::BypassInterceptor);
- QQmlPropertyPrivate::setBinding(action.property, newBinding, QQmlPropertyPrivate::DontRemoveBinding | QQmlPropertyPrivate::BypassInterceptor);
+ QQmlPropertyPrivate::setBinding(newBinding, QQmlPropertyPrivate::None, QQmlPropertyPrivate::DontRemoveBinding | QQmlPropertyPrivate::BypassInterceptor);
}
}
}
diff --git a/src/quick/util/qquicksmoothedanimation_p.h b/src/quick/util/qquicksmoothedanimation_p.h
index 68479aa629..efac9217f5 100644
--- a/src/quick/util/qquicksmoothedanimation_p.h
+++ b/src/quick/util/qquicksmoothedanimation_p.h
@@ -47,7 +47,6 @@ class Q_AUTOTEST_EXPORT QQuickSmoothedAnimation : public QQuickNumberAnimation
{
Q_OBJECT
Q_DECLARE_PRIVATE(QQuickSmoothedAnimation)
- Q_ENUMS(ReversingMode)
Q_PROPERTY(qreal velocity READ velocity WRITE setVelocity NOTIFY velocityChanged)
Q_PROPERTY(ReversingMode reversingMode READ reversingMode WRITE setReversingMode NOTIFY reversingModeChanged)
@@ -55,6 +54,7 @@ class Q_AUTOTEST_EXPORT QQuickSmoothedAnimation : public QQuickNumberAnimation
public:
enum ReversingMode { Eased, Immediate, Sync };
+ Q_ENUM(ReversingMode)
QQuickSmoothedAnimation(QObject *parent = 0);
~QQuickSmoothedAnimation();
diff --git a/src/quick/util/qquickstate.cpp b/src/quick/util/qquickstate.cpp
index 98d7a76c7e..be676680a6 100644
--- a/src/quick/util/qquickstate.cpp
+++ b/src/quick/util/qquickstate.cpp
@@ -78,7 +78,7 @@ QQuickStateActionEvent::~QQuickStateActionEvent()
{
}
-void QQuickStateActionEvent::execute(Reason)
+void QQuickStateActionEvent::execute()
{
}
@@ -87,7 +87,7 @@ bool QQuickStateActionEvent::isReversable()
return false;
}
-void QQuickStateActionEvent::reverse(Reason)
+void QQuickStateActionEvent::reverse()
{
}
@@ -157,11 +157,6 @@ QQuickState::~QQuickState()
Q_D(QQuickState);
if (d->group)
d->group->removeState(this);
-
- foreach (const QQuickSimpleAction &action, d->revertList) {
- if (action.binding())
- action.binding()->destroy();
- }
}
/*!
@@ -361,8 +356,7 @@ void QQuickState::cancel()
void QQuickStateAction::deleteFromBinding()
{
if (fromBinding) {
- QQmlPropertyPrivate::setBinding(property, 0);
- fromBinding->destroy();
+ QQmlPropertyPrivate::removeBinding(property);
fromBinding = 0;
}
}
@@ -413,9 +407,6 @@ bool QQuickState::changeBindingInRevertList(QObject *target, const QString &name
while (revertListIterator.hasNext()) {
QQuickSimpleAction &simpleAction = revertListIterator.next();
if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty() == name) {
- if (simpleAction.binding())
- simpleAction.binding()->destroy();
-
simpleAction.setBinding(binding);
return true;
}
@@ -435,15 +426,11 @@ bool QQuickState::removeEntryFromRevertList(QObject *target, const QString &name
while (revertListIterator.hasNext()) {
QQuickSimpleAction &simpleAction = revertListIterator.next();
if (simpleAction.property().object() == target && simpleAction.property().name() == name) {
- QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::binding(simpleAction.property());
- if (oldBinding) {
- QQmlPropertyPrivate::setBinding(simpleAction.property(), 0);
- oldBinding->destroy();
- }
+ QQmlPropertyPrivate::removeBinding(simpleAction.property());
simpleAction.property().write(simpleAction.value());
if (simpleAction.binding())
- QQmlPropertyPrivate::setBinding(simpleAction.property(), simpleAction.binding());
+ QQmlPropertyPrivate::setBinding(simpleAction.binding());
revertListIterator.remove();
return true;
@@ -473,15 +460,11 @@ void QQuickState::removeAllEntriesFromRevertList(QObject *target)
while (revertListIterator.hasNext()) {
QQuickSimpleAction &simpleAction = revertListIterator.next();
if (simpleAction.property().object() == target) {
- QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::binding(simpleAction.property());
- if (oldBinding) {
- QQmlPropertyPrivate::setBinding(simpleAction.property(), 0);
- oldBinding->destroy();
- }
+ QQmlPropertyPrivate::removeBinding(simpleAction.property());
simpleAction.property().write(simpleAction.value());
if (simpleAction.binding())
- QQmlPropertyPrivate::setBinding(simpleAction.property(), simpleAction.binding());
+ QQmlPropertyPrivate::setBinding(simpleAction.binding());
revertListIterator.remove();
}
@@ -494,18 +477,15 @@ void QQuickState::addEntriesToRevertList(const QList<QQuickStateAction> &actionL
Q_D(QQuickState);
if (isStateActive()) {
QList<QQuickSimpleAction> simpleActionList;
+ simpleActionList.reserve(actionList.count());
QListIterator<QQuickStateAction> actionListIterator(actionList);
while(actionListIterator.hasNext()) {
const QQuickStateAction &action = actionListIterator.next();
QQuickSimpleAction simpleAction(action);
action.property.write(action.toValue);
- if (!action.toBinding.isNull()) {
- QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::binding(simpleAction.property());
- if (oldBinding)
- QQmlPropertyPrivate::setBinding(simpleAction.property(), 0);
- QQmlPropertyPrivate::setBinding(simpleAction.property(), action.toBinding.data(), QQmlPropertyPrivate::DontRemoveBinding);
- }
+ if (action.toBinding)
+ QQmlPropertyPrivate::setBinding(action.toBinding.data());
simpleActionList.append(simpleAction);
}
@@ -619,7 +599,7 @@ void QQuickState::apply(QQuickTransition *trans, QQuickState *revert)
for (int jj = 0; jj < d->revertList.count(); ++jj) {
if (d->revertList.at(jj).property() == action.property) {
found = true;
- if (d->revertList.at(jj).binding() != action.fromBinding) {
+ if (d->revertList.at(jj).binding() != action.fromBinding.data()) {
action.deleteFromBinding();
}
break;
@@ -663,16 +643,13 @@ void QQuickState::apply(QQuickTransition *trans, QQuickState *revert)
}
if (!found) {
QVariant cur = d->revertList.at(ii).property().read();
- QQmlAbstractBinding *delBinding =
- QQmlPropertyPrivate::setBinding(d->revertList.at(ii).property(), 0);
- if (delBinding)
- delBinding->destroy();
+ QQmlPropertyPrivate::removeBinding(d->revertList.at(ii).property());
QQuickStateAction a;
a.property = d->revertList.at(ii).property();
a.fromValue = cur;
a.toValue = d->revertList.at(ii).value();
- a.toBinding = QQmlAbstractBinding::getPointer(d->revertList.at(ii).binding());
+ a.toBinding = d->revertList.at(ii).binding();
a.specifiedObject = d->revertList.at(ii).specifiedObject();
a.specifiedProperty = d->revertList.at(ii).specifiedProperty();
a.event = d->revertList.at(ii).event();
diff --git a/src/quick/util/qquickstate_p.h b/src/quick/util/qquickstate_p.h
index 0c774635d8..1870b70626 100644
--- a/src/quick/util/qquickstate_p.h
+++ b/src/quick/util/qquickstate_p.h
@@ -39,13 +39,14 @@
#include <QtCore/qobject.h>
#include <QtCore/qsharedpointer.h>
#include <private/qtquickglobal_p.h>
+#include <private/qqmlabstractbinding_p.h>
QT_BEGIN_NAMESPACE
class QQuickStateActionEvent;
-class QQmlAbstractBinding;
class QQmlBinding;
class QQmlExpression;
+
class QQuickStateAction
{
public:
@@ -63,8 +64,8 @@ public:
QVariant fromValue;
QVariant toValue;
- QQmlAbstractBinding *fromBinding;
- QWeakPointer<QQmlAbstractBinding> toBinding;
+ QQmlAbstractBinding::Ptr fromBinding;
+ QQmlAbstractBinding::Ptr toBinding;
QQuickStateActionEvent *event;
//strictly for matching
@@ -80,13 +81,12 @@ public:
virtual ~QQuickStateActionEvent();
enum EventType { Script, SignalHandler, ParentChange, AnchorChanges };
- enum Reason { ActualChange, FastForward };
virtual EventType type() const = 0;
- virtual void execute(Reason reason = ActualChange);
+ virtual void execute();
virtual bool isReversable();
- virtual void reverse(Reason reason = ActualChange);
+ virtual void reverse();
virtual void saveOriginals() {}
virtual bool needsCopy() { return false; }
virtual void copyOriginals(QQuickStateActionEvent *) {}
diff --git a/src/quick/util/qquickstate_p_p.h b/src/quick/util/qquickstate_p_p.h
index fc589f0d2d..e6ecb424e5 100644
--- a/src/quick/util/qquickstate_p_p.h
+++ b/src/quick/util/qquickstate_p_p.h
@@ -71,7 +71,7 @@ public:
if (state == StartState) {
m_value = a.fromValue;
if (QQmlPropertyPrivate::binding(m_property)) {
- m_binding = QQmlAbstractBinding::getPointer(QQmlPropertyPrivate::binding(m_property));
+ m_binding = QQmlPropertyPrivate::binding(m_property);
}
m_reverseEvent = true;
} else {
@@ -88,7 +88,7 @@ public:
QQuickSimpleAction(const QQuickSimpleAction &other)
: m_property(other.m_property),
m_value(other.m_value),
- m_binding(QQmlAbstractBinding::getPointer(other.binding())),
+ m_binding(other.binding()),
m_specifiedObject(other.m_specifiedObject),
m_specifiedProperty(other.m_specifiedProperty),
m_event(other.m_event),
@@ -100,7 +100,7 @@ public:
{
m_property = other.m_property;
m_value = other.m_value;
- m_binding = QQmlAbstractBinding::getPointer(other.binding());
+ m_binding = other.binding();
m_specifiedObject = other.m_specifiedObject;
m_specifiedProperty = other.m_specifiedProperty;
m_event = other.m_event;
@@ -131,7 +131,7 @@ public:
void setBinding(QQmlAbstractBinding *binding)
{
- m_binding = QQmlAbstractBinding::getPointer(binding);
+ m_binding = binding;
}
QQmlAbstractBinding *binding() const
@@ -162,7 +162,7 @@ public:
private:
QQmlProperty m_property;
QVariant m_value;
- QQmlAbstractBinding::Pointer m_binding;
+ QQmlAbstractBinding::Ptr m_binding;
QObject *m_specifiedObject;
QString m_specifiedProperty;
QQuickStateActionEvent *m_event;
diff --git a/src/quick/util/qquickstatechangescript.cpp b/src/quick/util/qquickstatechangescript.cpp
index 6d25b9791d..c276183d62 100644
--- a/src/quick/util/qquickstatechangescript.cpp
+++ b/src/quick/util/qquickstatechangescript.cpp
@@ -118,7 +118,7 @@ void QQuickStateChangeScript::setName(const QString &n)
d->name = n;
}
-void QQuickStateChangeScript::execute(Reason)
+void QQuickStateChangeScript::execute()
{
Q_D(QQuickStateChangeScript);
if (!d->script.isEmpty()) {
diff --git a/src/quick/util/qquickstatechangescript_p.h b/src/quick/util/qquickstatechangescript_p.h
index 4ff6f0db3e..6c019a43d2 100644
--- a/src/quick/util/qquickstatechangescript_p.h
+++ b/src/quick/util/qquickstatechangescript_p.h
@@ -62,7 +62,7 @@ public:
QString name() const;
void setName(const QString &);
- virtual void execute(Reason reason = ActualChange);
+ virtual void execute();
};
diff --git a/src/quick/util/qquickstyledtext.cpp b/src/quick/util/qquickstyledtext.cpp
index 6ed32c10e2..c411207121 100644
--- a/src/quick/util/qquickstyledtext.cpp
+++ b/src/quick/util/qquickstyledtext.cpp
@@ -182,7 +182,7 @@ void QQuickStyledText::parse(const QString &string, QTextLayout &layout,
void QQuickStyledTextPrivate::parse()
{
- QList<QTextLayout::FormatRange> ranges;
+ QVector<QTextLayout::FormatRange> ranges;
QStack<QTextCharFormat> formatStack;
QString drawText;
@@ -283,7 +283,7 @@ void QQuickStyledTextPrivate::parse()
}
layout.setText(drawText);
- layout.setAdditionalFormats(ranges);
+ layout.setFormats(ranges);
}
void QQuickStyledTextPrivate::appendText(const QString &textIn, int start, int length, QString &textOut)
diff --git a/src/quick/util/qquicksystempalette_p.h b/src/quick/util/qquicksystempalette_p.h
index 143efa1c12..fb898eb1fa 100644
--- a/src/quick/util/qquicksystempalette_p.h
+++ b/src/quick/util/qquicksystempalette_p.h
@@ -45,7 +45,6 @@ class QQuickSystemPalettePrivate;
class Q_AUTOTEST_EXPORT QQuickSystemPalette : public QObject
{
Q_OBJECT
- Q_ENUMS(ColorGroup)
Q_DECLARE_PRIVATE(QQuickSystemPalette)
Q_PROPERTY(QQuickSystemPalette::ColorGroup colorGroup READ colorGroup WRITE setColorGroup NOTIFY paletteChanged)
@@ -69,6 +68,7 @@ public:
~QQuickSystemPalette();
enum ColorGroup { Active = QPalette::Active, Inactive = QPalette::Inactive, Disabled = QPalette::Disabled };
+ Q_ENUM(ColorGroup)
QColor window() const;
QColor windowText() const;
diff --git a/src/quick/util/qquicktimeline.cpp b/src/quick/util/qquicktimeline.cpp
index 74754a0bfb..88fc03bba8 100644
--- a/src/quick/util/qquicktimeline.cpp
+++ b/src/quick/util/qquicktimeline.cpp
@@ -659,7 +659,7 @@ void QQuickTimeLine::complete()
*/
void QQuickTimeLine::clear()
{
- for (QQuickTimeLinePrivate::Ops::const_iterator iter = d->ops.begin(), cend = d->ops.end(); iter != cend; ++iter)
+ for (QQuickTimeLinePrivate::Ops::const_iterator iter = d->ops.cbegin(), cend = d->ops.cend(); iter != cend; ++iter)
iter.key()->_t = 0;
d->ops.clear();
d->length = 0;
diff --git a/src/quick/util/qquicktransitionmanager.cpp b/src/quick/util/qquicktransitionmanager.cpp
index 832596d9a2..3992df993c 100644
--- a/src/quick/util/qquicktransitionmanager.cpp
+++ b/src/quick/util/qquicktransitionmanager.cpp
@@ -101,8 +101,8 @@ void QQuickTransitionManager::complete()
void QQuickTransitionManagerPrivate::applyBindings()
{
foreach(const QQuickStateAction &action, bindingsList) {
- if (!action.toBinding.isNull()) {
- QQmlPropertyPrivate::setBinding(action.property, action.toBinding.data());
+ if (action.toBinding) {
+ QQmlPropertyPrivate::setBinding(action.toBinding.data());
} else if (action.event) {
if (action.reverseEvent)
action.event->reverse();
@@ -131,7 +131,7 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list,
if (action.toBinding)
d->bindingsList << action;
if (action.fromBinding)
- QQmlPropertyPrivate::setBinding(action.property, 0); // Disable current binding
+ QQmlPropertyPrivate::removeBinding(action.property); // Disable current binding
if (action.event && action.event->changesBindings()) { //### assume isReversable()?
d->bindingsList << action;
action.event->clearBindings();
@@ -146,24 +146,21 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list,
//
// This doesn't catch everything, and it might be a little fragile in
// some cases - but whatcha going to do?
- //
- // Note that we only fast forward if both a transition and bindings are
- // present, as it is unnecessary (and potentially expensive) otherwise.
if (transition && !d->bindingsList.isEmpty()) {
// Apply all the property and binding changes
for (int ii = 0; ii < applyList.size(); ++ii) {
const QQuickStateAction &action = applyList.at(ii);
- if (!action.toBinding.isNull()) {
- QQmlPropertyPrivate::setBinding(action.property, action.toBinding.data(), QQmlPropertyPrivate::BypassInterceptor | QQmlPropertyPrivate::DontRemoveBinding);
+ if (action.toBinding) {
+ QQmlPropertyPrivate::setBinding(action.toBinding.data(), QQmlPropertyPrivate::None, QQmlPropertyPrivate::BypassInterceptor | QQmlPropertyPrivate::DontRemoveBinding);
} else if (!action.event) {
QQmlPropertyPrivate::write(action.property, action.toValue, QQmlPropertyPrivate::BypassInterceptor | QQmlPropertyPrivate::DontRemoveBinding);
} else if (action.event->isReversable()) {
if (action.reverseEvent)
- action.event->reverse(QQuickStateActionEvent::FastForward);
+ action.event->reverse();
else
- action.event->execute(QQuickStateActionEvent::FastForward);
+ action.event->execute();
}
}
@@ -175,7 +172,7 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list,
continue;
}
const QQmlProperty &prop = action->property;
- if (!action->toBinding.isNull() || !action->toValue.isValid()) {
+ if (action->toBinding || !action->toValue.isValid()) {
action->toValue = prop.read();
}
}
@@ -192,7 +189,7 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list,
}
if (action.toBinding)
- QQmlPropertyPrivate::setBinding(action.property, 0); // Make sure this is disabled during the transition
+ QQmlPropertyPrivate::removeBinding(action.property); // Make sure this is disabled during the transition
QQmlPropertyPrivate::write(action.property, action.fromValue, QQmlPropertyPrivate::BypassInterceptor | QQmlPropertyPrivate::DontRemoveBinding);
}
@@ -269,10 +266,9 @@ void QQuickTransitionManager::cancel()
for(int i = 0; i < d->bindingsList.count(); ++i) {
QQuickStateAction action = d->bindingsList[i];
- if (!action.toBinding.isNull() && action.deletableToBinding) {
- QQmlPropertyPrivate::setBinding(action.property, 0);
- action.toBinding.data()->destroy();
- action.toBinding.clear();
+ if (action.toBinding && action.deletableToBinding) {
+ QQmlPropertyPrivate::removeBinding(action.property);
+ action.toBinding = 0;
action.deletableToBinding = false;
} else if (action.event) {
//### what do we do here?
diff --git a/src/quick/util/qquickutilmodule.cpp b/src/quick/util/qquickutilmodule.cpp
index 4d156a2d9a..4f6e49fa7a 100644
--- a/src/quick/util/qquickutilmodule.cpp
+++ b/src/quick/util/qquickutilmodule.cpp
@@ -49,6 +49,7 @@
#include "qquicktransition_p.h"
#include "qquickanimator_p.h"
#include "qquickshortcut_p.h"
+#include "qquickvalidator_p.h"
#include <qqmlinfo.h>
#include <private/qqmltypenotavailable_p.h>
#include <private/qquickanimationcontroller_p.h>
@@ -87,6 +88,13 @@ void QQuickUtilModule::defineModule()
qmlRegisterType<QQuickTransition>("QtQuick",2,0,"Transition");
qmlRegisterType<QQuickVector3dAnimation>("QtQuick",2,0,"Vector3dAnimation");
+#ifndef QT_NO_VALIDATOR
+ qmlRegisterType<QValidator>();
+ qmlRegisterType<QQuickIntValidator>("QtQuick",2,0,"IntValidator");
+ qmlRegisterType<QQuickDoubleValidator>("QtQuick",2,0,"DoubleValidator");
+ qmlRegisterType<QRegExpValidator>("QtQuick",2,0,"RegExpValidator");
+#endif
+
qmlRegisterUncreatableType<QQuickAnimator>("QtQuick", 2, 2, "Animator", QQuickAbstractAnimation::tr("Animator is an abstract class"));
qmlRegisterType<QQuickXAnimator>("QtQuick", 2, 2, "XAnimator");
qmlRegisterType<QQuickYAnimator>("QtQuick", 2, 2, "YAnimator");
diff --git a/src/quick/util/qquickvalidator.cpp b/src/quick/util/qquickvalidator.cpp
new file mode 100644
index 0000000000..3eebf5d77a
--- /dev/null
+++ b/src/quick/util/qquickvalidator.cpp
@@ -0,0 +1,221 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickvalidator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_VALIDATOR
+
+/*!
+ \qmltype IntValidator
+ \instantiates QIntValidator
+ \inqmlmodule QtQuick
+ \ingroup qtquick-text-utility
+ \brief Defines a validator for integer values
+
+ The IntValidator type provides a validator for integer values.
+
+ If no \l locale is set IntValidator uses the \l {QLocale::setDefault()}{default locale} to
+ interpret the number and will accept locale specific digits, group separators, and positive
+ and negative signs. In addition, IntValidator is always guaranteed to accept a number
+ formatted according to the "C" locale.
+*/
+
+QQuickIntValidator::QQuickIntValidator(QObject *parent)
+ : QIntValidator(parent)
+{
+}
+
+/*!
+ \qmlproperty string QtQuick::IntValidator::locale
+
+ This property holds the name of the locale used to interpret the number.
+
+ \sa {QtQml::Qt::locale()}{Qt.locale()}
+*/
+
+QString QQuickIntValidator::localeName() const
+{
+ return locale().name();
+}
+
+void QQuickIntValidator::setLocaleName(const QString &name)
+{
+ if (locale().name() != name) {
+ setLocale(QLocale(name));
+ emit localeNameChanged();
+ }
+}
+
+void QQuickIntValidator::resetLocaleName()
+{
+ QLocale defaultLocale;
+ if (locale() != defaultLocale) {
+ setLocale(defaultLocale);
+ emit localeNameChanged();
+ }
+}
+
+/*!
+ \qmlproperty int QtQuick::IntValidator::top
+
+ This property holds the validator's highest acceptable value.
+ By default, this property's value is derived from the highest signed integer available (typically 2147483647).
+*/
+/*!
+ \qmlproperty int QtQuick::IntValidator::bottom
+
+ This property holds the validator's lowest acceptable value.
+ By default, this property's value is derived from the lowest signed integer available (typically -2147483647).
+*/
+
+/*!
+ \qmltype DoubleValidator
+ \instantiates QDoubleValidator
+ \inqmlmodule QtQuick
+ \ingroup qtquick-text-utility
+ \brief Defines a validator for non-integer numbers
+
+ The DoubleValidator type provides a validator for non-integer numbers.
+
+ Input is accepted if it contains a double that is within the valid range
+ and is in the correct format.
+
+ Input is accepected but invalid if it contains a double that is outside
+ the range or is in the wrong format; e.g. with too many digits after the
+ decimal point or is empty.
+
+ Input is rejected if it is not a double.
+
+ Note: If the valid range consists of just positive doubles (e.g. 0.0 to
+ 100.0) and input is a negative double then it is rejected. If \l notation
+ is set to DoubleValidator.StandardNotation, and the input contains more
+ digits before the decimal point than a double in the valid range may have,
+ it is also rejected. If \l notation is DoubleValidator.ScientificNotation,
+ and the input is not in the valid range, it is accecpted but invalid. The
+ value may yet become valid by changing the exponent.
+*/
+
+QQuickDoubleValidator::QQuickDoubleValidator(QObject *parent)
+ : QDoubleValidator(parent)
+{
+}
+
+/*!
+ \qmlproperty string QtQuick::DoubleValidator::locale
+
+ This property holds the name of the locale used to interpret the number.
+
+ \sa {QtQml::Qt::locale()}{Qt.locale()}
+*/
+
+QString QQuickDoubleValidator::localeName() const
+{
+ return locale().name();
+}
+
+void QQuickDoubleValidator::setLocaleName(const QString &name)
+{
+ if (locale().name() != name) {
+ setLocale(QLocale(name));
+ emit localeNameChanged();
+ }
+}
+
+void QQuickDoubleValidator::resetLocaleName()
+{
+ QLocale defaultLocale;
+ if (locale() != defaultLocale) {
+ setLocale(defaultLocale);
+ emit localeNameChanged();
+ }
+}
+
+/*!
+ \qmlproperty real QtQuick::DoubleValidator::top
+
+ This property holds the validator's maximum acceptable value.
+ By default, this property contains a value of infinity.
+*/
+/*!
+ \qmlproperty real QtQuick::DoubleValidator::bottom
+
+ This property holds the validator's minimum acceptable value.
+ By default, this property contains a value of -infinity.
+*/
+/*!
+ \qmlproperty int QtQuick::DoubleValidator::decimals
+
+ This property holds the validator's maximum number of digits after the decimal point.
+ By default, this property contains a value of 1000.
+*/
+/*!
+ \qmlproperty enumeration QtQuick::DoubleValidator::notation
+ This property holds the notation of how a string can describe a number.
+
+ The possible values for this property are:
+
+ \list
+ \li DoubleValidator.StandardNotation
+ \li DoubleValidator.ScientificNotation (default)
+ \endlist
+
+ If this property is set to DoubleValidator.ScientificNotation, the written number may have an exponent part (e.g. 1.5E-2).
+*/
+
+/*!
+ \qmltype RegExpValidator
+ \instantiates QRegExpValidator
+ \inqmlmodule QtQuick
+ \ingroup qtquick-text-utility
+ \brief Provides a string validator
+
+ The RegExpValidator type provides a validator, which counts as valid any string which
+ matches a specified regular expression.
+*/
+/*!
+ \qmlproperty regExp QtQuick::RegExpValidator::regExp
+
+ This property holds the regular expression used for validation.
+
+ Note that this property should be a regular expression in JS syntax, e.g /a/ for the regular expression
+ matching "a".
+
+ By default, this property contains a regular expression with the pattern .* that matches any string.
+*/
+
+#endif // QT_NO_VALIDATOR
+
+QT_END_NAMESPACE
+
diff --git a/src/quick/util/qquickvalidator_p.h b/src/quick/util/qquickvalidator_p.h
new file mode 100644
index 0000000000..59d7884afc
--- /dev/null
+++ b/src/quick/util/qquickvalidator_p.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKVALIDATOR_P_H
+#define QQUICKVALIDATOR_P_H
+
+#include <QtGui/qvalidator.h>
+#include <QtQml/qqml.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_VALIDATOR
+class Q_AUTOTEST_EXPORT QQuickIntValidator : public QIntValidator
+{
+ Q_OBJECT
+ Q_PROPERTY(QString locale READ localeName WRITE setLocaleName RESET resetLocaleName NOTIFY localeNameChanged)
+public:
+ QQuickIntValidator(QObject *parent = 0);
+
+ QString localeName() const;
+ void setLocaleName(const QString &name);
+ void resetLocaleName();
+
+Q_SIGNALS:
+ void localeNameChanged();
+};
+
+class Q_AUTOTEST_EXPORT QQuickDoubleValidator : public QDoubleValidator
+{
+ Q_OBJECT
+ Q_PROPERTY(QString locale READ localeName WRITE setLocaleName RESET resetLocaleName NOTIFY localeNameChanged)
+public:
+ QQuickDoubleValidator(QObject *parent = 0);
+
+ QString localeName() const;
+ void setLocaleName(const QString &name);
+ void resetLocaleName();
+
+Q_SIGNALS:
+ void localeNameChanged();
+};
+#endif
+
+QT_END_NAMESPACE
+
+#ifndef QT_NO_VALIDATOR
+QML_DECLARE_TYPE(QValidator)
+QML_DECLARE_TYPE(QQuickIntValidator)
+QML_DECLARE_TYPE(QQuickDoubleValidator)
+QML_DECLARE_TYPE(QRegExpValidator)
+#endif
+
+#endif // QQUICKVALIDATOR_P_H
diff --git a/src/quick/util/qquickvaluetypes.cpp b/src/quick/util/qquickvaluetypes.cpp
index fef6dfd1d0..1f0d54e4e7 100644
--- a/src/quick/util/qquickvaluetypes.cpp
+++ b/src/quick/util/qquickvaluetypes.cpp
@@ -533,6 +533,16 @@ void QQuickFontValueType::setFamily(const QString &family)
v.setFamily(family);
}
+QString QQuickFontValueType::styleName() const
+{
+ return v.styleName();
+}
+
+void QQuickFontValueType::setStyleName(const QString &style)
+{
+ v.setStyleName(style);
+}
+
bool QQuickFontValueType::bold() const
{
return v.bold();
diff --git a/src/quick/util/qquickvaluetypes_p.h b/src/quick/util/qquickvaluetypes_p.h
index f62306ed01..7a2e8888b7 100644
--- a/src/quick/util/qquickvaluetypes_p.h
+++ b/src/quick/util/qquickvaluetypes_p.h
@@ -266,10 +266,9 @@ class QQuickFontValueType
{
QFont v;
Q_GADGET
- Q_ENUMS(FontWeight)
- Q_ENUMS(Capitalization)
Q_PROPERTY(QString family READ family WRITE setFamily FINAL)
+ Q_PROPERTY(QString styleName READ styleName WRITE setStyleName FINAL)
Q_PROPERTY(bool bold READ bold WRITE setBold FINAL)
Q_PROPERTY(FontWeight weight READ weight WRITE setWeight FINAL)
Q_PROPERTY(bool italic READ italic WRITE setItalic FINAL)
@@ -292,17 +291,22 @@ public:
Bold = QFont::Bold,
ExtraBold = QFont::ExtraBold,
Black = QFont::Black };
+ Q_ENUM(FontWeight)
enum Capitalization { MixedCase = QFont::MixedCase,
AllUppercase = QFont::AllUppercase,
AllLowercase = QFont::AllLowercase,
SmallCaps = QFont::SmallCaps,
Capitalize = QFont::Capitalize };
+ Q_ENUM(Capitalization)
Q_INVOKABLE QString toString() const;
QString family() const;
void setFamily(const QString &);
+ QString styleName() const;
+ void setStyleName(const QString &);
+
bool bold() const;
void setBold(bool b);
diff --git a/src/quick/util/util.pri b/src/quick/util/util.pri
index 0e0df4e751..ffb31ae75e 100644
--- a/src/quick/util/util.pri
+++ b/src/quick/util/util.pri
@@ -29,7 +29,8 @@ SOURCES += \
$$PWD/qquickprofiler.cpp \
$$PWD/qquickfontmetrics.cpp \
$$PWD/qquicktextmetrics.cpp \
- $$PWD/qquickshortcut.cpp
+ $$PWD/qquickshortcut.cpp \
+ $$PWD/qquickvalidator.cpp
HEADERS += \
$$PWD/qquickapplication_p.h\
@@ -66,4 +67,5 @@ HEADERS += \
$$PWD/qquickprofiler_p.h \
$$PWD/qquickfontmetrics_p.h \
$$PWD/qquicktextmetrics_p.h \
- $$PWD/qquickshortcut_p.h
+ $$PWD/qquickshortcut_p.h \
+ $$PWD/qquickvalidator_p.h