aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick')
-rw-r--r--src/quick/accessible/qaccessiblequickitem.cpp9
-rw-r--r--src/quick/accessible/qaccessiblequickitem_p.h11
-rw-r--r--src/quick/accessible/qaccessiblequickview_p.h11
-rw-r--r--src/quick/accessible/qquickaccessiblefactory_p.h11
-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/doc/qtquick.qdocconf2
-rw-r--r--src/quick/doc/src/concepts/effects/sprites.qdoc7
-rw-r--r--src/quick/doc/src/concepts/effects/transformations.qdoc2
-rw-r--r--src/quick/doc/src/concepts/input/textinput.qdoc7
-rw-r--r--src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc17
-rw-r--r--src/quick/doc/src/concepts/positioning/anchors.qdoc2
-rw-r--r--src/quick/doc/src/concepts/positioning/layouts.qdoc3
-rw-r--r--src/quick/doc/src/concepts/statesanimations/animations.qdoc30
-rw-r--r--src/quick/doc/src/concepts/statesanimations/states.qdoc3
-rw-r--r--src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc2
-rw-r--r--src/quick/doc/src/examples.qdoc2
-rw-r--r--src/quick/items/context2d/qquickcanvascontext_p.h11
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp21
-rw-r--r--src/quick/items/context2d/qquickcanvasitem_p.h15
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp81
-rw-r--r--src/quick/items/context2d/qquickcontext2d_p.h13
-rw-r--r--src/quick/items/context2d/qquickcontext2dcommandbuffer_p.h11
-rw-r--r--src/quick/items/context2d/qquickcontext2dtexture_p.h11
-rw-r--r--src/quick/items/context2d/qquickcontext2dtile_p.h11
-rw-r--r--src/quick/items/items.pri1
-rw-r--r--src/quick/items/qquickaccessibleattached_p.h11
-rw-r--r--src/quick/items/qquickanchors.cpp28
-rw-r--r--src/quick/items/qquickanchors_p.h11
-rw-r--r--src/quick/items/qquickanimatedimage_p.h11
-rw-r--r--src/quick/items/qquickanimatedsprite_p.h13
-rw-r--r--src/quick/items/qquickborderimage_p.h13
-rw-r--r--src/quick/items/qquickclipnode_p.h11
-rw-r--r--src/quick/items/qquickdrag_p.h14
-rw-r--r--src/quick/items/qquickdroparea_p.h11
-rw-r--r--src/quick/items/qquickflickable.cpp33
-rw-r--r--src/quick/items/qquickflickable_p.h13
-rw-r--r--src/quick/items/qquickflickable_p_p.h1
-rw-r--r--src/quick/items/qquickflickablebehavior_p.h11
-rw-r--r--src/quick/items/qquickflipable_p.h13
-rw-r--r--src/quick/items/qquickfocusscope_p.h11
-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.h15
-rw-r--r--src/quick/items/qquickimage.cpp5
-rw-r--r--src/quick/items/qquickimage_p.h19
-rw-r--r--src/quick/items/qquickimagebase.cpp32
-rw-r--r--src/quick/items/qquickimagebase_p.h13
-rw-r--r--src/quick/items/qquickimplicitsizeitem_p.h11
-rw-r--r--src/quick/items/qquickimplicitsizeitem_p_p.h2
-rw-r--r--src/quick/items/qquickitem.cpp271
-rw-r--r--src/quick/items/qquickitem.h2
-rw-r--r--src/quick/items/qquickitem_p.h50
-rw-r--r--src/quick/items/qquickitemanimation_p.h13
-rw-r--r--src/quick/items/qquickitemchangelistener_p.h8
-rw-r--r--src/quick/items/qquickitemsmodule.cpp21
-rw-r--r--src/quick/items/qquickitemsmodule_p.h11
-rw-r--r--src/quick/items/qquickitemview.cpp115
-rw-r--r--src/quick/items/qquickitemview_p.h20
-rw-r--r--src/quick/items/qquickitemview_p_p.h17
-rw-r--r--src/quick/items/qquickitemviewtransition.cpp1
-rw-r--r--src/quick/items/qquickitemviewtransition_p.h23
-rw-r--r--src/quick/items/qquicklistview.cpp73
-rw-r--r--src/quick/items/qquicklistview_p.h23
-rw-r--r--src/quick/items/qquickloader.cpp9
-rw-r--r--src/quick/items/qquickloader_p.h13
-rw-r--r--src/quick/items/qquickloader_p_p.h3
-rw-r--r--src/quick/items/qquickmousearea.cpp1
-rw-r--r--src/quick/items/qquickmousearea_p.h11
-rw-r--r--src/quick/items/qquickmultipointtoucharea.cpp6
-rw-r--r--src/quick/items/qquickmultipointtoucharea_p.h11
-rw-r--r--src/quick/items/qquickopenglinfo_p.h3
-rw-r--r--src/quick/items/qquickpainteditem.cpp117
-rw-r--r--src/quick/items/qquickpainteditem.h8
-rw-r--r--src/quick/items/qquickpainteditem_p.h14
-rw-r--r--src/quick/items/qquickpathview.cpp169
-rw-r--r--src/quick/items/qquickpathview_p.h18
-rw-r--r--src/quick/items/qquickpathview_p_p.h5
-rw-r--r--src/quick/items/qquickpincharea_p.h13
-rw-r--r--src/quick/items/qquickpositioners.cpp319
-rw-r--r--src/quick/items/qquickpositioners_p.h57
-rw-r--r--src/quick/items/qquickpositioners_p_p.h23
-rw-r--r--src/quick/items/qquickrectangle_p.h13
-rw-r--r--src/quick/items/qquickrendercontrol.cpp1
-rw-r--r--src/quick/items/qquickrepeater.cpp25
-rw-r--r--src/quick/items/qquickrepeater_p.h11
-rw-r--r--src/quick/items/qquickscalegrid_p_p.h12
-rw-r--r--src/quick/items/qquickscreen_p.h11
-rw-r--r--src/quick/items/qquickshadereffect_p.h15
-rw-r--r--src/quick/items/qquickshadereffectmesh_p.h11
-rw-r--r--src/quick/items/qquickshadereffectnode.cpp6
-rw-r--r--src/quick/items/qquickshadereffectnode_p.h11
-rw-r--r--src/quick/items/qquickshadereffectsource.cpp34
-rw-r--r--src/quick/items/qquickshadereffectsource_p.h27
-rw-r--r--src/quick/items/qquicksprite_p.h11
-rw-r--r--src/quick/items/qquickspriteengine_p.h11
-rw-r--r--src/quick/items/qquickspritesequence_p.h11
-rw-r--r--src/quick/items/qquickstateoperations.cpp201
-rw-r--r--src/quick/items/qquickstateoperations_p.h19
-rw-r--r--src/quick/items/qquicktext.cpp438
-rw-r--r--src/quick/items/qquicktext_p.h62
-rw-r--r--src/quick/items/qquicktext_p_p.h61
-rw-r--r--src/quick/items/qquicktextcontrol.cpp22
-rw-r--r--src/quick/items/qquicktextcontrol_p_p.h3
-rw-r--r--src/quick/items/qquicktextdocument.cpp148
-rw-r--r--src/quick/items/qquicktextdocument_p.h101
-rw-r--r--src/quick/items/qquicktextedit.cpp303
-rw-r--r--src/quick/items/qquicktextedit_p.h58
-rw-r--r--src/quick/items/qquicktextedit_p_p.h35
-rw-r--r--src/quick/items/qquicktextinput.cpp468
-rw-r--r--src/quick/items/qquicktextinput_p.h96
-rw-r--r--src/quick/items/qquicktextinput_p_p.h28
-rw-r--r--src/quick/items/qquicktextnode.cpp45
-rw-r--r--src/quick/items/qquicktextnode_p.h15
-rw-r--r--src/quick/items/qquicktextnodeengine.cpp5
-rw-r--r--src/quick/items/qquicktextnodeengine_p.h13
-rw-r--r--src/quick/items/qquicktranslate_p.h11
-rw-r--r--src/quick/items/qquickview.cpp33
-rw-r--r--src/quick/items/qquickview.h3
-rw-r--r--src/quick/items/qquickview_p.h23
-rw-r--r--src/quick/items/qquickwindow.cpp162
-rw-r--r--src/quick/items/qquickwindow.h8
-rw-r--r--src/quick/items/qquickwindow_p.h2
-rw-r--r--src/quick/items/qquickwindowattached_p.h11
-rw-r--r--src/quick/items/qquickwindowmodule_p.h11
-rw-r--r--src/quick/qtquick2.cpp16
-rw-r--r--src/quick/qtquick2_p.h11
-rw-r--r--src/quick/scenegraph/coreapi/qsgabstractrenderer_p.h11
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp87
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h35
-rw-r--r--src/quick/scenegraph/coreapi/qsggeometry_p.h11
-rw-r--r--src/quick/scenegraph/coreapi/qsgmaterial.cpp2
-rw-r--r--src/quick/scenegraph/coreapi/qsgmaterialshader_p.h11
-rw-r--r--src/quick/scenegraph/coreapi/qsgnode.cpp2
-rw-r--r--src/quick/scenegraph/coreapi/qsgnode_p.h11
-rw-r--r--src/quick/scenegraph/coreapi/qsgnodeupdater.cpp18
-rw-r--r--src/quick/scenegraph/coreapi/qsgnodeupdater_p.h11
-rw-r--r--src/quick/scenegraph/coreapi/qsgrenderer.cpp11
-rw-r--r--src/quick/scenegraph/coreapi/qsgrenderer_p.h11
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer.cpp4
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer_p.h14
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp105
-rw-r--r--src/quick/scenegraph/qsgcontext_p.h21
-rw-r--r--src/quick/scenegraph/qsgcontextplugin_p.h11
-rw-r--r--src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h11
-rw-r--r--src/quick/scenegraph/qsgdefaultglyphnode_p.cpp13
-rw-r--r--src/quick/scenegraph/qsgdefaultglyphnode_p.h11
-rw-r--r--src/quick/scenegraph/qsgdefaultglyphnode_p_p.h11
-rw-r--r--src/quick/scenegraph/qsgdefaultimagenode.cpp2
-rw-r--r--src/quick/scenegraph/qsgdefaultimagenode_p.h11
-rw-r--r--src/quick/scenegraph/qsgdefaultlayer.cpp25
-rw-r--r--src/quick/scenegraph/qsgdefaultlayer_p.h21
-rw-r--r--src/quick/scenegraph/qsgdefaultrectanglenode_p.h11
-rw-r--r--src/quick/scenegraph/qsgdistancefieldglyphnode.cpp6
-rw-r--r--src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp11
-rw-r--r--src/quick/scenegraph/qsgdistancefieldglyphnode_p.h11
-rw-r--r--src/quick/scenegraph/qsgdistancefieldglyphnode_p_p.h11
-rw-r--r--src/quick/scenegraph/qsgrenderloop.cpp35
-rw-r--r--src/quick/scenegraph/qsgrenderloop_p.h13
-rw-r--r--src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp655
-rw-r--r--src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h124
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp65
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop_p.h12
-rw-r--r--src/quick/scenegraph/qsgwindowsrenderloop.cpp3
-rw-r--r--src/quick/scenegraph/qsgwindowsrenderloop_p.h11
-rw-r--r--src/quick/scenegraph/scenegraph.pri2
-rw-r--r--src/quick/scenegraph/util/qsgareaallocator_p.h11
-rw-r--r--src/quick/scenegraph/util/qsgatlastexture.cpp22
-rw-r--r--src/quick/scenegraph/util/qsgatlastexture_p.h14
-rw-r--r--src/quick/scenegraph/util/qsgdefaultpainternode.cpp62
-rw-r--r--src/quick/scenegraph/util/qsgdefaultpainternode_p.h40
-rw-r--r--src/quick/scenegraph/util/qsgdepthstencilbuffer_p.h11
-rw-r--r--src/quick/scenegraph/util/qsgdistancefieldutil.cpp19
-rw-r--r--src/quick/scenegraph/util/qsgdistancefieldutil_p.h11
-rw-r--r--src/quick/scenegraph/util/qsgengine.cpp15
-rw-r--r--src/quick/scenegraph/util/qsgengine.h3
-rw-r--r--src/quick/scenegraph/util/qsgengine_p.h11
-rw-r--r--src/quick/scenegraph/util/qsgshadersourcebuilder.cpp2
-rw-r--r--src/quick/scenegraph/util/qsgshadersourcebuilder_p.h11
-rw-r--r--src/quick/scenegraph/util/qsgtexture.cpp2
-rw-r--r--src/quick/scenegraph/util/qsgtexture_p.h11
-rw-r--r--src/quick/scenegraph/util/qsgtexturematerial_p.h11
-rw-r--r--src/quick/util/qquickanimation.cpp16
-rw-r--r--src/quick/util/qquickanimation_p.h15
-rw-r--r--src/quick/util/qquickanimation_p_p.h2
-rw-r--r--src/quick/util/qquickanimationcontroller_p.h11
-rw-r--r--src/quick/util/qquickanimator.cpp2
-rw-r--r--src/quick/util/qquickanimator_p.h14
-rw-r--r--src/quick/util/qquickanimator_p_p.h11
-rw-r--r--src/quick/util/qquickanimatorcontroller.cpp4
-rw-r--r--src/quick/util/qquickanimatorcontroller_p.h11
-rw-r--r--src/quick/util/qquickanimatorjob.cpp5
-rw-r--r--src/quick/util/qquickanimatorjob_p.h47
-rw-r--r--src/quick/util/qquickapplication_p.h11
-rw-r--r--src/quick/util/qquickbehavior_p.h11
-rw-r--r--src/quick/util/qquickfontloader.cpp58
-rw-r--r--src/quick/util/qquickfontloader_p.h13
-rw-r--r--src/quick/util/qquickfontmetrics.cpp3
-rw-r--r--src/quick/util/qquickfontmetrics_p.h11
-rw-r--r--src/quick/util/qquickglobal.cpp277
-rw-r--r--src/quick/util/qquickimageprovider.cpp131
-rw-r--r--src/quick/util/qquickimageprovider.h32
-rw-r--r--src/quick/util/qquickpath_p.h13
-rw-r--r--src/quick/util/qquickpathinterpolator_p.h11
-rw-r--r--src/quick/util/qquickpixmapcache.cpp245
-rw-r--r--src/quick/util/qquickpixmapcache_p.h11
-rw-r--r--src/quick/util/qquickprofiler.cpp24
-rw-r--r--src/quick/util/qquickprofiler_p.h2
-rw-r--r--src/quick/util/qquickpropertychanges.cpp34
-rw-r--r--src/quick/util/qquickpropertychanges_p.h11
-rw-r--r--src/quick/util/qquickshortcut.cpp31
-rw-r--r--src/quick/util/qquickshortcut_p.h5
-rw-r--r--src/quick/util/qquicksmoothedanimation_p.h13
-rw-r--r--src/quick/util/qquickspringanimation_p.h11
-rw-r--r--src/quick/util/qquickstate.cpp49
-rw-r--r--src/quick/util/qquickstate_p.h23
-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.h13
-rw-r--r--src/quick/util/qquickstategroup_p.h11
-rw-r--r--src/quick/util/qquickstyledtext.cpp4
-rw-r--r--src/quick/util/qquickstyledtext_p.h11
-rw-r--r--src/quick/util/qquicksvgparser_p.h11
-rw-r--r--src/quick/util/qquicksystempalette_p.h13
-rw-r--r--src/quick/util/qquicktextmetrics.cpp2
-rw-r--r--src/quick/util/qquicktextmetrics_p.h11
-rw-r--r--src/quick/util/qquicktimeline.cpp2
-rw-r--r--src/quick/util/qquicktransition.cpp2
-rw-r--r--src/quick/util/qquicktransition_p.h11
-rw-r--r--src/quick/util/qquicktransitionmanager.cpp28
-rw-r--r--src/quick/util/qquicktransitionmanager_p_p.h6
-rw-r--r--src/quick/util/qquickutilmodule.cpp10
-rw-r--r--src/quick/util/qquickutilmodule_p.h11
-rw-r--r--src/quick/util/qquickvalidator.cpp221
-rw-r--r--src/quick/util/qquickvalidator_p.h94
-rw-r--r--src/quick/util/qquickvaluetypes.cpp10
-rw-r--r--src/quick/util/qquickvaluetypes_p.h26
-rw-r--r--src/quick/util/util.pri6
256 files changed, 7555 insertions, 2810 deletions
diff --git a/src/quick/accessible/qaccessiblequickitem.cpp b/src/quick/accessible/qaccessiblequickitem.cpp
index 4ccfdb9142..44a2caecec 100644
--- a/src/quick/accessible/qaccessiblequickitem.cpp
+++ b/src/quick/accessible/qaccessiblequickitem.cpp
@@ -204,11 +204,12 @@ QAccessible::Role QAccessibleQuickItem::role() const
if (qobject_cast<QQuickText*>(const_cast<QQuickItem *>(item())))
return QAccessible::StaticText;
- QVariant v = QQuickAccessibleAttached::property(item(), "role");
- bool ok;
- QAccessible::Role role = (QAccessible::Role)v.toInt(&ok);
- if (!ok) // Not sure if this check is needed.
+ QAccessible::Role role = QAccessible::NoRole;
+ if (item())
+ role = QQuickItemPrivate::get(item())->accessibleRole();
+ if (role == QAccessible::NoRole)
role = QAccessible::Client;
+
return role;
}
diff --git a/src/quick/accessible/qaccessiblequickitem_p.h b/src/quick/accessible/qaccessiblequickitem_p.h
index deefb10e60..1ec569731e 100644
--- a/src/quick/accessible/qaccessiblequickitem_p.h
+++ b/src/quick/accessible/qaccessiblequickitem_p.h
@@ -34,6 +34,17 @@
#ifndef QACCESSIBLEQUICKITEM_H
#define QACCESSIBLEQUICKITEM_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 <QtQuick/QQuickItem>
#include <QtQuick/QQuickView>
#include <QtGui/qaccessibleobject.h>
diff --git a/src/quick/accessible/qaccessiblequickview_p.h b/src/quick/accessible/qaccessiblequickview_p.h
index f08b78528d..049fa385ba 100644
--- a/src/quick/accessible/qaccessiblequickview_p.h
+++ b/src/quick/accessible/qaccessiblequickview_p.h
@@ -34,6 +34,17 @@
#ifndef QAccessibleQuickView_H
#define QAccessibleQuickView_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 <QtGui/qaccessibleobject.h>
#include <QtQuick/qquickwindow.h>
diff --git a/src/quick/accessible/qquickaccessiblefactory_p.h b/src/quick/accessible/qquickaccessiblefactory_p.h
index f7936b140e..98512f9fb4 100644
--- a/src/quick/accessible/qquickaccessiblefactory_p.h
+++ b/src/quick/accessible/qquickaccessiblefactory_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKACCESSIBLEFACTORY_H
#define QQUICKACCESSIBLEFACTORY_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 <QtGui/qaccessible.h>
QT_BEGIN_NAMESPACE
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..76c94b242d
--- /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->propertyCount == 0
+ && data->aliasCount == 0
+ && data->signalCount == 0
+ && data->methodCount == 0;
+}
+
+static QQmlVMEMetaData* fakeMetaData()
+{
+ QQmlVMEMetaData* data = new QQmlVMEMetaData;
+ 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(QObject *o, 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(o, call, id, a);
+ else
+ return myObject()->qt_metacall(call, id, a);
+ }
+}
+
+int QQmlDesignerMetaObject::metaCall(QObject *o, QMetaObject::Call call, int id, void **a)
+{
+ Q_ASSERT(myObject() == o);
+
+ 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(o, call, id, a);
+ } else {
+ openMetaCall(o, 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..47f4baad2b
--- /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(QObject *o, QMetaObject::Call _c, int _id, void **_a);
+ int metaCall(QObject *o, 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/doc/qtquick.qdocconf b/src/quick/doc/qtquick.qdocconf
index 7f43dc2c31..044c1696ff 100644
--- a/src/quick/doc/qtquick.qdocconf
+++ b/src/quick/doc/qtquick.qdocconf
@@ -4,7 +4,7 @@ project = QtQuick
description = Qt Quick Reference Documentation
version = $QT_VERSION
-examplesinstallpath = quick
+examplesinstallpath = qtdeclarative/quick
qhp.projects = QtQuick
diff --git a/src/quick/doc/src/concepts/effects/sprites.qdoc b/src/quick/doc/src/concepts/effects/sprites.qdoc
index edad89b1e5..62d9ea0811 100644
--- a/src/quick/doc/src/concepts/effects/sprites.qdoc
+++ b/src/quick/doc/src/concepts/effects/sprites.qdoc
@@ -26,13 +26,10 @@
****************************************************************************/
/*!
-\ingroup qtquick-images-sprites
\page qtquick-effects-sprites.html
\title Sprite Animations
\brief Sprite-based animations with flexible transitioning
-\generatelist{related}
-
\section1 Sprite Engine
The \l {Qt Quick} sprite engine is a stochastic state machine combined with the ability
@@ -167,9 +164,9 @@ Additionally, \l ImageParticle can use \l Sprite types to define sprites for eac
sprite engine per type. This works similarly to SpriteSequence, but it also has the parametrized variability provided
by the \l ImageParticle type.
-\section1 AnimatedSprite
+\section1 AnimatedSprite Type
-For use-cases which do not need to transition between animations, consider the \l AnimatedSprite type.
+For use-cases which do not need to transition between animations, consider the AnimatedSprite type.
This type displays sprite animations with the same input format, but only one at a time. It also provides more fine-grained
manual control, as there is no sprite engine managing the timing and transitions behind the scenes.
diff --git a/src/quick/doc/src/concepts/effects/transformations.qdoc b/src/quick/doc/src/concepts/effects/transformations.qdoc
index a5c7b9c208..cfe9d420fa 100644
--- a/src/quick/doc/src/concepts/effects/transformations.qdoc
+++ b/src/quick/doc/src/concepts/effects/transformations.qdoc
@@ -31,8 +31,6 @@
\title Qt Quick Transformation Types
\brief Types for applying transformations to visual types
-\generatelist{related}
-
Transformations are applied to child hierarchies and also will also transform
mouse and touch input so coordinates in event handlers behave as expected.
diff --git a/src/quick/doc/src/concepts/input/textinput.qdoc b/src/quick/doc/src/concepts/input/textinput.qdoc
index 3965c246da..41508caad6 100644
--- a/src/quick/doc/src/concepts/input/textinput.qdoc
+++ b/src/quick/doc/src/concepts/input/textinput.qdoc
@@ -26,7 +26,6 @@
****************************************************************************/
/*!
-\ingroup qtquick-text
\page qtquick-input-textinput.html
\title Qt Quick Text Input Handling and Validators
\brief Text input and validation
@@ -38,8 +37,6 @@ type will display formatted text onto the screen, the \l TextEdit type
will place a multiline line edit onto the screen, and the \l TextInput will
place a single editable line field onto the screen.
-\generatelist{related}
-
To learn more about their specific features and properties, visit their
respective documentation.
@@ -63,11 +60,11 @@ Note that QML parses JavaScript regular expressions, while Qt's
*/
/*!
+\page qtquick-text-validator.html
\ingroup qtquick-text-validator
\title Qt Quick Text Validators
\brief Types that validate text input
-The \l{qtquick-concepts-input-text.html}
-{Qt Quick Text Input Handling and Validators} page has information about
+The \l {Qt Quick Text Input Handling and Validators} page has information about
validating user text input.
*/
diff --git a/src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc b/src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc
index e03b3a9bf8..324fc9750f 100644
--- a/src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc
+++ b/src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc
@@ -57,7 +57,7 @@ To visualize data, bind the view's \c model property to a model and the
Views are containers for collections of items. They are feature-rich and can be
customizable to meet style or behavior requirements.
- \keyword qtquick-views
+ \target qtquick-views
A set of standard views are provided in the basic set of Qt Quick
graphical types:
@@ -124,7 +124,7 @@ To visualize data, bind the view's \c model property to a model and the
\snippet qml/listview-sections.qml section
\image listview-section.png
-\keyword qml-view-delegate
+\target qml-view-delegate
\section1 View Delegates
Views need a \e delegate to visually represent an item in a list. A view will
@@ -154,7 +154,7 @@ To visualize data, bind the view's \c model property to a model and the
\snippet qml/models/views-models-delegates.qml rectangle
-\keyword qml-data-models
+\target qml-data-models
\section1 Models
Data is provided to the delegate via named data roles which the delegate may
@@ -320,7 +320,7 @@ To visualize data, bind the view's \c model property to a model and the
}
\endqml
- \keyword qml-c++-models
+ \target qml-c++-models
\section2 C++ Data Models
Models can be defined in C++ and then made available to QML. This mechanism
@@ -371,13 +371,12 @@ or removed from a positioner.
Transitions for adding items apply to items that are created as part of a
positioner, as well as those that are reparented to become children of a
positioner.
+
Transitions for removing items apply to items within a positioner that are
deleted, as well as those that are removed from a positioner and given new
parents in a document.
-Additionally, changing the opacity of items to zero will cause them to
-disappear using the remove transition, and making the opacity non-zero will
-cause them to appear using the add transition.
-
-
+\note Changing the opacity of items to zero will not cause them to
+disappear from the positioner. They can be removed and re-added by changing
+the visible property.
*/
diff --git a/src/quick/doc/src/concepts/positioning/anchors.qdoc b/src/quick/doc/src/concepts/positioning/anchors.qdoc
index 71af38b587..259dcbe671 100644
--- a/src/quick/doc/src/concepts/positioning/anchors.qdoc
+++ b/src/quick/doc/src/concepts/positioning/anchors.qdoc
@@ -30,7 +30,7 @@
\title Positioning with Anchors
\brief placing items with anchor properties
-\target anchor-layout
+\keyword anchor-layout
In addition to the more traditional \l Grid, \l Row, and \l Column,
Qt Quick also provides a way to layout items using the concept of \e anchors.
Each item can be thought of as having a set of 7 invisible "anchor lines":
diff --git a/src/quick/doc/src/concepts/positioning/layouts.qdoc b/src/quick/doc/src/concepts/positioning/layouts.qdoc
index de47af6db8..47ed2563f8 100644
--- a/src/quick/doc/src/concepts/positioning/layouts.qdoc
+++ b/src/quick/doc/src/concepts/positioning/layouts.qdoc
@@ -26,7 +26,6 @@
****************************************************************************/
/*!
-\ingroup qtquick-positioners
\page qtquick-positioning-layouts.html
\title Item Positioners
@@ -47,7 +46,7 @@ and are well suited for resizable user interfaces.
A set of standard positioners are provided in the basic set of Qt Quick
graphical types:
-\generatelist{related}
+\annotatedlist qtquick-positioners
\section2 Column
diff --git a/src/quick/doc/src/concepts/statesanimations/animations.qdoc b/src/quick/doc/src/concepts/statesanimations/animations.qdoc
index 4e336afa36..1a2cff43f4 100644
--- a/src/quick/doc/src/concepts/statesanimations/animations.qdoc
+++ b/src/quick/doc/src/concepts/statesanimations/animations.qdoc
@@ -138,7 +138,7 @@ are also automatically applied to this property and do not need to specify
values.
-\keyword qml-transition-animations
+\target qml-transition-animations
\section2 Transitions during State Changes
\l{State}{Qt Quick States} are property configurations where a property may have different values to reflect different states. State changes introduce
@@ -210,7 +210,7 @@ The \l SequentialAnimation type is also useful for playing
\l{qml-transition-animations}{transition animations} because animations are
played in parallel inside transitions.
-\keyword qml-controlling-animations
+\target qml-controlling-animations
\section1 Controlling Animations
There are different methods to control animations.
@@ -222,7 +222,7 @@ essential properties and methods for animation types. Animation types have
\c{start()}, \c{stop()}, \c{resume()}, \c{pause()}, \c {restart()}, and
\c{complete()} -- all of these methods control the execution of animations.
-\keyword qml-easing-animation
+\target qml-easing-animation
\section2 Easing
Easing curves define how the animation will interpolate between the start value
@@ -295,27 +295,3 @@ Rectangle {
\endqml
*/
-
-/*!
-\ingroup qtquick-animation-properties
-\title Qt Quick Property Animation
-\brief Animate property changes
-
-\generatelist{related}
-*/
-
-/*!
-\ingroup qtquick-animation-control
-\title Qt Quick Animation Controls
-\brief Control animation sequences
-
-\generatelist{related}
-*/
-
-/*!
-\ingroup qtquick-animation-modifiers
-\title Qt Quick Animation Modifiers
-\brief Modify animation sequences
-
-\generatelist{related}
-*/
diff --git a/src/quick/doc/src/concepts/statesanimations/states.qdoc b/src/quick/doc/src/concepts/statesanimations/states.qdoc
index d107369e44..b48a051379 100644
--- a/src/quick/doc/src/concepts/statesanimations/states.qdoc
+++ b/src/quick/doc/src/concepts/statesanimations/states.qdoc
@@ -26,13 +26,12 @@
****************************************************************************/
/*!
-\ingroup qtquick-states
\page qtquick-statesanimations-states.html
\title Qt Quick States
\brief Creating and setting states
\section1 Related Types
-\generatelist{related}
+\annotatedlist qtquick-states
Many user interface designs are \e{state driven}; interfaces have configurations
that differ depending on the current state. For example, a traffic signal will
diff --git a/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc b/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc
index 287bdc892e..187085a5d8 100644
--- a/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc
+++ b/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc
@@ -585,7 +585,7 @@ with multiple windows.
\section1 Batch Roots
- In addition to mergin compatible primitives into batches, the
+ In addition to merging compatible primitives into batches, the
default renderer also tries to minimize the amount of data that
needs to be sent to the GPU for every frame. The default renderer
identifies subtrees which belong together and tries to put these
diff --git a/src/quick/doc/src/examples.qdoc b/src/quick/doc/src/examples.qdoc
index dd21270673..e69c2f6551 100644
--- a/src/quick/doc/src/examples.qdoc
+++ b/src/quick/doc/src/examples.qdoc
@@ -32,7 +32,7 @@
\brief Building UIs with QML
\ingroup all-examples
\ingroup qtquick
-\target qtquick-samples
+\keyword qtquick-samples
Qt includes several examples to demonstrate a particular usage. The examples
run as applications or as non-GUI examples in Qt Creator. Qt tutorials show
diff --git a/src/quick/items/context2d/qquickcanvascontext_p.h b/src/quick/items/context2d/qquickcanvascontext_p.h
index b7a7f6db71..0010862044 100644
--- a/src/quick/items/context2d/qquickcanvascontext_p.h
+++ b/src/quick/items/context2d/qquickcanvascontext_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKCANVASCONTEXT_P_H
#define QQUICKCANVASCONTEXT_P_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 <QtQuick/qquickitem.h>
#include <private/qv8engine_p.h>
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp
index 6ef2d6123b..9abca59b1c 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>
@@ -256,19 +256,6 @@ QQuickCanvasItemPrivate::~QQuickCanvasItemPrivate()
The default render target is Canvas.Image and the default renderStrategy is
Canvas.Immediate.
- \section1 Tiled Canvas
- The Canvas item supports tiled rendering by setting \l canvasSize, \l tileSize
- and \l canvasWindow properties.
-
- Tiling allows efficient display of a very large virtual canvas via a smaller
- canvas window. The actual memory consumption is in relation to the canvas
- window size. The painting code can draw within the virtual canvas without
- handling coordinate system transformations.
-
- The tiles overlapping with the canvas window may be cached eliminating the
- need to redraw, which can lead to significantly improved performance in
- some situations.
-
\section1 Pixel Operations
All HTML5 2D context pixel operations are supported. In order to ensure
improved pixel reading/writing performance the \a Canvas.Image render
@@ -431,6 +418,8 @@ void QQuickCanvasItem::setCanvasSize(const QSizeF & size)
By default the tileSize is the same as the canvasSize.
+ \obsolete This feature is incomplete. For details, see QTBUG-33129.
+
\sa canvasSize, canvasWindow
*/
QSize QQuickCanvasItem::tileSize() const
@@ -464,6 +453,8 @@ void QQuickCanvasItem::setTileSize(const QSize & size)
can display different visible areas by changing the canvas windowSize
and/or position.
+ \obsolete This feature is incomplete. For details, see QTBUG-33129
+
\sa canvasSize, tileSize
*/
QRectF QQuickCanvasItem::canvasWindow() const
@@ -1000,7 +991,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..a32ce5389d 100644
--- a/src/quick/items/context2d/qquickcanvasitem_p.h
+++ b/src/quick/items/context2d/qquickcanvasitem_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKCANVASITEM_P_H
#define QQUICKCANVASITEM_P_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 <QtQuick/qquickitem.h>
#include <private/qv8engine_p.h>
#include <QtCore/QThread>
@@ -68,8 +79,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 +94,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 c71a354e0c..1c021e7dc6 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.
@@ -475,17 +475,20 @@ namespace QV4 {
namespace Heap {
struct QQuickJSContext2D : Object {
- QQuickJSContext2D(QV4::ExecutionEngine *engine);
+ QQuickJSContext2D() {}
QQuickContext2D* context;
};
struct QQuickJSContext2DPrototype : Object {
- QQuickJSContext2DPrototype(ExecutionEngine *e)
- : Object(e) {}
+ QQuickJSContext2DPrototype() {}
};
struct QQuickContext2DStyle : Object {
- QQuickContext2DStyle(QV4::ExecutionEngine *e);
+ QQuickContext2DStyle()
+ {
+ patternRepeatX = false;
+ patternRepeatY = false;
+ }
QBrush brush;
bool patternRepeatX:1;
@@ -493,13 +496,13 @@ struct QQuickContext2DStyle : Object {
};
struct QQuickJSContext2DPixelData : Object {
- QQuickJSContext2DPixelData(QV4::ExecutionEngine *engine);
+ QQuickJSContext2DPixelData();
QImage image;
};
struct QQuickJSContext2DImageData : Object {
- QQuickJSContext2DImageData(QV4::ExecutionEngine *engine);
+ QQuickJSContext2DImageData();
QV4::Value pixelData;
};
@@ -552,11 +555,6 @@ struct QQuickJSContext2D : public QV4::Object
static QV4::ReturnedValue method_set_textBaseline(QV4::CallContext *ctx);
};
-QV4::Heap::QQuickJSContext2D::QQuickJSContext2D(QV4::ExecutionEngine *engine)
- : QV4::Heap::Object(engine)
-{
-}
-
DEFINE_OBJECT_VTABLE(QQuickJSContext2D);
@@ -567,7 +565,7 @@ public:
static QV4::Heap::QQuickJSContext2DPrototype *create(QV4::ExecutionEngine *engine)
{
QV4::Scope scope(engine);
- QV4::Scoped<QQuickJSContext2DPrototype> o(scope, engine->memoryManager->alloc<QQuickJSContext2DPrototype>(engine));
+ QV4::Scoped<QQuickJSContext2DPrototype> o(scope, engine->memoryManager->allocObject<QQuickJSContext2DPrototype>());
o->defineDefaultProperty(QStringLiteral("quadraticCurveTo"), method_quadraticCurveTo, 0);
o->defineDefaultProperty(QStringLiteral("restore"), method_restore, 0);
@@ -675,12 +673,7 @@ struct QQuickContext2DStyle : public QV4::Object
static QV4::ReturnedValue gradient_proto_addColorStop(QV4::CallContext *ctx);
};
-QV4::Heap::QQuickContext2DStyle::QQuickContext2DStyle(QV4::ExecutionEngine *e)
- : QV4::Heap::Object(e)
-{
- patternRepeatX = false;
- patternRepeatY = false;
-}
+
DEFINE_OBJECT_VTABLE(QQuickContext2DStyle);
@@ -884,16 +877,15 @@ 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);
};
-QV4::Heap::QQuickJSContext2DPixelData::QQuickJSContext2DPixelData(QV4::ExecutionEngine *engine)
- : QV4::Heap::Object(engine)
+QV4::Heap::QQuickJSContext2DPixelData::QQuickJSContext2DPixelData()
{
- QV4::Scope scope(engine);
+ QV4::Scope scope(internalClass->engine);
QV4::ScopedObject o(scope, this);
o->setArrayType(QV4::Heap::ArrayData::Custom);
}
@@ -914,12 +906,11 @@ struct QQuickJSContext2DImageData : public QV4::Object
}
};
-QV4::Heap::QQuickJSContext2DImageData::QQuickJSContext2DImageData(QV4::ExecutionEngine *engine)
- : QV4::Heap::Object(engine)
+QV4::Heap::QQuickJSContext2DImageData::QQuickJSContext2DImageData()
{
pixelData = QV4::Primitive::undefinedValue();
- QV4::Scope scope(engine);
+ QV4::Scope scope(internalClass->engine);
QV4::ScopedObject o(scope, this);
o->defineAccessorProperty(QStringLiteral("width"), ::QQuickJSContext2DImageData::method_get_width, 0);
@@ -933,7 +924,7 @@ static QV4::ReturnedValue qt_create_image_data(qreal w, qreal h, QV4::ExecutionE
{
QV4::Scope scope(v4);
QQuickContext2DEngineData *ed = engineData(scope.engine);
- QV4::Scoped<QQuickJSContext2DPixelData> pixelData(scope, scope.engine->memoryManager->alloc<QQuickJSContext2DPixelData>(v4));
+ QV4::Scoped<QQuickJSContext2DPixelData> pixelData(scope, scope.engine->memoryManager->allocObject<QQuickJSContext2DPixelData>());
QV4::ScopedObject p(scope, ed->pixelArrayProto.value());
pixelData->setPrototype(p);
@@ -945,7 +936,7 @@ static QV4::ReturnedValue qt_create_image_data(qreal w, qreal h, QV4::ExecutionE
pixelData->d()->image = image.format() == QImage::Format_ARGB32 ? image : image.convertToFormat(QImage::Format_ARGB32);
}
- QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, scope.engine->memoryManager->alloc<QQuickJSContext2DImageData>(v4));
+ QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, scope.engine->memoryManager->allocObject<QQuickJSContext2DImageData>());
imageData->d()->pixelData = pixelData.asReturnedValue();
return imageData.asReturnedValue();
}
@@ -1379,7 +1370,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 +1479,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;
@@ -1553,7 +1544,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createLinearGradient(QV4::
}
QQuickContext2DEngineData *ed = engineData(scope.engine);
- QV4::Scoped<QQuickContext2DStyle> gradient(scope, scope.engine->memoryManager->alloc<QQuickContext2DStyle>(scope.engine));
+ QV4::Scoped<QQuickContext2DStyle> gradient(scope, scope.engine->memoryManager->allocObject<QQuickContext2DStyle>());
QV4::ScopedObject p(scope, ed->gradientProto.value());
gradient->setPrototype(p);
gradient->d()->brush = QLinearGradient(x0, y0, x1, y1);
@@ -1604,7 +1595,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createRadialGradient(QV4::
QQuickContext2DEngineData *ed = engineData(scope.engine);
- QV4::Scoped<QQuickContext2DStyle> gradient(scope, scope.engine->memoryManager->alloc<QQuickContext2DStyle>(scope.engine));
+ QV4::Scoped<QQuickContext2DStyle> gradient(scope, scope.engine->memoryManager->allocObject<QQuickContext2DStyle>());
QV4::ScopedObject p(scope, ed->gradientProto.value());
gradient->setPrototype(p);
gradient->d()->brush = QRadialGradient(QPointF(x1, y1), r0+r1, QPointF(x0, y0));
@@ -1647,7 +1638,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createConicalGradient(QV4:
QQuickContext2DEngineData *ed = engineData(scope.engine);
- QV4::Scoped<QQuickContext2DStyle> gradient(scope, scope.engine->memoryManager->alloc<QQuickContext2DStyle>(scope.engine));
+ QV4::Scoped<QQuickContext2DStyle> gradient(scope, scope.engine->memoryManager->allocObject<QQuickContext2DStyle>());
QV4::ScopedObject p(scope, ed->gradientProto.value());
gradient->setPrototype(p);
gradient->d()->brush = QConicalGradient(x, y, angle);
@@ -1706,7 +1697,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createPattern(QV4::CallCon
CHECK_CONTEXT(r)
if (ctx->argc() >= 2) {
- QV4::Scoped<QQuickContext2DStyle> pattern(scope, scope.engine->memoryManager->alloc<QQuickContext2DStyle>(scope.engine));
+ QV4::Scoped<QQuickContext2DStyle> pattern(scope, scope.engine->memoryManager->allocObject<QQuickContext2DStyle>());
QColor color = scope.engine->toVariant(ctx->args()[0], qMetaTypeId<QColor>()).value<QColor>();
if (color.isValid()) {
@@ -1719,7 +1710,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 +2903,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 +2912,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 +3080,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 +3348,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 +4226,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;
}
@@ -4324,7 +4315,7 @@ void QQuickContext2D::setV4Engine(QV4::ExecutionEngine *engine)
QQuickContext2DEngineData *ed = engineData(engine);
QV4::Scope scope(engine);
- QV4::Scoped<QQuickJSContext2D> wrapper(scope, engine->memoryManager->alloc<QQuickJSContext2D>(engine));
+ QV4::Scoped<QQuickJSContext2D> wrapper(scope, engine->memoryManager->allocObject<QQuickJSContext2D>());
QV4::ScopedObject p(scope, ed->contextPrototype.value());
wrapper->setPrototype(p);
wrapper->d()->context = this;
diff --git a/src/quick/items/context2d/qquickcontext2d_p.h b/src/quick/items/context2d/qquickcontext2d_p.h
index 67d3a2e4fb..94762fe7a2 100644
--- a/src/quick/items/context2d/qquickcontext2d_p.h
+++ b/src/quick/items/context2d/qquickcontext2d_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKCONTEXT2D_P_H
#define QQUICKCONTEXT2D_P_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 <QtQuick/qtquickglobal.h>
#include <QtQml/qqml.h>
#include <QtQml/qqmlcomponent.h>
@@ -48,7 +59,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/context2d/qquickcontext2dcommandbuffer_p.h b/src/quick/items/context2d/qquickcontext2dcommandbuffer_p.h
index 54bf209c79..48cf21ad71 100644
--- a/src/quick/items/context2d/qquickcontext2dcommandbuffer_p.h
+++ b/src/quick/items/context2d/qquickcontext2dcommandbuffer_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKCONTEXT2DCOMMANDBUFFER_P_H
#define QQUICKCONTEXT2DCOMMANDBUFFER_P_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 <QtCore/qmutex.h>
#include "qquickcontext2d_p.h"
diff --git a/src/quick/items/context2d/qquickcontext2dtexture_p.h b/src/quick/items/context2d/qquickcontext2dtexture_p.h
index 88d7b6858f..50ce95e19b 100644
--- a/src/quick/items/context2d/qquickcontext2dtexture_p.h
+++ b/src/quick/items/context2d/qquickcontext2dtexture_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKCONTEXT2DTEXTURE_P_H
#define QQUICKCONTEXT2DTEXTURE_P_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 <QtQuick/qsgtexture.h>
#include "qquickcanvasitem_p.h"
#include "qquickcontext2d_p.h"
diff --git a/src/quick/items/context2d/qquickcontext2dtile_p.h b/src/quick/items/context2d/qquickcontext2dtile_p.h
index d923313a28..781261c8d2 100644
--- a/src/quick/items/context2d/qquickcontext2dtile_p.h
+++ b/src/quick/items/context2d/qquickcontext2dtile_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKCONTEXT2DTILE_P_H
#define QQUICKCONTEXT2DTILE_P_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 "qquickcontext2d_p.h"
#include <QOpenGLFramebufferObject>
diff --git a/src/quick/items/items.pri b/src/quick/items/items.pri
index 0b98782566..ab966b6ccc 100644
--- a/src/quick/items/items.pri
+++ b/src/quick/items/items.pri
@@ -23,6 +23,7 @@ HEADERS += \
$$PWD/qquicktextcontrol_p.h \
$$PWD/qquicktextcontrol_p_p.h \
$$PWD/qquicktextdocument.h \
+ $$PWD/qquicktextdocument_p.h \
$$PWD/qquicktextedit_p.h \
$$PWD/qquicktextedit_p_p.h \
$$PWD/qquicktextutil_p.h \
diff --git a/src/quick/items/qquickaccessibleattached_p.h b/src/quick/items/qquickaccessibleattached_p.h
index be78e74b19..617b5aa886 100644
--- a/src/quick/items/qquickaccessibleattached_p.h
+++ b/src/quick/items/qquickaccessibleattached_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKACCESSIBLEATTACHED_H
#define QQUICKACCESSIBLEATTACHED_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 <QtQuick/qquickitem.h>
#include <QtCore/qobject.h>
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/qquickanchors_p.h b/src/quick/items/qquickanchors_p.h
index a2328162e5..4157e4bf6d 100644
--- a/src/quick/items/qquickanchors_p.h
+++ b/src/quick/items/qquickanchors_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKANCHORS_P_H
#define QQUICKANCHORS_P_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 <qqml.h>
#include <QtCore/QObject>
diff --git a/src/quick/items/qquickanimatedimage_p.h b/src/quick/items/qquickanimatedimage_p.h
index 409933817f..42f2d4cb64 100644
--- a/src/quick/items/qquickanimatedimage_p.h
+++ b/src/quick/items/qquickanimatedimage_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKANIMATEDIMAGE_P_H
#define QQUICKANIMATEDIMAGE_P_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 "qquickimage_p.h"
#ifndef QT_NO_MOVIE
diff --git a/src/quick/items/qquickanimatedsprite_p.h b/src/quick/items/qquickanimatedsprite_p.h
index e535f1b077..87d489a60a 100644
--- a/src/quick/items/qquickanimatedsprite_p.h
+++ b/src/quick/items/qquickanimatedsprite_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKANIMATEDSPRITE_P_H
#define QQUICKANIMATEDSPRITE_P_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 <QtQuick/QQuickItem>
#include <private/qquicksprite_p.h>
#include <QTime>
@@ -70,12 +81,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..02e01dedd5 100644
--- a/src/quick/items/qquickborderimage_p.h
+++ b/src/quick/items/qquickborderimage_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKBORDERIMAGE_P_H
#define QQUICKBORDERIMAGE_P_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 "qquickimagebase_p.h"
QT_BEGIN_NAMESPACE
@@ -44,7 +55,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 +69,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/qquickclipnode_p.h b/src/quick/items/qquickclipnode_p.h
index 2e7fa1f495..70dbf149b2 100644
--- a/src/quick/items/qquickclipnode_p.h
+++ b/src/quick/items/qquickclipnode_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKCLIPNODE_P_H
#define QQUICKCLIPNODE_P_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 <private/qtquickglobal_p.h>
#include <QtQuick/qsgnode.h>
diff --git a/src/quick/items/qquickdrag_p.h b/src/quick/items/qquickdrag_p.h
index 4bd4cfc6fd..5599831b6f 100644
--- a/src/quick/items/qquickdrag_p.h
+++ b/src/quick/items/qquickdrag_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKDRAG_P_H
#define QQUICKDRAG_P_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 <QtQuick/qquickitem.h>
#include <private/qv8engine_p.h>
@@ -140,7 +151,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 +170,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/qquickdroparea_p.h b/src/quick/items/qquickdroparea_p.h
index 3223f4203b..127b3bd4a3 100644
--- a/src/quick/items/qquickdroparea_p.h
+++ b/src/quick/items/qquickdroparea_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKDROPAREA_P_H
#define QQUICKDROPAREA_P_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 "qquickitem.h"
#include <private/qqmlguard_p.h>
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 19fb66c19c..9d6c51f37a 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -218,7 +218,7 @@ QQuickFlickablePrivate::QQuickFlickablePrivate()
, hMoved(false), vMoved(false)
, stealMouse(false), pressed(false)
, scrollingPhase(false), interactive(true), calcVelocity(false)
- , pixelAligned(false), replayingPressEvent(false)
+ , pixelAligned(false)
, lastPosTime(-1)
, lastPressTime(0)
, deceleration(QML_FLICK_DEFAULTDECELERATION)
@@ -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())
@@ -1639,10 +1640,8 @@ void QQuickFlickable::geometryChanged(const QRectF &newGeometry,
bool changed = false;
if (newGeometry.width() != oldGeometry.width()) {
changed = true; // we must update visualArea.widthRatio
- if (d->hData.viewSize < 0) {
+ if (d->hData.viewSize < 0)
d->contentItem->setWidth(width());
- emit contentWidthChanged();
- }
// Make sure that we're entirely in view.
if (!d->pressed && !d->hData.moving && !d->vData.moving) {
d->fixupMode = QQuickFlickablePrivate::Immediate;
@@ -1651,10 +1650,8 @@ void QQuickFlickable::geometryChanged(const QRectF &newGeometry,
}
if (newGeometry.height() != oldGeometry.height()) {
changed = true; // we must update visualArea.heightRatio
- if (d->vData.viewSize < 0) {
+ if (d->vData.viewSize < 0)
d->contentItem->setHeight(height());
- emit contentHeightChanged();
- }
// Make sure that we're entirely in view.
if (!d->pressed && !d->hData.moving && !d->vData.moving) {
d->fixupMode = QQuickFlickablePrivate::Immediate;
@@ -1670,6 +1667,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 +1679,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);
}
@@ -2195,10 +2202,6 @@ bool QQuickFlickable::sendMouseEvent(QQuickItem *item, QMouseEvent *event)
d->handleMouseMoveEvent(mouseEvent.data());
break;
case QEvent::MouseButtonPress:
- // Don't process a replayed event during replay
- if (d->replayingPressEvent)
- return false;
-
d->handleMousePressEvent(mouseEvent.data());
d->captureDelayedPress(item, event);
stealThisEvent = d->stealMouse; // Update stealThisEvent in case changed by function call above
diff --git a/src/quick/items/qquickflickable_p.h b/src/quick/items/qquickflickable_p.h
index 3c3cd362dd..ac072f0e50 100644
--- a/src/quick/items/qquickflickable_p.h
+++ b/src/quick/items/qquickflickable_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKFLICKABLE_P_H
#define QQUICKFLICKABLE_P_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 "qquickitem.h"
#include <private/qtquickglobal_p.h>
@@ -93,7 +104,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 +187,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/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h
index 65bb3e802d..9d75533c8a 100644
--- a/src/quick/items/qquickflickable_p_p.h
+++ b/src/quick/items/qquickflickable_p_p.h
@@ -211,7 +211,6 @@ public:
bool interactive : 1;
bool calcVelocity : 1;
bool pixelAligned : 1;
- bool replayingPressEvent : 1;
QElapsedTimer timer;
qint64 lastPosTime;
qint64 lastPressTime;
diff --git a/src/quick/items/qquickflickablebehavior_p.h b/src/quick/items/qquickflickablebehavior_p.h
index a79297894c..69fca4d0fb 100644
--- a/src/quick/items/qquickflickablebehavior_p.h
+++ b/src/quick/items/qquickflickablebehavior_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKFLICKABLEBEHAVIOR_H
#define QQUICKFLICKABLEBEHAVIOR_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.
+//
+
/* ### Platform specific flickable mechanics are defined either here, or in
mkspec files. Long-term (QtQuick 3) Flickable needs to allow such
mechanic details to be controlled via QML so that platforms can easily
diff --git a/src/quick/items/qquickflipable_p.h b/src/quick/items/qquickflipable_p.h
index bd2efe0676..93610031f6 100644
--- a/src/quick/items/qquickflipable_p.h
+++ b/src/quick/items/qquickflipable_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKFLIPABLE_P_H
#define QQUICKFLIPABLE_P_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 "qquickitem.h"
#include <QtGui/qtransform.h>
@@ -47,7 +58,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 +74,7 @@ public:
void setBack(QQuickItem *);
enum Side { Front, Back };
+ Q_ENUM(Side)
Side side() const;
Q_SIGNALS:
diff --git a/src/quick/items/qquickfocusscope_p.h b/src/quick/items/qquickfocusscope_p.h
index b0e92cb312..eb42cf83b5 100644
--- a/src/quick/items/qquickfocusscope_p.h
+++ b/src/quick/items/qquickfocusscope_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKFOCUSSCOPE_P_H
#define QQUICKFOCUSSCOPE_P_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 "qquickitem.h"
QT_BEGIN_NAMESPACE
diff --git a/src/quick/items/qquickframebufferobject.cpp b/src/quick/items/qquickframebufferobject.cpp
index 4638bbbdf3..5ce3ae57f7 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..65d7362e84 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 && (!topItem || topItem->index != currentIndex)) {
// StrictlyEnforceRange always keeps an item in range
updateHighlight();
topItem = currentItem;
}
FxViewItem *bottomItem = snapItemAt(tempPosition+highlightRangeEnd);
- if (!bottomItem && strictHighlightRange && currentItem) {
+ if (strictHighlightRange && currentItem && (!bottomItem || bottomItem->index != currentIndex)) {
// 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..8c93f4ce97 100644
--- a/src/quick/items/qquickgridview_p.h
+++ b/src/quick/items/qquickgridview_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKGRIDVIEW_P_H
#define QQUICKGRIDVIEW_P_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 "qquickitemview_p.h"
@@ -52,8 +63,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 +70,7 @@ public:
FlowLeftToRight = LeftToRight,
FlowTopToBottom = TopToBottom
};
+ Q_ENUM(Flow)
QQuickGridView(QQuickItem *parent=0);
~QQuickGridView();
@@ -78,6 +88,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.cpp b/src/quick/items/qquickimage.cpp
index 483d86c97d..20f4551af9 100644
--- a/src/quick/items/qquickimage.cpp
+++ b/src/quick/items/qquickimage.cpp
@@ -196,7 +196,6 @@ void QQuickImagePrivate::setPixmap(const QQuickPixmap &pixmap)
Set this property to define what happens when the source image has a different size
than the item.
-
\list
\li Image.Stretch - the image is scaled to fit
\li Image.PreserveAspectFit - the image is scaled uniformly to fit without cropping
@@ -309,8 +308,8 @@ void QQuickImage::setFillMode(FillMode mode)
\qmlproperty real QtQuick::Image::paintedHeight
These properties hold the size of the image that is actually painted.
- In most cases it is the same as \c width and \c height, but when using a
- \c fillMode \c PreserveAspectFit or \c fillMode \c PreserveAspectCrop
+ In most cases it is the same as \c width and \c height, but when using an
+ \l {fillMode}{Image.PreserveAspectFit} or an \l {fillMode}{Image.PreserveAspectCrop}
\c paintedWidth or \c paintedHeight can be smaller or larger than
\c width and \c height of the Image item.
*/
diff --git a/src/quick/items/qquickimage_p.h b/src/quick/items/qquickimage_p.h
index be514ae2f5..82bd005463 100644
--- a/src/quick/items/qquickimage_p.h
+++ b/src/quick/items/qquickimage_p.h
@@ -34,18 +34,26 @@
#ifndef QQUICKIMAGE_P_H
#define QQUICKIMAGE_P_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 "qquickimagebase_p.h"
#include <QtQuick/qsgtextureprovider.h>
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 +70,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 72325243df..073fe58e7b 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.path(QUrl::PrettyDecoded);
+ 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);
@@ -346,7 +358,7 @@ void QQuickImageBase::resolve2xLocalFile(const QUrl &url, qreal targetDevicePixe
Q_ASSERT(sourceDevicePixelRatio);
// Bail out if "@2x" image loading is disabled, don't change the source url or devicePixelRatio.
- static bool disable2xImageLoading = !qgetenv("QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING").isEmpty();
+ static const bool disable2xImageLoading = !qEnvironmentVariableIsEmpty("QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING");
if (disable2xImageLoading)
return;
@@ -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..b6d592c826 100644
--- a/src/quick/items/qquickimagebase_p.h
+++ b/src/quick/items/qquickimagebase_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKIMAGEBASE_P_H
#define QQUICKIMAGEBASE_P_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 "qquickimplicitsizeitem_p.h"
#include <private/qtquickglobal_p.h>
@@ -43,7 +54,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 +67,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.h b/src/quick/items/qquickimplicitsizeitem_p.h
index 3499cf22c5..1acbb7791d 100644
--- a/src/quick/items/qquickimplicitsizeitem_p.h
+++ b/src/quick/items/qquickimplicitsizeitem_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKIMPLICITSIZEITEM_H
#define QQUICKIMPLICITSIZEITEM_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 "qquickpainteditem.h"
#include <private/qtquickglobal_p.h>
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 fbea3a0ee1..fd1b74d32d 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -72,14 +72,14 @@
#endif
#include <algorithm>
-#include <float.h>
+#include <limits>
// XXX todo Check that elements that create items handle memory correctly after visual ownership change
QT_BEGIN_NAMESPACE
#ifndef QT_NO_DEBUG
-static bool qsg_leak_check = !qgetenv("QML_LEAK_CHECK").isEmpty();
+static const bool qsg_leak_check = !qEnvironmentVariableIsEmpty("QML_LEAK_CHECK");
#endif
void debugFocusTree(QQuickItem *item, QQuickItem *scope = 0, int depth = 1)
@@ -217,8 +217,8 @@ bool QQuickContents::calcHeight(QQuickItem *changed)
m_y = top;
m_height = bottom - top;
} else {
- qreal top = FLT_MAX;
- qreal bottom = 0;
+ qreal top = std::numeric_limits<qreal>::max();
+ qreal bottom = -std::numeric_limits<qreal>::max();
QList<QQuickItem *> children = m_item->childItems();
for (int i = 0; i < children.count(); ++i) {
QQuickItem *child = children.at(i);
@@ -252,8 +252,8 @@ bool QQuickContents::calcWidth(QQuickItem *changed)
m_x = left;
m_width = right - left;
} else {
- qreal left = FLT_MAX;
- qreal right = 0;
+ qreal left = std::numeric_limits<qreal>::max();
+ qreal right = -std::numeric_limits<qreal>::max();
QList<QQuickItem *> children = m_item->childItems();
for (int i = 0; i < children.count(); ++i) {
QQuickItem *child = children.at(i);
@@ -622,7 +622,7 @@ void QQuickKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
QQuickItem* leftItem = mirror ? d->right : d->left;
if (leftItem) {
- setFocusNavigation(leftItem, mirror ? "right" : "left");
+ setFocusNavigation(leftItem, mirror ? "right" : "left", mirror ? Qt::TabFocusReason : Qt::BacktabFocusReason);
event->accept();
}
break;
@@ -632,20 +632,20 @@ void QQuickKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
QQuickItem* rightItem = mirror ? d->left : d->right;
if (rightItem) {
- setFocusNavigation(rightItem, mirror ? "left" : "right");
+ setFocusNavigation(rightItem, mirror ? "left" : "right", mirror ? Qt::BacktabFocusReason : Qt::TabFocusReason);
event->accept();
}
break;
}
case Qt::Key_Up:
if (d->up) {
- setFocusNavigation(d->up, "up");
+ setFocusNavigation(d->up, "up", Qt::BacktabFocusReason);
event->accept();
}
break;
case Qt::Key_Down:
if (d->down) {
- setFocusNavigation(d->down, "down");
+ setFocusNavigation(d->down, "down", Qt::TabFocusReason);
event->accept();
}
break;
@@ -1306,8 +1306,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);
@@ -1610,6 +1610,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;
@@ -2345,6 +2424,50 @@ bool QQuickItemPrivate::focusNextPrev(QQuickItem *item, bool forward)
return true;
}
+QQuickItem *QQuickItemPrivate::nextTabChildItem(const QQuickItem *item, int start)
+{
+ if (!item) {
+ qWarning() << "QQuickItemPrivate::nextTabChildItem called with null item.";
+ return Q_NULLPTR;
+ }
+ const QList<QQuickItem *> &children = item->childItems();
+ const int count = children.count();
+ if (start < 0 || start >= count) {
+ qWarning() << "QQuickItemPrivate::nextTabChildItem: Start index value out of range for item" << item;
+ return Q_NULLPTR;
+ }
+ while (start < count) {
+ QQuickItem *child = children.at(start);
+ if (!child->d_func()->isTabFence)
+ return child;
+ ++start;
+ }
+ return Q_NULLPTR;
+}
+
+QQuickItem *QQuickItemPrivate::prevTabChildItem(const QQuickItem *item, int start)
+{
+ if (!item) {
+ qWarning() << "QQuickItemPrivate::prevTabChildItem called with null item.";
+ return Q_NULLPTR;
+ }
+ const QList<QQuickItem *> &children = item->childItems();
+ const int count = children.count();
+ if (start == -1)
+ start = count - 1;
+ if (start < 0 || start >= count) {
+ qWarning() << "QQuickItemPrivate::prevTabChildItem: Start index value out of range for item" << item;
+ return Q_NULLPTR;
+ }
+ while (start >= 0) {
+ QQuickItem *child = children.at(start);
+ if (!child->d_func()->isTabFence)
+ return child;
+ --start;
+ }
+ return Q_NULLPTR;
+}
+
QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, bool forward)
{
Q_ASSERT(item);
@@ -2367,7 +2490,6 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
from = item->parentItem();
}
bool skip = false;
- const QQuickItem * const originalItem = item;
QQuickItem * startItem = item;
QQuickItem * firstFromItem = from;
QQuickItem *current = item;
@@ -2376,46 +2498,53 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
QQuickItem *last = current;
bool hasChildren = !current->childItems().isEmpty() && current->isEnabled() && current->isVisible();
+ QQuickItem *firstChild = Q_NULLPTR;
+ QQuickItem *lastChild = Q_NULLPTR;
+ if (hasChildren) {
+ firstChild = nextTabChildItem(current, 0);
+ if (!firstChild)
+ hasChildren = false;
+ else
+ lastChild = prevTabChildItem(current, -1);
+ }
+ bool isTabFence = current->d_func()->isTabFence;
// coming from parent: check children
if (hasChildren && from == current->parentItem()) {
if (forward) {
- current = current->childItems().first();
+ current = firstChild;
} else {
- current = current->childItems().last();
+ current = lastChild;
if (!current->childItems().isEmpty())
skip = true;
}
- } else if (hasChildren && forward && from != current->childItems().last()) {
+ } else if (hasChildren && forward && from != lastChild) {
// not last child going forwards
int nextChild = current->childItems().indexOf(from) + 1;
- current = current->childItems().at(nextChild);
- } else if (hasChildren && !forward && from != current->childItems().first()) {
+ current = nextTabChildItem(current, nextChild);
+ } else if (hasChildren && !forward && from != firstChild) {
// not first child going backwards
int prevChild = current->childItems().indexOf(from) - 1;
- current = current->childItems().at(prevChild);
+ current = prevTabChildItem(current, prevChild);
if (!current->childItems().isEmpty())
skip = true;
// back to the parent
- } else if (current->parentItem()) {
- current = current->parentItem();
+ } else if (QQuickItem *parent = !isTabFence ? current->parentItem() : Q_NULLPTR) {
// we would evaluate the parent twice, thus we skip
if (forward) {
skip = true;
- } else if (!forward && !current->childItems().isEmpty()) {
- if (last != current->childItems().first()) {
- skip = true;
- } else if (last == current->childItems().first()) {
- if (current->isFocusScope() && current->activeFocusOnTab() && current->hasActiveFocus())
+ } else if (QQuickItem *firstSibling = !forward ? nextTabChildItem(parent, 0) : Q_NULLPTR) {
+ if (last != firstSibling
+ || (parent->isFocusScope() && parent->activeFocusOnTab() && parent->hasActiveFocus()))
skip = true;
- }
}
+ current = parent;
} else if (hasChildren) {
// Wrap around after checking all items forward
if (forward) {
- current = current->childItems().first();
+ current = firstChild;
} else {
- current = current->childItems().last();
+ current = lastChild;
if (!current->childItems().isEmpty())
skip = true;
}
@@ -2423,9 +2552,9 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
from = last;
if (current == startItem && from == firstFromItem) {
// wrapped around, avoid endless loops
- if (originalItem == contentItem) {
+ if (item == contentItem) {
qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: looped, return contentItem";
- return item->window()->contentItem();
+ return item;
} else {
qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: looped, return " << startItem;
return startItem;
@@ -2475,7 +2604,7 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
QQuickItem *itemAncestor = parentItem;
while (itemAncestor != 0) {
if (itemAncestor == this) {
- qWarning("QQuickItem::setParentItem: Parent is already part of this items subtree.");
+ qWarning() << "QQuickItem::setParentItem: Parent" << parentItem << "is already part of the subtree of" << this;
return;
}
itemAncestor = itemAncestor->parentItem();
@@ -2587,7 +2716,15 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
/*!
Moves the specified \a sibling item to the index before this item
- within the visual stacking order.
+ within the list of children. The order of children affects both the
+ visual stacking order and tab focus navigation order.
+
+ Assuming the z values of both items are the same, this will cause \a
+ sibling to be rendered above this item.
+
+ If both items have activeFocusOnTab set to \c true, this will also cause
+ the tab focus order to change, with \a sibling receiving focus after this
+ item.
The given \a sibling must be a sibling of this item; that is, they must
have the same immediate \l parent.
@@ -2623,7 +2760,15 @@ void QQuickItem::stackBefore(const QQuickItem *sibling)
/*!
Moves the specified \a sibling item to the index after this item
- within the visual stacking order.
+ within the list of children. The order of children affects both the
+ visual stacking order and tab focus navigation order.
+
+ Assuming the z values of both items are the same, this will cause \a
+ sibling to be rendered below this item.
+
+ If both items have activeFocusOnTab set to \c true, this will also cause
+ the tab focus order to change, with \a sibling receiving focus before this
+ item.
The given \a sibling must be a sibling of this item; that is, they must
have the same immediate \l parent.
@@ -2778,7 +2923,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);
@@ -2810,7 +2955,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)
@@ -2949,6 +3094,8 @@ QQuickItemPrivate::QQuickItemPrivate()
, activeFocusOnTab(false)
, implicitAntialiasing(false)
, antialiasingValid(false)
+ , isTabFence(false)
+ , replayingPressEvent(false)
, dirtyAttributes(0)
, nextDirtyItem(0)
, prevDirtyItem(0)
@@ -3962,6 +4109,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;
}
@@ -4104,7 +4256,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();
}
}
@@ -5578,7 +5730,7 @@ QString QQuickItemPrivate::dirtyToString() const
{
#define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
if (!rv.isEmpty()) \
- rv.append(QLatin1String("|")); \
+ rv.append(QLatin1Char('|')); \
rv.append(QLatin1String(#value)); \
}
@@ -7408,6 +7560,7 @@ QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
, m_effectComponent(0)
, m_effect(0)
, m_effectSource(0)
+ , m_textureMirroring(QQuickShaderEffectSource::MirrorVertically)
{
}
@@ -7481,6 +7634,7 @@ void QQuickItemLayer::activate()
m_effectSource->setMipmap(m_mipmap);
m_effectSource->setWrapMode(m_wrapMode);
m_effectSource->setFormat(m_format);
+ m_effectSource->setTextureMirroring(m_textureMirroring);
if (m_effectComponent)
activateEffect();
@@ -7745,6 +7899,35 @@ void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode)
}
/*!
+ \qmlproperty enumeration QtQuick::Item::layer.textureMirroring
+ \since 5.6
+
+ This property defines how the generated OpenGL texture should be mirrored.
+ The default value is \c{ShaderEffectSource.MirrorVertically}.
+ Custom mirroring can be useful if the generated texture is directly accessed by custom shaders,
+ such as those specified by ShaderEffect. If no effect is specified for the layered
+ item, mirroring has no effect on the UI representation of the item.
+
+ \list
+ \li ShaderEffectSource.NoMirroring - No mirroring
+ \li ShaderEffectSource.MirrorHorizontally - The generated texture is flipped along X-axis.
+ \li ShaderEffectSource.MirrorVertically - The generated texture is flipped along Y-axis.
+ \endlist
+ */
+
+void QQuickItemLayer::setTextureMirroring(QQuickShaderEffectSource::TextureMirroring mirroring)
+{
+ if (mirroring == m_textureMirroring)
+ return;
+ m_textureMirroring = mirroring;
+
+ if (m_effectSource)
+ m_effectSource->setTextureMirroring(m_textureMirroring);
+
+ emit textureMirroringChanged(mirroring);
+}
+
+/*!
\qmlproperty string QtQuick::Item::layer.samplerName
Holds the name of the effect's source texture property.
@@ -7856,6 +8039,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),
@@ -7864,6 +8048,19 @@ QQuickItemPrivate::ExtraData::ExtraData()
{
}
+
+#ifndef QT_NO_ACCESSIBILITY
+QAccessible::Role QQuickItemPrivate::accessibleRole() const
+{
+ Q_Q(const QQuickItem);
+ QQuickAccessibleAttached *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(q, false));
+ if (accessibleAttached)
+ return accessibleAttached->role();
+
+ return QAccessible::NoRole;
+}
+#endif
+
QT_END_NAMESPACE
#include <moc_qquickitem.cpp>
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..634aa2b658 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
@@ -142,6 +143,7 @@ class QQuickItemLayer : public QObject, public QQuickItemChangeListener
Q_PROPERTY(QQuickShaderEffectSource::Format format READ format WRITE setFormat NOTIFY formatChanged)
Q_PROPERTY(QByteArray samplerName READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(QQmlComponent *effect READ effect WRITE setEffect NOTIFY effectChanged)
+ Q_PROPERTY(QQuickShaderEffectSource::TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged)
public:
QQuickItemLayer(QQuickItem *item);
~QQuickItemLayer();
@@ -176,6 +178,9 @@ public:
QQmlComponent *effect() const { return m_effectComponent; }
void setEffect(QQmlComponent *effect);
+ QQuickShaderEffectSource::TextureMirroring textureMirroring() const { return m_textureMirroring; }
+ void setTextureMirroring(QQuickShaderEffectSource::TextureMirroring mirroring);
+
QQuickShaderEffectSource *effectSource() const { return m_effectSource; }
void itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &) Q_DECL_OVERRIDE;
@@ -199,6 +204,7 @@ Q_SIGNALS:
void smoothChanged(bool smooth);
void formatChanged(QQuickShaderEffectSource::Format format);
void sourceRectChanged(const QRectF &sourceRect);
+ void textureMirroringChanged(QQuickShaderEffectSource::TextureMirroring mirroring);
private:
friend class QQuickTransformAnimatorJob;
@@ -222,6 +228,7 @@ private:
QQmlComponent *m_effectComponent;
QQuickItem *m_effect;
QQuickShaderEffectSource *m_effectSource;
+ QQuickShaderEffectSource::TextureMirroring m_textureMirroring;
};
class Q_QUICK_PRIVATE_EXPORT QQuickItemPrivate : public QObjectPrivate
@@ -338,6 +345,7 @@ public:
QQuickContents *contents;
QQuickScreenAttached *screenAttached;
QQuickLayoutMirroringAttached* layoutDirectionAttached;
+ QQuickEnterKeyAttached *enterKeyAttached;
QQuickItemKeyFilter *keyHandler;
mutable QQuickItemLayer *layer;
#ifndef QT_NO_CURSOR
@@ -419,6 +427,13 @@ public:
bool activeFocusOnTab:1;
bool implicitAntialiasing:1;
bool antialiasingValid:1;
+ // isTabFence: When true, the item acts as a fence within the tab focus chain.
+ // This means that the item and its children will be skipped from the tab focus
+ // chain when navigating from its parent or any of its siblings. Similarly,
+ // when any of the item's descendants gets focus, the item constrains the tab
+ // focus chain and prevents tabbing outside.
+ bool isTabFence:1;
+ bool replayingPressEvent:1;
enum DirtyType {
TransformOrigin = 0x00000001,
@@ -490,6 +505,8 @@ public:
void itemToParentTransform(QTransform &) const;
static bool focusNextPrev(QQuickItem *item, bool forward);
+ static QQuickItem *nextTabChildItem(const QQuickItem *item, int start);
+ static QQuickItem *prevTabChildItem(const QQuickItem *item, int start);
static QQuickItem *nextPrevItemInTabFocusChain(QQuickItem *item, bool forward);
static bool canAcceptTabFocus(QQuickItem *item);
@@ -517,6 +534,10 @@ public:
virtual void implicitWidthChanged();
virtual void implicitHeightChanged();
+#ifndef QT_NO_ACCESSIBILITY
+ virtual QAccessible::Role accessibleRole() const;
+#endif
+
void setImplicitAntialiasing(bool antialiasing);
void resolveLayoutMirror();
@@ -645,8 +666,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 +683,7 @@ public:
void setBacktab(QQuickItem *);
enum Priority { BeforeItem, AfterItem };
+ Q_ENUM(Priority)
Priority priority() const;
void setPriority(Priority);
@@ -710,6 +730,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 +780,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 +794,7 @@ public:
}
enum Priority { BeforeItem, AfterItem};
+ Q_ENUM(Priority)
Priority priority() const;
void setPriority(Priority);
@@ -895,5 +935,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..338af46ecb 100644
--- a/src/quick/items/qquickitemanimation_p.h
+++ b/src/quick/items/qquickitemanimation_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKITEMANIMATION_H
#define QQUICKITEMANIMATION_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 "qquickitem.h"
#include <QtQuick/private/qquickanimation_p.h>
@@ -136,7 +147,7 @@ public:
BottomFirst,
TopFirst
};
- Q_ENUMS(Orientation)
+ Q_ENUM(Orientation)
int duration() const;
void setDuration(int);
diff --git a/src/quick/items/qquickitemchangelistener_p.h b/src/quick/items/qquickitemchangelistener_p.h
index d987b62454..fd8076c6a2 100644
--- a/src/quick/items/qquickitemchangelistener_p.h
+++ b/src/quick/items/qquickitemchangelistener_p.h
@@ -55,16 +55,16 @@ class QQuickAnchorsPrivate;
class QQuickItemChangeListener
{
public:
- virtual ~QQuickItemChangeListener() {};
+ virtual ~QQuickItemChangeListener() {}
virtual void itemGeometryChanged(QQuickItem *, const QRectF & /* new */, const QRectF & /* old */ ) {}
virtual void itemSiblingOrderChanged(QQuickItem *) {}
virtual void itemVisibilityChanged(QQuickItem *) {}
virtual void itemOpacityChanged(QQuickItem *) {}
virtual void itemDestroyed(QQuickItem *) {}
- virtual void itemChildAdded(QQuickItem *, QQuickItem *) {}
- virtual void itemChildRemoved(QQuickItem *, QQuickItem *) {}
- virtual void itemParentChanged(QQuickItem *, QQuickItem *) {}
+ virtual void itemChildAdded(QQuickItem *, QQuickItem * /* child */ ) {}
+ virtual void itemChildRemoved(QQuickItem *, QQuickItem * /* child */ ) {}
+ virtual void itemParentChanged(QQuickItem *, QQuickItem * /* parent */ ) {}
virtual void itemRotationChanged(QQuickItem *) {}
virtual void itemImplicitWidthChanged(QQuickItem *) {}
virtual void itemImplicitHeightChanged(QQuickItem *) {}
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index 5fbae66b6c..62e0adcb0a 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,19 @@ 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"));
+ qmlRegisterType<QQuickShaderEffectSource, 1>(uri, 2, 6, "ShaderEffectSource");
}
static void initResources()
diff --git a/src/quick/items/qquickitemsmodule_p.h b/src/quick/items/qquickitemsmodule_p.h
index a7442e972a..b04e9ff23f 100644
--- a/src/quick/items/qquickitemsmodule_p.h
+++ b/src/quick/items/qquickitemsmodule_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKITEMSMODULE_P_H
#define QQUICKITEMSMODULE_P_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 <qqml.h>
QT_BEGIN_NAMESPACE
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 01ef1e65f7..b618daf64b 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,18 +1687,20 @@ 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();
}
updateHighlight();
if (oldCurrentIndex != currentIndex)
emit q->currentIndexChanged();
- if (oldCurrentItem != currentItem)
+ if (oldCurrentItem != currentItem
+ && (!oldCurrentItem || !currentItem || oldCurrentItem->item != currentItem->item))
emit q->currentItemChanged();
releaseItem(oldCurrentItem);
}
@@ -1806,7 +1831,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 +1849,7 @@ void QQuickItemViewPrivate::layout()
if (!isValid() && !visibleItems.count()) {
clear();
setPosition(contentStartOffset());
+ updateViewport();
if (transitioner)
transitioner->setPopulateTransitionEnabled(false);
inLayout = false;
@@ -1967,7 +1993,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 +2033,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 +2068,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 +2121,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 +2381,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 +2452,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..789b5a3e55 100644
--- a/src/quick/items/qquickitemview_p.h
+++ b/src/quick/items/qquickitemview_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKITEMVIEW_P_H
#define QQUICKITEMVIEW_P_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 "qquickflickable_p.h"
#include <qpointer.h>
#include <QtCore/QLoggingCategory>
@@ -88,11 +99,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 +109,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 +193,7 @@ public:
virtual void setHighlightFollowsCurrentItem(bool);
enum HighlightRangeMode { NoHighlightRange, ApplyRange, StrictlyEnforceRange };
+ Q_ENUM(HighlightRangeMode)
HighlightRangeMode highlightRangeMode() const;
void setHighlightRangeMode(HighlightRangeMode mode);
@@ -200,6 +209,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..8af703eb03 100644
--- a/src/quick/items/qquickitemview_p_p.h
+++ b/src/quick/items/qquickitemview_p_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKITEMVIEW_P_P_H
#define QQUICKITEMVIEW_P_P_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 "qquickitemview_p.h"
#include "qquickitemviewtransition_p.h"
#include "qquickflickable_p_p.h"
@@ -53,6 +64,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 +88,7 @@ public:
virtual bool contains(qreal x, qreal y) const = 0;
- QQuickItem *item;
+ QPointer<QQuickItem> item;
QQuickItemView *view;
QQuickItemViewTransitionableItem *transitionableItem;
QQuickItemViewAttached *attached;
@@ -198,6 +211,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 3218e3847c..565377df58 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..b4c2705fd3 100644
--- a/src/quick/items/qquickitemviewtransition_p.h
+++ b/src/quick/items/qquickitemviewtransition_p.h
@@ -34,16 +34,31 @@
#ifndef QQUICKITEMVIEWTRANSITION_P_P_H
#define QQUICKITEMVIEWTRANSITION_P_P_H
-#include <private/qquicktransitionmanager_p_p.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 <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 +68,7 @@ public:
};
-class QQuickItemViewTransitioner
+class Q_QUICK_PRIVATE_EXPORT QQuickItemViewTransitioner
{
public:
enum TransitionType {
@@ -113,7 +128,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..0211e9f285 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 {
@@ -1388,6 +1401,15 @@ void QQuickListViewPrivate::itemGeometryChanged(QQuickItem *item, const QRectF &
if (!q->isComponentComplete())
return;
+ if (currentItem && currentItem->item == item) {
+ const bool contentFlowReversed = isContentFlowReversed();
+ const qreal pos = position();
+ const qreal sz = size();
+ const qreal from = contentFlowReversed ? -pos - displayMarginBeginning - sz : pos - displayMarginBeginning;
+ const qreal to = contentFlowReversed ? -pos + displayMarginEnd : pos + sz + displayMarginEnd;
+ QQuickItemPrivate::get(currentItem->item)->setCulled(currentItem->endPosition() < from || currentItem->position() > to);
+ }
+
if (item != contentItem && (!highlight || item != highlight->item)) {
if ((orient == QQuickListView::Vertical && newGeometry.height() != oldGeometry.height())
|| (orient == QQuickListView::Horizontal && newGeometry.width() != oldGeometry.width())) {
@@ -1457,13 +1479,13 @@ void QQuickListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExte
tempPosition -= bias;
}
FxViewItem *topItem = snapItemAt(tempPosition+highlightRangeStart);
- if (!topItem && strictHighlightRange && currentItem) {
+ if (strictHighlightRange && currentItem && (!topItem || topItem->index != currentIndex)) {
// StrictlyEnforceRange always keeps an item in range
updateHighlight();
topItem = currentItem;
}
FxViewItem *bottomItem = snapItemAt(tempPosition+highlightRangeEnd);
- if (!bottomItem && strictHighlightRange && currentItem) {
+ if (strictHighlightRange && currentItem && (!bottomItem || bottomItem->index != currentIndex)) {
// StrictlyEnforceRange always keeps an item in range
updateHighlight();
bottomItem = currentItem;
@@ -2844,7 +2866,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..5f8be2ab02 100644
--- a/src/quick/items/qquicklistview_p.h
+++ b/src/quick/items/qquicklistview_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKLISTVIEW_P_H
#define QQUICKLISTVIEW_P_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 "qquickitemview_p.h"
QT_BEGIN_NAMESPACE
@@ -47,8 +58,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 +65,7 @@ public:
void setProperty(const QString &);
enum SectionCriteria { FullString, FirstCharacter };
+ Q_ENUM(SectionCriteria)
SectionCriteria criteria() const { return m_criteria; }
void setCriteria(SectionCriteria);
@@ -65,6 +75,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 +117,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 +127,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 +148,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..456eedd0be 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)
@@ -932,7 +931,7 @@ QUrl QQuickLoaderPrivate::resolveSourceUrl(QQmlV4Function *args)
if (arg.isEmpty())
return QUrl();
- QQmlContextData *context = args->context();
+ QQmlContextData *context = scope.engine->callingQmlContext();
Q_ASSERT(context);
return context->resolvedUrl(QUrl(arg));
}
@@ -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..e9d765fa5c 100644
--- a/src/quick/items/qquickloader_p.h
+++ b/src/quick/items/qquickloader_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKLOADER_P_H
#define QQUICKLOADER_P_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 "qquickimplicitsizeitem_p.h"
QT_BEGIN_NAMESPACE
@@ -42,7 +53,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 +79,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/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp
index 4a44760035..b933dc240a 100644
--- a/src/quick/items/qquickmousearea.cpp
+++ b/src/quick/items/qquickmousearea.cpp
@@ -921,6 +921,7 @@ bool QQuickMouseArea::sendMouseEvent(QMouseEvent *event)
break;
case QEvent::MouseButtonRelease:
mouseReleaseEvent(&mouseEvent);
+ stealThisEvent = d->stealMouse;
break;
default:
break;
diff --git a/src/quick/items/qquickmousearea_p.h b/src/quick/items/qquickmousearea_p.h
index 4ad14e6bdd..e3cbf2553c 100644
--- a/src/quick/items/qquickmousearea_p.h
+++ b/src/quick/items/qquickmousearea_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKMOUSEAREA_P_H
#define QQUICKMOUSEAREA_P_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 "qquickitem.h"
#include <private/qtquickglobal_p.h>
#include <QtCore/qstringlist.h>
diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp
index e6b63d32f2..13ace44f9a 100644
--- a/src/quick/items/qquickmultipointtoucharea.cpp
+++ b/src/quick/items/qquickmultipointtoucharea.cpp
@@ -451,6 +451,12 @@ void QQuickMultiPointTouchArea::touchEvent(QTouchEvent *event)
}
break;
}
+ case QEvent::TouchCancel:
+ _stealMouse = false;
+ setKeepMouseGrab(false);
+ setKeepTouchGrab(false);
+ ungrabTouchPoints();
+ break;
default:
QQuickItem::touchEvent(event);
break;
diff --git a/src/quick/items/qquickmultipointtoucharea_p.h b/src/quick/items/qquickmultipointtoucharea_p.h
index e5c547da81..792724a9c8 100644
--- a/src/quick/items/qquickmultipointtoucharea_p.h
+++ b/src/quick/items/qquickmultipointtoucharea_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKMULTIPOINTTOUCHAREA_H
#define QQUICKMULTIPOINTTOUCHAREA_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 "qquickitem.h"
#include "qevent.h"
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.cpp b/src/quick/items/qquickpainteditem.cpp
index 8d93c577ab..4172b83419 100644
--- a/src/quick/items/qquickpainteditem.cpp
+++ b/src/quick/items/qquickpainteditem.cpp
@@ -67,15 +67,11 @@ public:
To enable QPainter to do anti-aliased rendering, use setAntialiasing().
- To write your own painted item, you first create a subclass of QQuickPaintedItem, and then
- start by implementing its only pure virtual public function: paint(), which implements
- the actual painting. To get the size of the area painted by the item, use
- contentsBoundingRect().
-
- Starting Qt 5.4, the QQuickPaintedItem is a
- \l{QSGTextureProvider}{texture provider}
- and can be used directly in \l {ShaderEffect}{ShaderEffects} and other
- classes that consume texture providers.
+ To write your own painted item, you first create a subclass of
+ QQuickPaintedItem, and then start by implementing its only pure virtual
+ public function: paint(), which implements the actual painting. The
+ painting will be inside the rectangle spanning from 0,0 to
+ width(),height().
*/
/*!
@@ -109,11 +105,12 @@ public:
This enum describes flags that you can enable to improve rendering
performance in QQuickPaintedItem. By default, none of these flags are set.
- \value FastFBOResizing If your item gets resized often and you are using the
- QQuickPaintedItem::FramebufferObject render target, set this flag to true to reduce the
- item resizing time at the cost of using more graphics memory. Resizing a Framebuffer object
- is a costly operation, by enabling this property the Framebuffer Object will use a texture
- larger than the actual size of the item to avoid as much as possible resizing it.
+ \value FastFBOResizing Resizing an FBO can be a costly operation on a few
+ OpenGL driver implementations. To work around this, one can set this flag
+ to let the QQuickPaintedItem allocate one large framebuffer object and
+ instead draw into a subregion of it. This saves the resize at the cost of
+ using more memory. Please note that this is not a common problem.
+
*/
/*!
@@ -332,16 +329,47 @@ void QQuickPaintedItem::setPerformanceHints(QQuickPaintedItem::PerformanceHints
update();
}
+QSize QQuickPaintedItem::textureSize() const
+{
+ Q_D(const QQuickPaintedItem);
+ return d->textureSize;
+}
+
/*!
- This function returns the outer bounds of the item as a rectangle; all painting must be
- restricted to inside an item's bounding rect.
+ \property QQuickPaintedItem::textureSize
+
+ \brief Defines the size of the texture.
- If the contents size has not been set it reflects the size of the item; otherwise
- it reflects the contents size scaled by the contents scale.
+ Changing the texture's size does not affect the coordinate system used in
+ paint(). A scale factor is instead applied so painting should still happen
+ inside 0,0 to width(),height().
- Use this function to know the area painted by the item.
+ By default, the texture size will have the same size as this item.
- \sa QQuickItem::width(), QQuickItem::height(), contentsSize(), contentsScale()
+ \note If the item is on a window with a device pixel ratio different from
+ 1, this scale factor will be implicitly applied to the texture size.
+
+ */
+void QQuickPaintedItem::setTextureSize(const QSize &size)
+{
+ Q_D(QQuickPaintedItem);
+ if (d->textureSize == size)
+ return;
+ d->textureSize = size;
+ emit textureSizeChanged();
+}
+
+#if QT_VERSION >= 0x060000
+#warning "Remove: QQuickPaintedItem::contentsBoundingRect, contentsScale, contentsSize. Also remove them from qsgadaptationlayer_p.h and qsgdefaultpainternode.h/cpp."
+#endif
+
+/*!
+ \obsolete
+
+ This function is provided for compatibility, use size in combination
+ with textureSize to decide the size of what you are drawing.
+
+ \sa width(), height(), textureSize()
*/
QRectF QQuickPaintedItem::contentsBoundingRect() const
{
@@ -360,11 +388,13 @@ QRectF QQuickPaintedItem::contentsBoundingRect() const
/*!
\property QQuickPaintedItem::contentsSize
- \brief The size of the contents
+ \brief Obsolete method for setting the contents size.
+ \obsolete
+
+ This function is provided for compatibility, use size in combination
+ with textureSize to decide the size of what you are drawing.
- The contents size is the size of the item in regards to how it is painted
- using the paint() function. This is distinct from the size of the
- item in regards to height() and width().
+ \sa width(), height(), textureSize()
*/
QSize QQuickPaintedItem::contentsSize() const
{
@@ -386,6 +416,7 @@ void QQuickPaintedItem::setContentsSize(const QSize &size)
}
/*!
+ \obsolete
This convenience function is equivalent to calling setContentsSize(QSize()).
*/
void QQuickPaintedItem::resetContentsSize()
@@ -395,12 +426,13 @@ void QQuickPaintedItem::resetContentsSize()
/*!
\property QQuickPaintedItem::contentsScale
- \brief The scale of the contents
+ \brief Obsolete method for scaling the contents.
+ \obsolete
- All painting happening in paint() is scaled by the contents scale. This is distinct
- from the scale of the item in regards to scale().
+ This function is provided for compatibility, use size() in combination
+ with textureSize() to decide the size of what you are drawing.
- The default value is 1.
+ \sa width(), height(), textureSize()
*/
qreal QQuickPaintedItem::contentsScale() const
{
@@ -487,6 +519,9 @@ void QQuickPaintedItem::setRenderTarget(RenderTarget target)
This function, which is usually called by the QML Scene Graph, paints the
contents of an item in local coordinates.
+ The underlying texture will have a size defined by textureSize when set,
+ or the item's size, multiplied by the window's device pixel ratio.
+
The function is called after the item has been filled with the fillColor.
Reimplement this function in a QQuickPaintedItem subclass to provide the
@@ -500,6 +535,8 @@ void QQuickPaintedItem::setRenderTarget(RenderTarget target)
\warning Extreme caution must be used when creating QObjects, emitting signals, starting
timers and similar inside this function as these will have affinity to the rendering thread.
+
+ \sa width(), height(), textureSize
*/
/*!
@@ -525,17 +562,35 @@ QSGNode *QQuickPaintedItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat
d->node = node;
}
- QRectF br = contentsBoundingRect();
+ bool hasTextureSize = d->textureSize.width() > 0 && d->textureSize.height() > 0;
+
+ // Use the compat mode if any of the compat things are set and
+ // textureSize is 0x0.
+ if (!hasTextureSize
+ && (d->contentsScale != 1
+ || (d->contentsSize.width() > 0 && d->contentsSize.height() > 0))) {
+ QRectF br = contentsBoundingRect();
+ node->setContentsScale(d->contentsScale);
+ QSize size = QSize(qRound(br.width()), qRound(br.height()));
+ node->setSize(size);
+ node->setTextureSize(size);
+ } else {
+ // The default, use textureSize or item's size * device pixel ratio
+ node->setContentsScale(1);
+ QSize itemSize(qRound(width()), qRound(height()));
+ node->setSize(itemSize);
+ QSize textureSize = (hasTextureSize ? d->textureSize : itemSize)
+ * window()->effectiveDevicePixelRatio();
+ node->setTextureSize(textureSize);
+ }
node->setPreferredRenderTarget(d->renderTarget);
node->setFastFBOResizing(d->performanceHints & FastFBOResizing);
- node->setSize(QSize(qRound(br.width()), qRound(br.height())));
node->setSmoothPainting(d->antialiasing);
node->setLinearFiltering(d->smooth);
node->setMipmapping(d->mipmap);
node->setOpaquePainting(d->opaquePainting);
node->setFillColor(d->fillColor);
- node->setContentsScale(d->contentsScale);
node->setDirty(d->dirtyRect);
node->update();
diff --git a/src/quick/items/qquickpainteditem.h b/src/quick/items/qquickpainteditem.h
index 356e4a46f6..8c9ae2eebb 100644
--- a/src/quick/items/qquickpainteditem.h
+++ b/src/quick/items/qquickpainteditem.h
@@ -43,12 +43,13 @@ 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)
Q_PROPERTY(qreal contentsScale READ contentsScale WRITE setContentsScale NOTIFY contentsScaleChanged)
Q_PROPERTY(RenderTarget renderTarget READ renderTarget WRITE setRenderTarget NOTIFY renderTargetChanged)
+ Q_PROPERTY(QSize textureSize READ textureSize WRITE setTextureSize NOTIFY textureSizeChanged)
+
public:
QQuickPaintedItem(QQuickItem *parent = 0);
virtual ~QQuickPaintedItem();
@@ -58,6 +59,7 @@ public:
FramebufferObject,
InvertedYFramebufferObject
};
+ Q_ENUM(RenderTarget)
enum PerformanceHint {
FastFBOResizing = 0x1
@@ -88,6 +90,9 @@ public:
qreal contentsScale() const;
void setContentsScale(qreal);
+ QSize textureSize() const;
+ void setTextureSize(const QSize &size);
+
QColor fillColor() const;
void setFillColor(const QColor&);
@@ -104,6 +109,7 @@ Q_SIGNALS:
void contentsSizeChanged();
void contentsScaleChanged();
void renderTargetChanged();
+ void textureSizeChanged();
protected:
QQuickPaintedItem(QQuickPaintedItemPrivate &dd, QQuickItem *parent = 0);
diff --git a/src/quick/items/qquickpainteditem_p.h b/src/quick/items/qquickpainteditem_p.h
index 3712e964f8..d0e4f9481d 100644
--- a/src/quick/items/qquickpainteditem_p.h
+++ b/src/quick/items/qquickpainteditem_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKPAINTEDITEM_P_P_H
#define QQUICKPAINTEDITEM_P_P_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 "qquickitem_p.h"
#include <QtGui/qcolor.h>
@@ -42,7 +53,7 @@ QT_BEGIN_NAMESPACE
class QQuickPaintedItemTextureProvider;
class QSGPainterNode;
-class QQuickPaintedItemPrivate : public QQuickItemPrivate
+class Q_QUICK_PRIVATE_EXPORT QQuickPaintedItemPrivate : public QQuickItemPrivate
{
public:
QQuickPaintedItemPrivate();
@@ -52,6 +63,7 @@ public:
QColor fillColor;
QQuickPaintedItem::RenderTarget renderTarget;
QQuickPaintedItem::PerformanceHints performanceHints;
+ QSize textureSize;
QRect dirtyRect;
diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp
index 58605f79dd..05bf50574c 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();
}
@@ -754,7 +753,7 @@ void QQuickPathView::setCurrentIndex(int idx)
if (d->modelCount) {
d->createCurrentItem();
if (d->haveHighlightRange && d->highlightRangeMode == QQuickPathView::StrictlyEnforceRange)
- d->snapToIndex(d->currentIndex);
+ d->snapToIndex(d->currentIndex, QQuickPathViewPrivate::SetIndex);
d->currentItemOffset = d->positionOfIndex(d->currentIndex);
d->updateHighlight();
}
@@ -989,7 +988,7 @@ void QQuickPathView::setHighlightRangeMode(HighlightRangeMode mode)
d->regenerate();
int index = d->highlightRangeMode != NoHighlightRange ? d->currentIndex : d->calcCurrentIndex();
if (index >= 0)
- d->snapToIndex(index);
+ d->snapToIndex(index, QQuickPathViewPrivate::Other);
}
emit highlightRangeModeChanged();
}
@@ -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))
@@ -2241,12 +2306,12 @@ void QQuickPathViewPrivate::fixOffset()
if (curr != currentIndex && highlightRangeMode == QQuickPathView::StrictlyEnforceRange)
q->setCurrentIndex(curr);
else
- snapToIndex(curr);
+ snapToIndex(curr, Other);
}
}
}
-void QQuickPathViewPrivate::snapToIndex(int index)
+void QQuickPathViewPrivate::snapToIndex(int index, MovementReason reason)
{
if (!model || modelCount <= 0)
return;
@@ -2256,7 +2321,7 @@ void QQuickPathViewPrivate::snapToIndex(int index)
if (offset == targetOffset)
return;
- moveReason = Other;
+ moveReason = reason;
offsetAdj = 0.0;
tl.reset(moveOffset);
moveOffset.setValue(offset);
diff --git a/src/quick/items/qquickpathview_p.h b/src/quick/items/qquickpathview_p.h
index 8062e07795..0973d65a58 100644
--- a/src/quick/items/qquickpathview_p.h
+++ b/src/quick/items/qquickpathview_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKPATHVIEW_P_H
#define QQUICKPATHVIEW_P_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 "qquickitem.h"
#include <private/qquickpath_p.h>
@@ -78,10 +89,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 +112,7 @@ public:
QQuickItem *highlightItem();
enum HighlightRangeMode { NoHighlightRange, ApplyRange, StrictlyEnforceRange };
+ Q_ENUM(HighlightRangeMode)
HighlightRangeMode highlightRangeMode() const;
void setHighlightRangeMode(HighlightRangeMode mode);
@@ -146,10 +154,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..73e4884424 100644
--- a/src/quick/items/qquickpathview_p_p.h
+++ b/src/quick/items/qquickpathview_p_p.h
@@ -114,7 +114,8 @@ public:
void setAdjustedOffset(qreal offset);
void regenerate();
void updateItem(QQuickItem *, qreal);
- void snapToIndex(int index);
+ enum MovementReason { Other, SetIndex, Mouse };
+ void snapToIndex(int index, MovementReason reason);
QPointF pointNear(const QPointF &point, qreal *nearPercent=0) const;
void addVelocitySample(qreal v);
qreal calcVelocity() const;
@@ -155,7 +156,6 @@ public:
QQuickTimeLine tl;
QQuickTimeLineValueProxy<QQuickPathViewPrivate> moveOffset;
int flickDuration;
- int firstIndex;
int pathItems;
int requestedIndex;
int cacheSize;
@@ -164,7 +164,6 @@ public:
QList<QQuickItem *> itemCache;
QPointer<QQmlInstanceModel> model;
QVariant modelVariant;
- enum MovementReason { Other, SetIndex, Mouse };
MovementReason moveReason;
enum MovementDirection { Shortest, Negative, Positive };
MovementDirection moveDirection;
diff --git a/src/quick/items/qquickpincharea_p.h b/src/quick/items/qquickpincharea_p.h
index d2de59b5d6..d623a70010 100644
--- a/src/quick/items/qquickpincharea_p.h
+++ b/src/quick/items/qquickpincharea_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKPINCHAREA_H
#define QQUICKPINCHAREA_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 "qquickitem.h"
QT_BEGIN_NAMESPACE
@@ -42,7 +53,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 +113,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..fca64b0a22 100644
--- a/src/quick/items/qquickpositioners_p.h
+++ b/src/quick/items/qquickpositioners_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKPOSITIONERS_P_H
#define QQUICKPOSITIONERS_P_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 "qquickimplicitsizeitem_p.h"
#include "qquickitemviewtransition_p.h"
@@ -86,6 +97,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 +125,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 +157,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 +186,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 +285,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 +294,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 +350,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..feca74cb41 100644
--- a/src/quick/items/qquickrectangle_p.h
+++ b/src/quick/items/qquickrectangle_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKRECTANGLE_P_H
#define QQUICKRECTANGLE_P_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 "qquickitem.h"
#include <QtGui/qbrush.h>
@@ -125,7 +136,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/qquickrepeater_p.h b/src/quick/items/qquickrepeater_p.h
index 5f652da975..c0a0a32f5f 100644
--- a/src/quick/items/qquickrepeater_p.h
+++ b/src/quick/items/qquickrepeater_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKREPEATER_P_H
#define QQUICKREPEATER_P_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 "qquickitem.h"
QT_BEGIN_NAMESPACE
diff --git a/src/quick/items/qquickscalegrid_p_p.h b/src/quick/items/qquickscalegrid_p_p.h
index 7e0c021c19..1d067f1a94 100644
--- a/src/quick/items/qquickscalegrid_p_p.h
+++ b/src/quick/items/qquickscalegrid_p_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKSCALEGRID_P_P_H
#define QQUICKSCALEGRID_P_P_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 "qquickborderimage_p.h"
#include <QtQml/qqml.h>
@@ -47,7 +58,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/qquickscreen_p.h b/src/quick/items/qquickscreen_p.h
index 266f7bfed8..d8c8cbde2f 100644
--- a/src/quick/items/qquickscreen_p.h
+++ b/src/quick/items/qquickscreen_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKSCREEN_P_H
#define QQUICKSCREEN_P_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 <qqml.h>
#include <QRect>
#include <QSize>
diff --git a/src/quick/items/qquickshadereffect_p.h b/src/quick/items/qquickshadereffect_p.h
index 1c60d9feaa..a5e993ee0c 100644
--- a/src/quick/items/qquickshadereffect_p.h
+++ b/src/quick/items/qquickshadereffect_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKSHADEREFFECT_P_H
#define QQUICKSHADEREFFECT_P_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 <QtQuick/qquickitem.h>
#include <QtQuick/qsgmaterial.h>
@@ -92,8 +103,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 +111,7 @@ public:
BackFaceCulling = QQuickShaderEffectMaterial::BackFaceCulling,
FrontFaceCulling = QQuickShaderEffectMaterial::FrontFaceCulling
};
+ Q_ENUM(CullMode)
enum Status
{
@@ -109,6 +119,7 @@ public:
Uncompiled,
Error
};
+ Q_ENUM(Status)
QQuickShaderEffect(QQuickItem *parent = 0);
~QQuickShaderEffect();
diff --git a/src/quick/items/qquickshadereffectmesh_p.h b/src/quick/items/qquickshadereffectmesh_p.h
index b392753bf8..eb0f03ea81 100644
--- a/src/quick/items/qquickshadereffectmesh_p.h
+++ b/src/quick/items/qquickshadereffectmesh_p.h
@@ -43,6 +43,17 @@
#ifndef QQUICKSHADEREFFECTMESH_P_H
#define QQUICKSHADEREFFECTMESH_P_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.
+//
+
QT_BEGIN_NAMESPACE
class QSGGeometry;
diff --git a/src/quick/items/qquickshadereffectnode.cpp b/src/quick/items/qquickshadereffectnode.cpp
index be6ecfae18..081e572e3b 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);
}
@@ -458,7 +460,7 @@ void QQuickShaderEffectMaterial::updateTextures() const
{
for (int i = 0; i < textureProviders.size(); ++i) {
if (QSGTextureProvider *provider = textureProviders.at(i)) {
- if (QSGLayer *texture = qobject_cast<QSGLayer *>(provider->texture()))
+ if (QSGDynamicTexture *texture = qobject_cast<QSGDynamicTexture *>(provider->texture()))
texture->updateTexture();
}
}
diff --git a/src/quick/items/qquickshadereffectnode_p.h b/src/quick/items/qquickshadereffectnode_p.h
index a6a6d1b2fc..76aecd1b04 100644
--- a/src/quick/items/qquickshadereffectnode_p.h
+++ b/src/quick/items/qquickshadereffectnode_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKSHADEREFFECTNODE_P_H
#define QQUICKSHADEREFFECTNODE_P_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 <QtQuick/qsgnode.h>
#include <QtQuick/qsgmaterial.h>
#include <QtQuick/qsgtextureprovider.h>
diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp
index bf69fe4277..2effc0d0ae 100644
--- a/src/quick/items/qquickshadereffectsource.cpp
+++ b/src/quick/items/qquickshadereffectsource.cpp
@@ -189,6 +189,7 @@ QQuickShaderEffectSource::QQuickShaderEffectSource(QQuickItem *parent)
, m_mipmap(false)
, m_recursive(false)
, m_grab(true)
+ , m_textureMirroring(MirrorVertically)
{
setFlag(ItemHasContents);
}
@@ -543,6 +544,37 @@ void QQuickShaderEffectSource::setRecursive(bool enabled)
}
/*!
+ \qmlproperty enumeration QtQuick::ShaderEffectSource::textureMirroring
+ \since 5.6
+
+ This property defines how the generated OpenGL texture should be mirrored.
+ The default value is \c{ShaderEffectSource.MirrorVertically}.
+ Custom mirroring can be useful if the generated texture is directly accessed by custom shaders,
+ such as those specified by ShaderEffect. Mirroring has no effect on the UI representation of
+ the ShaderEffectSource item itself.
+
+ \list
+ \li ShaderEffectSource.NoMirroring - No mirroring
+ \li ShaderEffectSource.MirrorHorizontally - The generated texture is flipped along X-axis.
+ \li ShaderEffectSource.MirrorVertically - The generated texture is flipped along Y-axis.
+ \endlist
+*/
+
+QQuickShaderEffectSource::TextureMirroring QQuickShaderEffectSource::textureMirroring() const
+{
+ return QQuickShaderEffectSource::TextureMirroring(m_textureMirroring);
+}
+
+void QQuickShaderEffectSource::setTextureMirroring(TextureMirroring mirroring)
+{
+ if (mirroring == QQuickShaderEffectSource::TextureMirroring(m_textureMirroring))
+ return;
+ m_textureMirroring = mirroring;
+ update();
+ emit textureMirroringChanged();
+}
+
+/*!
\qmlmethod QtQuick::ShaderEffectSource::scheduleUpdate()
Schedules a re-rendering of the texture for the next frame.
@@ -642,6 +674,8 @@ QSGNode *QQuickShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaint
m_texture->setRecursive(m_recursive);
m_texture->setFormat(GLenum(m_format));
m_texture->setHasMipmaps(m_mipmap);
+ m_texture->setMirrorHorizontal(m_textureMirroring & MirrorHorizontally);
+ m_texture->setMirrorVertical(m_textureMirroring & MirrorVertically);
if (m_grab)
m_texture->scheduleUpdate();
diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h
index 31e503be42..c9d50cef9e 100644
--- a/src/quick/items/qquickshadereffectsource_p.h
+++ b/src/quick/items/qquickshadereffectsource_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKSHADEREFFECTSOURCE_P_H
#define QQUICKSHADEREFFECTSOURCE_P_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 "qquickitem.h"
#include <QtQuick/qsgtextureprovider.h>
#include <private/qsgadaptationlayer_p.h>
@@ -66,8 +77,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectSource : public QQuickItem, publi
Q_PROPERTY(bool hideSource READ hideSource WRITE setHideSource NOTIFY hideSourceChanged)
Q_PROPERTY(bool mipmap READ mipmap WRITE setMipmap NOTIFY mipmapChanged)
Q_PROPERTY(bool recursive READ recursive WRITE setRecursive NOTIFY recursiveChanged)
+ Q_PROPERTY(TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged REVISION 1)
- Q_ENUMS(Format WrapMode)
public:
enum WrapMode {
ClampToEdge,
@@ -75,12 +86,21 @@ public:
RepeatVertically,
Repeat
};
+ Q_ENUM(WrapMode)
enum Format {
Alpha = GL_ALPHA,
RGB = GL_RGB,
RGBA = GL_RGBA
};
+ Q_ENUM(Format)
+
+ enum TextureMirroring {
+ NoMirroring = 0x00,
+ MirrorHorizontally = 0x01,
+ MirrorVertically = 0x02
+ };
+ Q_ENUM(TextureMirroring)
QQuickShaderEffectSource(QQuickItem *parent = 0);
~QQuickShaderEffectSource();
@@ -112,6 +132,9 @@ public:
bool recursive() const;
void setRecursive(bool enabled);
+ TextureMirroring textureMirroring() const;
+ void setTextureMirroring(TextureMirroring mirroring);
+
bool isTextureProvider() const Q_DECL_OVERRIDE { return true; }
QSGTextureProvider *textureProvider() const Q_DECL_OVERRIDE;
@@ -127,6 +150,7 @@ Q_SIGNALS:
void hideSourceChanged();
void mipmapChanged();
void recursiveChanged();
+ void textureMirroringChanged();
void scheduledUpdateCompleted();
@@ -156,6 +180,7 @@ private:
uint m_mipmap : 1;
uint m_recursive : 1;
uint m_grab : 1;
+ uint m_textureMirroring : 2; // Stores TextureMirroring enum
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquicksprite_p.h b/src/quick/items/qquicksprite_p.h
index 86350738a0..43c5e44be3 100644
--- a/src/quick/items/qquicksprite_p.h
+++ b/src/quick/items/qquicksprite_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKSPRITE_P_H
#define QQUICKSPRITE_P_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 <QObject>
#include <QUrl>
#include <QVariantMap>
diff --git a/src/quick/items/qquickspriteengine_p.h b/src/quick/items/qquickspriteengine_p.h
index ef52bcc9fe..48808e73c9 100644
--- a/src/quick/items/qquickspriteengine_p.h
+++ b/src/quick/items/qquickspriteengine_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKSPRITEENGINE_P_H
#define QQUICKSPRITEENGINE_P_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 <QObject>
#include <QVector>
#include <QTimer>
diff --git a/src/quick/items/qquickspritesequence_p.h b/src/quick/items/qquickspritesequence_p.h
index f5d467580d..54ed2636b2 100644
--- a/src/quick/items/qquickspritesequence_p.h
+++ b/src/quick/items/qquickspritesequence_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKSPRITESEQUENCE_P_H
#define QQUICKSPRITESEQUENCE_P_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 <QtQuick/QQuickItem>
#include <QTime>
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..f1959fa374 100644
--- a/src/quick/items/qquickstateoperations_p.h
+++ b/src/quick/items/qquickstateoperations_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKSTATEOPERATIONS_P_H
#define QQUICKSTATEOPERATIONS_P_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 "qquickitem.h"
#include "qquickanchors_p.h"
@@ -97,9 +108,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 +191,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 f848d0baee..223219a3f9 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -40,6 +40,7 @@
#include "qquicktextnode_p.h"
#include "qquickimage_p_p.h"
#include "qquicktextutil_p.h"
+#include "qquicktextdocument_p.h"
#include <QtQuick/private/qsgtexture_p.h>
@@ -85,7 +86,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)
@@ -104,180 +114,105 @@ void QQuickTextPrivate::init()
q->setFlag(QQuickItem::ItemHasContents);
}
-QQuickTextDocumentWithImageResources::QQuickTextDocumentWithImageResources(QQuickItem *parent)
-: QTextDocument(parent), outstanding(0)
-{
- setUndoRedoEnabled(false);
- documentLayout()->registerHandler(QTextFormat::ImageObject, this);
- connect(this, SIGNAL(baseUrlChanged(QUrl)), this, SLOT(reset()));
-}
-
-QQuickTextDocumentWithImageResources::~QQuickTextDocumentWithImageResources()
+QQuickTextPrivate::~QQuickTextPrivate()
{
- if (!m_resources.isEmpty())
- qDeleteAll(m_resources);
-}
+ delete elideLayout;
+ delete textLine; textLine = 0;
-QVariant QQuickTextDocumentWithImageResources::loadResource(int type, const QUrl &name)
-{
- QVariant resource = QTextDocument::loadResource(type, name);
- if (resource.isNull() && type == QTextDocument::ImageResource) {
- QQmlContext *context = qmlContext(parent());
- QUrl url = baseUrl().resolved(name);
- QQuickPixmap *p = loadPixmap(context, url);
- resource = p->image();
+ if (extra.isAllocated()) {
+ qDeleteAll(extra->imgTags);
+ extra->imgTags.clear();
}
-
- return resource;
}
-void QQuickTextDocumentWithImageResources::requestFinished()
+qreal QQuickTextPrivate::getImplicitWidth() const
{
- outstanding--;
- if (outstanding == 0) {
- markContentsDirty(0, characterCount());
- emit imagesLoaded();
+ if (!requireImplicitSize) {
+ // We don't calculate implicitWidth unless it is required.
+ // We need to force a size update now to ensure implicitWidth is calculated
+ QQuickTextPrivate *me = const_cast<QQuickTextPrivate*>(this);
+ me->requireImplicitSize = true;
+ me->updateSize();
}
+ return implicitWidth;
}
-QSizeF QQuickTextDocumentWithImageResources::intrinsicSize(
- QTextDocument *, int, const QTextFormat &format)
+qreal QQuickTextPrivate::getImplicitHeight() const
{
- if (format.isImageFormat()) {
- QTextImageFormat imageFormat = format.toImageFormat();
-
- const int width = qRound(imageFormat.width());
- const bool hasWidth = imageFormat.hasProperty(QTextFormat::ImageWidth) && width > 0;
- const int height = qRound(imageFormat.height());
- const bool hasHeight = imageFormat.hasProperty(QTextFormat::ImageHeight) && height > 0;
-
- QSizeF size(width, height);
- if (!hasWidth || !hasHeight) {
- QVariant res = resource(QTextDocument::ImageResource, QUrl(imageFormat.name()));
- QImage image = res.value<QImage>();
- if (image.isNull()) {
- if (!hasWidth)
- size.setWidth(16);
- if (!hasHeight)
- size.setHeight(16);
- return size;
- }
- QSize imgSize = image.size();
-
- if (!hasWidth) {
- if (!hasHeight)
- size.setWidth(imgSize.width());
- else
- size.setWidth(qRound(height * (imgSize.width() / (qreal) imgSize.height())));
- }
- if (!hasHeight) {
- if (!hasWidth)
- size.setHeight(imgSize.height());
- else
- size.setHeight(qRound(width * (imgSize.height() / (qreal) imgSize.width())));
- }
- }
- return size;
+ if (!requireImplicitSize) {
+ QQuickTextPrivate *me = const_cast<QQuickTextPrivate*>(this);
+ me->requireImplicitSize = true;
+ me->updateSize();
}
- return QSizeF();
-}
-
-void QQuickTextDocumentWithImageResources::drawObject(
- QPainter *, const QRectF &, QTextDocument *, int, const QTextFormat &)
-{
+ return implicitHeight;
}
-QImage QQuickTextDocumentWithImageResources::image(const QTextImageFormat &format)
+qreal QQuickTextPrivate::availableWidth() const
{
- QVariant res = resource(QTextDocument::ImageResource, QUrl(format.name()));
- return res.value<QImage>();
+ Q_Q(const QQuickText);
+ return q->width() - q->leftPadding() - q->rightPadding();
}
-void QQuickTextDocumentWithImageResources::reset()
+qreal QQuickTextPrivate::availableHeight() const
{
- clearResources();
- markContentsDirty(0, characterCount());
+ Q_Q(const QQuickText);
+ return q->height() - q->topPadding() - q->bottomPadding();
}
-QQuickPixmap *QQuickTextDocumentWithImageResources::loadPixmap(
- QQmlContext *context, const QUrl &url)
+void QQuickTextPrivate::setTopPadding(qreal value, bool reset)
{
-
- QHash<QUrl, QQuickPixmap *>::Iterator iter = m_resources.find(url);
-
- if (iter == m_resources.end()) {
- QQuickPixmap *p = new QQuickPixmap(context->engine(), url);
- iter = m_resources.insert(url, p);
-
- if (p->isLoading()) {
- p->connectFinished(this, SLOT(requestFinished()));
- outstanding++;
- }
+ Q_Q(QQuickText);
+ qreal oldPadding = q->topPadding();
+ if (!reset || extra.isAllocated()) {
+ extra.value().topPadding = value;
+ extra.value().explicitTopPadding = !reset;
}
-
- QQuickPixmap *p = *iter;
- if (p->isError()) {
- if (!errors.contains(url)) {
- errors.insert(url);
- qmlInfo(parent()) << p->error();
- }
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding()))) {
+ updateSize();
+ emit q->topPaddingChanged();
}
- return p;
-}
-
-void QQuickTextDocumentWithImageResources::clearResources()
-{
- foreach (QQuickPixmap *pixmap, m_resources)
- pixmap->clear(this);
- qDeleteAll(m_resources);
- m_resources.clear();
- outstanding = 0;
-}
-
-void QQuickTextDocumentWithImageResources::setText(const QString &text)
-{
- clearResources();
-
-#ifndef QT_NO_TEXTHTMLPARSER
- setHtml(text);
-#else
- setPlainText(text);
-#endif
}
-QSet<QUrl> QQuickTextDocumentWithImageResources::errors;
-
-QQuickTextPrivate::~QQuickTextPrivate()
+void QQuickTextPrivate::setLeftPadding(qreal value, bool reset)
{
- delete elideLayout;
- delete textLine; textLine = 0;
-
- if (extra.isAllocated()) {
- qDeleteAll(extra->imgTags);
- extra->imgTags.clear();
+ 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();
}
}
-qreal QQuickTextPrivate::getImplicitWidth() const
+void QQuickTextPrivate::setRightPadding(qreal value, bool reset)
{
- if (!requireImplicitSize) {
- // We don't calculate implicitWidth unless it is required.
- // We need to force a size update now to ensure implicitWidth is calculated
- QQuickTextPrivate *me = const_cast<QQuickTextPrivate*>(this);
- me->requireImplicitSize = true;
- me->updateSize();
+ 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();
}
- return implicitWidth;
}
-qreal QQuickTextPrivate::getImplicitHeight() const
+void QQuickTextPrivate::setBottomPadding(qreal value, bool reset)
{
- if (!requireImplicitSize) {
- QQuickTextPrivate *me = const_cast<QQuickTextPrivate*>(this);
- me->requireImplicitSize = true;
- me->updateSize();
+ 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();
}
- return implicitHeight;
}
/*!
@@ -323,9 +258,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) {
@@ -406,7 +341,7 @@ void QQuickTextPrivate::updateBaseline(qreal baseline, qreal dy)
yoff = dy/2;
}
- q->setBaselineOffset(baseline + yoff);
+ q->setBaselineOffset(baseline + yoff + q->topPadding());
}
void QQuickTextPrivate::updateSize()
@@ -426,6 +361,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
@@ -438,8 +376,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;
@@ -460,7 +398,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.
@@ -484,15 +422,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)
@@ -501,7 +439,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;
@@ -509,11 +447,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)
@@ -619,7 +557,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)
@@ -631,10 +569,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);
@@ -687,10 +625,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;
@@ -726,7 +665,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;
@@ -747,8 +686,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;
@@ -918,7 +857,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.
@@ -935,8 +874,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.
@@ -989,7 +931,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))
@@ -1069,7 +1011,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);
@@ -1092,7 +1034,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
default:
break;
}
- elideLayout->setAdditionalFormats(formats);
+ elideLayout->setFormats(formats);
}
elideLayout->setFont(layout.font());
@@ -1283,6 +1225,13 @@ QQuickText::QQuickText(QQuickItem *parent)
d->init();
}
+QQuickText::QQuickText(QQuickTextPrivate &dd, QQuickItem *parent)
+: QQuickImplicitSizeItem(dd, parent)
+{
+ Q_D(QQuickText);
+ d->init();
+}
+
QQuickText::~QQuickText()
{
}
@@ -1357,6 +1306,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 font.weight, \l font.bold and \l font.italic.
+*/
+
+/*!
\qmlproperty bool QtQuick::Text::font.bold
Sets whether the font weight is bold.
@@ -2194,18 +2153,19 @@ void QQuickText::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeo
bool widthMaximum = newGeometry.width() >= oldGeometry.width() && !d->widthExceeded;
bool heightMaximum = newGeometry.height() >= oldGeometry.height() && !d->heightExceeded;
+ bool verticalPositionChanged = heightChanged && d->vAlign != AlignTop;
+
if ((!widthChanged && !heightChanged) || d->internalWidthUpdate)
goto geomChangeDone;
- if ((effectiveHAlign() != QQuickText::AlignLeft && widthChanged)
- || (vAlign() != QQuickText::AlignTop && heightChanged)) {
+ if ((effectiveHAlign() != QQuickText::AlignLeft && widthChanged) || verticalPositionChanged) {
// If the width has changed and we're not left aligned do an update so the text is
// repositioned even if a full layout isn't required. And the same for vertical.
d->updateType = QQuickTextPrivate::UpdatePaintNode;
update();
}
- if (!wrapped && !elide && !scaleFont)
+ if (!wrapped && !elide && !scaleFont && !verticalPositionChanged)
goto geomChangeDone; // left aligned unwrapped text without eliding never needs relayout
if (elide // eliding and dimensions were and remain invalid;
@@ -2214,7 +2174,7 @@ void QQuickText::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeo
goto geomChangeDone;
}
- if (widthMaximum && heightMaximum && !d->isLineLaidOutConnected()) // Size is sufficient and growing.
+ if (widthMaximum && heightMaximum && !d->isLineLaidOutConnected() && !verticalPositionChanged) // Size is sufficient and growing.
goto geomChangeDone;
if (!(widthChanged || widthMaximum) && !d->isLineLaidOutConnected()) { // only height has changed
@@ -2275,7 +2235,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)
@@ -2292,11 +2252,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;
@@ -2566,7 +2526,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) {
@@ -2583,14 +2543,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();
@@ -2808,4 +2769,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..5b385aeb0a 100644
--- a/src/quick/items/qquicktext_p.h
+++ b/src/quick/items/qquicktext_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKTEXT_P_H
#define QQUICKTEXT_P_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 "qquickimplicitsizeitem_p.h"
#include <private/qtquickglobal_p.h>
#include <QtGui/qtextoption.h>
@@ -45,15 +56,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 +86,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 +100,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 +127,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 +221,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,8 +268,15 @@ 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:
+ QQuickText(QQuickTextPrivate &dd, QQuickItem *parent = 0);
+
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void itemChange(ItemChange change, const ItemChangeData &value) Q_DECL_OVERRIDE;
diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h
index 28435bc8c5..c8cadcece9 100644
--- a/src/quick/items/qquicktext_p_p.h
+++ b/src/quick/items/qquicktext_p_p.h
@@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE
class QTextLayout;
class QQuickTextDocumentWithImageResources;
-class Q_AUTOTEST_EXPORT QQuickTextPrivate : public QQuickImplicitSizeItemPrivate
+class Q_QUICK_PRIVATE_EXPORT QQuickTextPrivate : public QQuickImplicitSizeItemPrivate
{
Q_DECLARE_PUBLIC(QQuickText)
public:
@@ -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);
@@ -178,45 +196,6 @@ public:
static inline QQuickTextPrivate *get(QQuickText *t) { return t->d_func(); }
};
-class QQuickPixmap;
-class Q_AUTOTEST_EXPORT QQuickTextDocumentWithImageResources : public QTextDocument, public QTextObjectInterface
-{
- Q_OBJECT
- Q_INTERFACES(QTextObjectInterface)
-public:
- QQuickTextDocumentWithImageResources(QQuickItem *parent);
- virtual ~QQuickTextDocumentWithImageResources();
-
- void setText(const QString &);
- int resourcesLoading() const { return outstanding; }
-
- QSizeF intrinsicSize(QTextDocument *doc, int posInDocument, const QTextFormat &format);
- void drawObject(QPainter *p, const QRectF &rect, QTextDocument *doc, int posInDocument, const QTextFormat &format);
-
- QImage image(const QTextImageFormat &format);
-
-public Q_SLOTS:
- void clearResources();
-
-Q_SIGNALS:
- void imagesLoaded();
-
-protected:
- QVariant loadResource(int type, const QUrl &name);
-
- QQuickPixmap *loadPixmap(QQmlContext *context, const QUrl &name);
-
-private Q_SLOTS:
- void reset();
- void requestFinished();
-
-private:
- QHash<QUrl, QQuickPixmap *> m_resources;
-
- int outstanding;
- static QSet<QUrl> errors;
-};
-
QT_END_NAMESPACE
#endif // QQUICKTEXT_P_P_H
diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp
index 6929bb44a2..04e43c017e 100644
--- a/src/quick/items/qquicktextcontrol.cpp
+++ b/src/quick/items/qquicktextcontrol.cpp
@@ -106,7 +106,9 @@ QQuickTextControlPrivate::QQuickTextControlPrivate()
hadSelectionOnMousePress(false),
wordSelectionEnabled(false),
hasImState(false),
- cursorRectangleChanged(false)
+ cursorRectangleChanged(false),
+ lastSelectionStart(-1),
+ lastSelectionEnd(-1)
{}
bool QQuickTextControlPrivate::cursorMoveKeyEvent(QKeyEvent *e)
@@ -403,11 +405,19 @@ void QQuickTextControlPrivate::selectionChanged(bool forceEmitSelectionChanged /
}
bool current = cursor.hasSelection();
- if (current == lastSelectionState)
+ int selectionStart = cursor.selectionStart();
+ int selectionEnd = cursor.selectionEnd();
+ if (current == lastSelectionState && (!current || (selectionStart == lastSelectionStart && selectionEnd == lastSelectionEnd)))
return;
- lastSelectionState = current;
- emit q->copyAvailable(current);
+ if (lastSelectionState != current) {
+ lastSelectionState = current;
+ emit q->copyAvailable(current);
+ }
+
+ lastSelectionStart = selectionStart;
+ lastSelectionEnd = selectionEnd;
+
if (!forceEmitSelectionChanged) {
#ifndef QT_NO_IM
if (hasFocus)
@@ -1313,7 +1323,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 +1346,7 @@ void QQuickTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
}
}
}
- layout->setAdditionalFormats(overrides);
+ layout->setFormats(overrides);
cursor.endEditBlock();
diff --git a/src/quick/items/qquicktextcontrol_p_p.h b/src/quick/items/qquicktextcontrol_p_p.h
index 4c3e03a552..3c2e579737 100644
--- a/src/quick/items/qquicktextcontrol_p_p.h
+++ b/src/quick/items/qquicktextcontrol_p_p.h
@@ -156,6 +156,9 @@ public:
bool hasImState : 1;
bool cursorRectangleChanged : 1;
+ int lastSelectionStart;
+ int lastSelectionEnd;
+
void _q_copyLink();
};
diff --git a/src/quick/items/qquicktextdocument.cpp b/src/quick/items/qquicktextdocument.cpp
index fa89d43b86..c8b29dc1ad 100644
--- a/src/quick/items/qquicktextdocument.cpp
+++ b/src/quick/items/qquicktextdocument.cpp
@@ -32,11 +32,16 @@
****************************************************************************/
#include "qquicktextdocument.h"
+#include "qquicktextdocument_p.h"
#include "qquicktextedit_p.h"
#include "qquicktextedit_p_p.h"
#include "qquicktext_p_p.h"
+#include <QtQml/qqmlinfo.h>
+#include <QtQml/qqmlcontext.h>
+#include <QtQuick/private/qquickpixmapcache_p.h>
+
QT_BEGIN_NAMESPACE
/*!
@@ -85,4 +90,147 @@ QTextDocument* QQuickTextDocument::textDocument() const
return d->document.data();
}
+QQuickTextDocumentWithImageResources::QQuickTextDocumentWithImageResources(QQuickItem *parent)
+: QTextDocument(parent), outstanding(0)
+{
+ setUndoRedoEnabled(false);
+ documentLayout()->registerHandler(QTextFormat::ImageObject, this);
+ connect(this, SIGNAL(baseUrlChanged(QUrl)), this, SLOT(reset()));
+}
+
+QQuickTextDocumentWithImageResources::~QQuickTextDocumentWithImageResources()
+{
+ if (!m_resources.isEmpty())
+ qDeleteAll(m_resources);
+}
+
+QVariant QQuickTextDocumentWithImageResources::loadResource(int type, const QUrl &name)
+{
+ QVariant resource = QTextDocument::loadResource(type, name);
+ if (resource.isNull() && type == QTextDocument::ImageResource) {
+ QQmlContext *context = qmlContext(parent());
+ QUrl url = baseUrl().resolved(name);
+ QQuickPixmap *p = loadPixmap(context, url);
+ resource = p->image();
+ }
+
+ return resource;
+}
+
+void QQuickTextDocumentWithImageResources::requestFinished()
+{
+ outstanding--;
+ if (outstanding == 0) {
+ markContentsDirty(0, characterCount());
+ emit imagesLoaded();
+ }
+}
+
+QSizeF QQuickTextDocumentWithImageResources::intrinsicSize(
+ QTextDocument *, int, const QTextFormat &format)
+{
+ if (format.isImageFormat()) {
+ QTextImageFormat imageFormat = format.toImageFormat();
+
+ const int width = qRound(imageFormat.width());
+ const bool hasWidth = imageFormat.hasProperty(QTextFormat::ImageWidth) && width > 0;
+ const int height = qRound(imageFormat.height());
+ const bool hasHeight = imageFormat.hasProperty(QTextFormat::ImageHeight) && height > 0;
+
+ QSizeF size(width, height);
+ if (!hasWidth || !hasHeight) {
+ QVariant res = resource(QTextDocument::ImageResource, QUrl(imageFormat.name()));
+ QImage image = res.value<QImage>();
+ if (image.isNull()) {
+ if (!hasWidth)
+ size.setWidth(16);
+ if (!hasHeight)
+ size.setHeight(16);
+ return size;
+ }
+ QSize imgSize = image.size();
+
+ if (!hasWidth) {
+ if (!hasHeight)
+ size.setWidth(imgSize.width());
+ else
+ size.setWidth(qRound(height * (imgSize.width() / (qreal) imgSize.height())));
+ }
+ if (!hasHeight) {
+ if (!hasWidth)
+ size.setHeight(imgSize.height());
+ else
+ size.setHeight(qRound(width * (imgSize.height() / (qreal) imgSize.width())));
+ }
+ }
+ return size;
+ }
+ return QSizeF();
+}
+
+void QQuickTextDocumentWithImageResources::drawObject(
+ QPainter *, const QRectF &, QTextDocument *, int, const QTextFormat &)
+{
+}
+
+QImage QQuickTextDocumentWithImageResources::image(const QTextImageFormat &format)
+{
+ QVariant res = resource(QTextDocument::ImageResource, QUrl(format.name()));
+ return res.value<QImage>();
+}
+
+void QQuickTextDocumentWithImageResources::reset()
+{
+ clearResources();
+ markContentsDirty(0, characterCount());
+}
+
+QQuickPixmap *QQuickTextDocumentWithImageResources::loadPixmap(
+ QQmlContext *context, const QUrl &url)
+{
+
+ QHash<QUrl, QQuickPixmap *>::Iterator iter = m_resources.find(url);
+
+ if (iter == m_resources.end()) {
+ QQuickPixmap *p = new QQuickPixmap(context->engine(), url);
+ iter = m_resources.insert(url, p);
+
+ if (p->isLoading()) {
+ p->connectFinished(this, SLOT(requestFinished()));
+ outstanding++;
+ }
+ }
+
+ QQuickPixmap *p = *iter;
+ if (p->isError()) {
+ if (!errors.contains(url)) {
+ errors.insert(url);
+ qmlInfo(parent()) << p->error();
+ }
+ }
+ return p;
+}
+
+void QQuickTextDocumentWithImageResources::clearResources()
+{
+ foreach (QQuickPixmap *pixmap, m_resources)
+ pixmap->clear(this);
+ qDeleteAll(m_resources);
+ m_resources.clear();
+ outstanding = 0;
+}
+
+void QQuickTextDocumentWithImageResources::setText(const QString &text)
+{
+ clearResources();
+
+#ifndef QT_NO_TEXTHTMLPARSER
+ setHtml(text);
+#else
+ setPlainText(text);
+#endif
+}
+
+QSet<QUrl> QQuickTextDocumentWithImageResources::errors;
+
QT_END_NAMESPACE
diff --git a/src/quick/items/qquicktextdocument_p.h b/src/quick/items/qquicktextdocument_p.h
new file mode 100644
index 0000000000..1a9d71fe1c
--- /dev/null
+++ b/src/quick/items/qquicktextdocument_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** 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 QQUICKTEXTDOCUMENT_P_H
+#define QQUICKTEXTDOCUMENT_P_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 <QtCore/qhash.h>
+#include <QtCore/qvariant.h>
+#include <QtGui/qimage.h>
+#include <QtGui/qtextdocument.h>
+#include <QtGui/qabstracttextdocumentlayout.h>
+#include <QtGui/qtextlayout.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickItem;
+class QQuickPixmap;
+class QQmlContext;
+
+class Q_AUTOTEST_EXPORT QQuickTextDocumentWithImageResources : public QTextDocument, public QTextObjectInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QTextObjectInterface)
+public:
+ QQuickTextDocumentWithImageResources(QQuickItem *parent);
+ virtual ~QQuickTextDocumentWithImageResources();
+
+ void setText(const QString &);
+ int resourcesLoading() const { return outstanding; }
+
+ QSizeF intrinsicSize(QTextDocument *doc, int posInDocument, const QTextFormat &format);
+ void drawObject(QPainter *p, const QRectF &rect, QTextDocument *doc, int posInDocument, const QTextFormat &format);
+
+ QImage image(const QTextImageFormat &format);
+
+public Q_SLOTS:
+ void clearResources();
+
+Q_SIGNALS:
+ void imagesLoaded();
+
+protected:
+ QVariant loadResource(int type, const QUrl &name);
+
+ QQuickPixmap *loadPixmap(QQmlContext *context, const QUrl &name);
+
+private Q_SLOTS:
+ void reset();
+ void requestFinished();
+
+private:
+ QHash<QUrl, QQuickPixmap *> m_resources;
+
+ int outstanding;
+ static QSet<QUrl> errors;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKDOCUMENT_P_H
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index cd1cf5eef1..8282c09770 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -34,7 +34,7 @@
#include "qquicktextedit_p.h"
#include "qquicktextedit_p_p.h"
#include "qquicktextcontrol_p.h"
-#include "qquicktext_p_p.h"
+#include "qquicktextdocument_p.h"
#include "qquickevents_p_p.h"
#include "qquickwindow.h"
#include "qquicktextnode_p.h"
@@ -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 font.weight, \l font.bold and \l font.italic.
+*/
+
+
+/*!
\qmlproperty bool QtQuick::TextEdit::font.bold
Sets whether the font weight is bold.
@@ -699,6 +717,75 @@ 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();
+ }
+}
+
+bool QQuickTextEditPrivate::isImplicitResizeEnabled() const
+{
+ return !extra.isAllocated() || extra->implicitResize;
+}
+
+void QQuickTextEditPrivate::setImplicitResizeEnabled(bool enabled)
+{
+ if (!enabled)
+ extra.value().implicitResize = false;
+ else if (extra.isAllocated())
+ extra->implicitResize = true;
+}
+
QQuickTextEdit::VAlignment QQuickTextEdit::vAlign() const
{
Q_D(const QQuickTextEdit);
@@ -1658,6 +1745,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 +1882,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 +1915,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 +1936,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 +1956,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 +1970,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 +1989,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 +2004,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 +2118,20 @@ 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)
+ , implicitResize(true)
+{
+}
+
void QQuickTextEditPrivate::init()
{
Q_Q(QQuickTextEdit);
@@ -2099,7 +2215,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 +2341,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 +2359,14 @@ void QQuickTextEdit::updateSize()
const bool wasInLayout = d->inLayout;
d->inLayout = true;
- setImplicitWidth(naturalWidth);
+ if (d->isImplicitResizeEnabled())
+ 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
@@ -2262,14 +2379,16 @@ void QQuickTextEdit::updateSize()
QFontMetricsF fm(d->font);
qreal newHeight = d->document->isEmpty() ? qCeil(fm.height()) : d->document->size().height();
- // ### Setting the implicitWidth triggers another updateSize(), and unless there are bindings nothing has changed.
- if (!widthValid() && !d->requireImplicitWidth)
- setImplicitSize(newWidth, newHeight);
- else
- setImplicitHeight(newHeight);
+ if (d->isImplicitResizeEnabled()) {
+ // ### Setting the implicitWidth triggers another updateSize(), and unless there are bindings nothing has changed.
+ if (!widthValid() && !d->requireImplicitWidth)
+ setImplicitSize(newWidth + leftPadding() + rightPadding(), newHeight + topPadding() + bottomPadding());
+ else
+ 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 +2535,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 +2558,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 +2709,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 +2810,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..f8b7100cfa 100644
--- a/src/quick/items/qquicktextedit_p.h
+++ b/src/quick/items/qquicktextedit_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKTEXTEDIT_P_H
#define QQUICKTEXTEDIT_P_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 "qquickimplicitsizeitem_p.h"
#include <QtGui/qtextoption.h>
@@ -47,12 +58,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 +96,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 +113,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 +135,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 +263,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 +319,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 +363,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..fed0688fd7 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,27 @@ 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;
+ bool implicitResize : 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 +142,22 @@ 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);
+
+ bool isImplicitResizeEnabled() const;
+ void setImplicitResizeEnabled(bool enabled);
+
QColor color;
QColor selectionColor;
QColor selectedTextColor;
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index db13a59a4e..087b8b8135 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 font.weight, \l font.bold and \l font.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,20 @@ 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)
+ , implicitResize(true)
+{
+}
+
void QQuickTextInputPrivate::init()
{
Q_Q(QQuickTextInput);
@@ -2882,7 +2732,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 +2740,75 @@ 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();
+ }
+}
+
+bool QQuickTextInputPrivate::isImplicitResizeEnabled() const
+{
+ return !extra.isAllocated() || extra->implicitResize;
+}
+
+void QQuickTextInputPrivate::setImplicitResizeEnabled(bool enabled)
+{
+ if (!enabled)
+ extra.value().implicitResize = false;
+ else if (extra.isAllocated())
+ extra->implicitResize = true;
+}
+
void QQuickTextInputPrivate::updateLayout()
{
Q_Q(QQuickTextInput);
@@ -2915,12 +2834,13 @@ void QQuickTextInputPrivate::updateLayout()
line.setLineWidth(INT_MAX);
const bool wasInLayout = inLayout;
inLayout = true;
- q->setImplicitWidth(qCeil(line.naturalTextWidth()));
+ if (isImplicitResizeEnabled())
+ 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 {
@@ -2946,10 +2866,12 @@ void QQuickTextInputPrivate::updateLayout()
q->polish();
q->update();
- if (!requireImplicitWidth && !q->widthValid())
- q->setImplicitSize(width, height);
- else
- q->setImplicitHeight(height);
+ if (isImplicitResizeEnabled()) {
+ if (!requireImplicitWidth && !q->widthValid())
+ q->setImplicitSize(width + q->leftPadding() + q->rightPadding(), height + q->topPadding() + q->bottomPadding());
+ else
+ q->setImplicitHeight(height + q->topPadding() + q->bottomPadding());
+ }
updateBaselineOffset();
@@ -2971,13 +2893,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 +3267,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 +3286,7 @@ void QQuickTextInputPrivate::processInputMethodEvent(QInputMethodEvent *event)
}
}
}
- m_textLayout.setAdditionalFormats(formats);
+ m_textLayout.setFormats(formats);
updateDisplayText(/*force*/ true);
if ((cursorPositionChanged && !emitCursorPositionChanged())
@@ -4273,6 +4195,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 +4445,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..8733b31960 100644
--- a/src/quick/items/qquicktextinput_p.h
+++ b/src/quick/items/qquicktextinput_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKTEXTINPUT_P_H
#define QQUICKTEXTINPUT_P_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 "qquickimplicitsizeitem_p.h"
#include <QtGui/qtextoption.h>
#include <QtGui/qvalidator.h>
@@ -45,13 +56,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 +100,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 +118,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 +141,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 +277,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 +337,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 +404,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..00d9b2b0fa 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,29 @@ 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;
+ bool implicitResize : 1;
+ };
+ QLazilyAllocated<ExtraData> extra;
+
QQuickTextInputPrivate()
: hscroll(0)
, vscroll(0)
@@ -420,6 +437,15 @@ 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);
+
+ bool isImplicitResizeEnabled() const;
+ void setImplicitResizeEnabled(bool enabled);
+
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..c6a1059e8a 100644
--- a/src/quick/items/qquicktextnode_p.h
+++ b/src/quick/items/qquicktextnode_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKTEXTNODE_P_H
#define QQUICKTEXTNODE_P_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 <QtQuick/qsgnode.h>
#include "qquicktext_p.h"
#include <qglyphrun.h>
@@ -101,14 +112,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..a65b98acd1 100644
--- a/src/quick/items/qquicktextnodeengine.cpp
+++ b/src/quick/items/qquicktextnodeengine.cpp
@@ -42,7 +42,8 @@
#include <QtGui/qtexttable.h>
#include <QtGui/qtextlist.h>
-#include <private/qquicktext_p_p.h>
+#include <private/qquicktext_p.h>
+#include <private/qquicktextdocument_p.h>
#include <private/qtextdocumentlayout_p.h>
#include <private/qtextimagehandler_p.h>
#include <private/qrawfont_p.h>
@@ -882,7 +883,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..2eae950f06 100644
--- a/src/quick/items/qquicktextnodeengine_p.h
+++ b/src/quick/items/qquicktextnodeengine_p.h
@@ -44,6 +44,17 @@
#ifndef QQUICKTEXTNODEENGINE_P_H
#define QQUICKTEXTNODEENGINE_P_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.
+//
+
QT_BEGIN_NAMESPACE
// Engine that takes glyph runs as input, and produces a set of glyph nodes, clip nodes,
@@ -231,8 +242,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/qquicktranslate_p.h b/src/quick/items/qquicktranslate_p.h
index 6dfb5a08b7..09868b5939 100644
--- a/src/quick/items/qquicktranslate_p.h
+++ b/src/quick/items/qquicktranslate_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKTRANSLATE_P_H
#define QQUICKTRANSLATE_P_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 "qquickitem.h"
#include <QtGui/qmatrix4x4.h>
diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp
index 5b5413a4ba..867f7d9d15 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>
@@ -53,7 +54,7 @@ DEFINE_OBJECT_VTABLE(QV4::QQuickRootItemMarker);
QV4::Heap::QQuickRootItemMarker *QV4::QQuickRootItemMarker::create(QQmlEngine *engine, QQuickWindow *window)
{
QV4::ExecutionEngine *e = QQmlEnginePrivate::getV4Engine(engine);
- return e->memoryManager->alloc<QQuickRootItemMarker>(e, window);
+ return e->memoryManager->allocObject<QQuickRootItemMarker>(window);
}
void QV4::QQuickRootItemMarker::markObjects(QV4::Heap::Base *that, QV4::ExecutionEngine *e)
@@ -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 && 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/qquickview_p.h b/src/quick/items/qquickview_p.h
index 6f673368d5..6f970f959d 100644
--- a/src/quick/items/qquickview_p.h
+++ b/src/quick/items/qquickview_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKVIEW_P_H
#define QQUICKVIEW_P_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 "qquickview.h"
#include <QtCore/qurl.h>
@@ -98,7 +109,10 @@ namespace QV4 {
namespace Heap {
struct QQuickRootItemMarker : Object {
- inline QQuickRootItemMarker(QV4::ExecutionEngine *engine, QQuickWindow *window);
+ inline QQuickRootItemMarker(QQuickWindow *window)
+ : window(window)
+ {
+ }
QQuickWindow *window;
};
@@ -115,12 +129,7 @@ struct QQuickRootItemMarker : public Object
};
-inline
-Heap::QQuickRootItemMarker::QQuickRootItemMarker(QV4::ExecutionEngine *engine, QQuickWindow *window)
- : Heap::Object(engine)
- , window(window)
-{
-}
+
}
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 76daa44225..6542bde4f1 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();
}
@@ -370,12 +368,15 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size)
if (!customRenderStage || !customRenderStage->render()) {
int fboId = 0;
const qreal devicePixelRatio = q->effectiveDevicePixelRatio();
- renderer->setDeviceRect(QRect(QPoint(0, 0), size * devicePixelRatio));
if (renderTargetId) {
+ QRect rect(QPoint(0, 0), renderTargetSize);
fboId = renderTargetId;
- renderer->setViewportRect(QRect(QPoint(0, 0), renderTargetSize));
+ renderer->setDeviceRect(rect);
+ renderer->setViewportRect(rect);
} else {
- renderer->setViewportRect(QRect(QPoint(0, 0), size * devicePixelRatio));
+ QRect rect(QPoint(0, 0), devicePixelRatio * size);
+ renderer->setDeviceRect(rect);
+ renderer->setViewportRect(rect);
}
renderer->setProjectionMatrixToRect(QRect(QPoint(0, 0), size));
renderer->setDevicePixelRatio(devicePixelRatio);
@@ -1433,29 +1434,8 @@ void QQuickWindowPrivate::deliverKeyEvent(QKeyEvent *e)
{
Q_Q(QQuickWindow);
-#ifndef QT_NO_SHORTCUT
- // Try looking for a Shortcut before sending key events
- if (e->type() == QEvent::KeyPress
- && QGuiApplicationPrivate::instance()->shortcutMap.tryShortcutEvent(q->focusObject(), e))
- return;
-#endif
-
if (activeFocusItem)
q->sendEvent(activeFocusItem, e);
-#ifdef Q_OS_MAC
- else {
- // This is the case for popup windows on Mac, where popup windows get focus
- // in Qt (after exposure) but they are not "key windows" in the Cocoa sense.
- // Therefore, the will never receive key events from Cocoa. Instead, the
- // toplevel non-popup window (the application current "key window") will
- // receive them. (QWidgetWindow does something similar for widgets, by keeping
- // a list of popup windows, and forwarding the key event to the top-most popup.)
- QWindow *focusWindow = QGuiApplication::focusWindow();
- if (focusWindow && focusWindow != q
- && (focusWindow->flags() & Qt::Popup) == Qt::Popup)
- QGuiApplication::sendEvent(focusWindow, e);
- }
-#endif
}
QMouseEvent *QQuickWindowPrivate::cloneMouseEvent(QMouseEvent *event, QPointF *transformedLocalPos)
@@ -2389,7 +2369,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) {
@@ -2453,9 +2435,11 @@ bool QQuickWindowPrivate::sendFilteredMouseEvent(QQuickItem *target, QQuickItem
if (!target)
return false;
- bool filtered = false;
-
QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(target);
+ if (targetPrivate->replayingPressEvent)
+ return false;
+
+ bool filtered = false;
if (targetPrivate->filtersChildMouseEvents && !hasFiltered->contains(target)) {
hasFiltered->insert(target);
if (target->childMouseEventFilter(item, event))
@@ -2733,7 +2717,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
@@ -2742,13 +2726,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));
@@ -2756,11 +2736,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));
@@ -2768,10 +2751,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)
@@ -2874,7 +2858,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
@@ -2892,14 +2879,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) {
@@ -2923,9 +2905,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);
@@ -2942,10 +2923,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()) {
@@ -3311,12 +3288,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");
@@ -3334,7 +3306,8 @@ QImage QQuickWindow::grabWindow()
d->syncSceneGraph();
d->renderSceneGraph(size());
- QImage image = qt_gl_read_framebuffer(size() * effectiveDevicePixelRatio(), false, false);
+ bool alpha = format().alphaBufferSize() > 0 && color().alpha() < 255;
+ QImage image = qt_gl_read_framebuffer(size() * effectiveDevicePixelRatio(), alpha, alpha);
d->cleanupNodesOnShutdown();
d->context->invalidate();
context.doneCurrent();
@@ -3386,6 +3359,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.
+
*/
/*!
@@ -3590,12 +3568,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.
@@ -3617,14 +3604,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);
}
@@ -4119,6 +4105,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}
*/
@@ -4144,8 +4131,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(),
@@ -4157,16 +4153,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 b63143178b..e475c48b0a 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -202,7 +202,7 @@ public:
QQuickItem *dirtyItemList;
QList<QSGNode *> cleanupNodeList;
- QSet<QQuickItem *> itemsToPolish;
+ QVector<QQuickItem *> itemsToPolish;
void updateDirtyNodes();
void cleanupNodes();
diff --git a/src/quick/items/qquickwindowattached_p.h b/src/quick/items/qquickwindowattached_p.h
index 8138ab216a..98b28430b2 100644
--- a/src/quick/items/qquickwindowattached_p.h
+++ b/src/quick/items/qquickwindowattached_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKWINDOW_ATTACHED_P_H
#define QQUICKWINDOW_ATTACHED_P_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 <qqml.h>
#include <QWindow>
diff --git a/src/quick/items/qquickwindowmodule_p.h b/src/quick/items/qquickwindowmodule_p.h
index bfc51953ca..8396019102 100644
--- a/src/quick/items/qquickwindowmodule_p.h
+++ b/src/quick/items/qquickwindowmodule_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKWINDOWMODULE_H
#define QQUICKWINDOWMODULE_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 <private/qtquickglobal_p.h>
#include <qquickwindow.h>
#include <qqmlparserstatus.h>
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/qtquick2_p.h b/src/quick/qtquick2_p.h
index f501323cde..523842a4cd 100644
--- a/src/quick/qtquick2_p.h
+++ b/src/quick/qtquick2_p.h
@@ -34,6 +34,17 @@
#ifndef QTQUICK2_P_H
#define QTQUICK2_P_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 <private/qtquickglobal_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/quick/scenegraph/coreapi/qsgabstractrenderer_p.h b/src/quick/scenegraph/coreapi/qsgabstractrenderer_p.h
index c5504513f4..17de89bf11 100644
--- a/src/quick/scenegraph/coreapi/qsgabstractrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgabstractrenderer_p.h
@@ -34,6 +34,17 @@
#ifndef QSGABSTRACTRENDERER_P_H
#define QSGABSTRACTRENDERER_P_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 "qsgabstractrenderer.h"
#include "qsgnode.h"
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index 4b0bc683c2..b1792d27a7 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -61,6 +61,8 @@ QT_BEGIN_NAMESPACE
extern QByteArray qsgShaderRewriter_insertZAttributes(const char *input, QSurfaceFormat::OpenGLContextProfile profile);
+int qt_sg_envInt(const char *name, int defaultValue);
+
namespace QSGBatchRenderer
{
@@ -198,9 +200,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 +489,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);
@@ -780,30 +787,17 @@ Renderer::Renderer(QSGRenderContext *ctx)
}
m_bufferStrategy = GL_STATIC_DRAW;
- QByteArray strategy = qgetenv("QSG_RENDERER_BUFFER_STRATEGY");
- if (strategy == "dynamic") {
- m_bufferStrategy = GL_DYNAMIC_DRAW;
- } else if (strategy == "stream") {
- m_bufferStrategy = GL_STREAM_DRAW;
- }
-
- m_batchNodeThreshold = 64;
- QByteArray alternateThreshold = qgetenv("QSG_RENDERER_BATCH_NODE_THRESHOLD");
- if (alternateThreshold.length() > 0) {
- bool ok = false;
- int threshold = alternateThreshold.toInt(&ok);
- if (ok)
- m_batchNodeThreshold = threshold;
- }
-
- m_batchVertexThreshold = 1024;
- alternateThreshold = qgetenv("QSG_RENDERER_BATCH_VERTEX_THRESHOLD");
- if (alternateThreshold.length() > 0) {
- bool ok = false;
- int threshold = alternateThreshold.toInt(&ok);
- if (ok)
- m_batchVertexThreshold = threshold;
+ if (Q_UNLIKELY(qEnvironmentVariableIsSet("QSG_RENDERER_BUFFER_STRATEGY"))) {
+ const QByteArray strategy = qgetenv("QSG_RENDERER_BUFFER_STRATEGY");
+ if (strategy == "dynamic")
+ m_bufferStrategy = GL_DYNAMIC_DRAW;
+ else if (strategy == "stream")
+ m_bufferStrategy = GL_STREAM_DRAW;
}
+
+ m_batchNodeThreshold = qt_sg_envInt("QSG_RENDERER_BATCH_NODE_THRESHOLD", 64);
+ m_batchVertexThreshold = qt_sg_envInt("QSG_RENDERER_BATCH_VERTEX_THRESHOLD", 1024);
+
if (Q_UNLIKELY(debug_build() || debug_render())) {
qDebug() << "Batch thresholds: nodes:" << m_batchNodeThreshold << " vertices:" << m_batchVertexThreshold;
qDebug() << "Using buffer strategy:" << (m_bufferStrategy == GL_STATIC_DRAW ? "static" : (m_bufferStrategy == GL_DYNAMIC_DRAW ? "dynamic" : "stream"));
@@ -816,7 +810,8 @@ Renderer::Renderer(QSGRenderContext *ctx)
m_vao->create();
}
- m_useDepthBuffer = ctx->openglContext()->format().depthBufferSize() > 0;
+ bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER");
+ m_useDepthBuffer = useDepth && ctx->openglContext()->format().depthBufferSize() > 0;
}
static void qsg_wipeBuffer(Buffer *buffer, QOpenGLFunctions *funcs)
@@ -1081,6 +1076,11 @@ void Renderer::nodeWasRemoved(Node *node)
if (e) {
e->removed = true;
m_elementsToDelete.add(e);
+
+ if (m_renderNodeElements.isEmpty()) {
+ static bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER");
+ m_useDepthBuffer = useDepth && context()->openglContext()->format().depthBufferSize() > 0;
+ }
}
}
@@ -1213,10 +1213,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 +2551,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 +2575,7 @@ void Renderer::render()
}
qDebug() << "Renderer::render()" << this << type;
+ timer.start();
}
if (m_vao)
@@ -2597,6 +2602,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 +2615,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 +2637,11 @@ void Renderer::render()
}
}
}
+ } else {
+ if (Q_UNLIKELY(debug_render())) timePrepareOpaque = timePrepareAlpha = timer.restart();
}
+
deleteRemovedElements();
if (m_rebuild != 0) {
@@ -2646,6 +2657,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 +2673,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 +2685,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 +2696,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..8cd9e7e3ff 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
@@ -34,6 +34,17 @@
#ifndef QSGBATCHRENDERER_P_H
#define QSGBATCHRENDERER_P_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 <private/qsgrenderer_p.h>
#include <private/qsgnodeupdater_p.h>
#include <private/qdatabuffer_p.h>
@@ -100,6 +111,7 @@ template <typename Type, int PageSize> class Allocator
{
public:
Allocator()
+ : m_freePage(0)
{
pages.push_back(new AllocatorPage<Type, PageSize>());
}
@@ -112,14 +124,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 +170,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 +194,7 @@ public:
}
QVector<AllocatorPage<Type, PageSize> *> pages;
+ int m_freePage;
};
@@ -500,8 +523,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:
@@ -534,8 +557,8 @@ public:
};
protected:
- void nodeChanged(QSGNode *node, QSGNode::DirtyState state);
- void render();
+ void nodeChanged(QSGNode *node, QSGNode::DirtyState state) Q_DECL_OVERRIDE;
+ void render() Q_DECL_OVERRIDE;
private:
enum ClipTypeBit
@@ -604,7 +627,7 @@ private:
void visualizeOverdraw();
void visualizeOverdraw_helper(Node *node);
void visualizeDrawGeometry(const QSGGeometry *g);
- void setCustomRenderMode(const QByteArray &mode);
+ void setCustomRenderMode(const QByteArray &mode) Q_DECL_OVERRIDE;
QSet<Node *> m_taggedRoots;
QDataBuffer<Element *> m_opaqueRenderList;
diff --git a/src/quick/scenegraph/coreapi/qsggeometry_p.h b/src/quick/scenegraph/coreapi/qsggeometry_p.h
index c52a45b25b..152fcb3427 100644
--- a/src/quick/scenegraph/coreapi/qsggeometry_p.h
+++ b/src/quick/scenegraph/coreapi/qsggeometry_p.h
@@ -34,6 +34,17 @@
#ifndef QSGGEOMETRY_P_H
#define QSGGEOMETRY_P_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 "qsggeometry.h"
QT_BEGIN_NAMESPACE
diff --git a/src/quick/scenegraph/coreapi/qsgmaterial.cpp b/src/quick/scenegraph/coreapi/qsgmaterial.cpp
index 367c0b1ee5..5fb0a9867e 100644
--- a/src/quick/scenegraph/coreapi/qsgmaterial.cpp
+++ b/src/quick/scenegraph/coreapi/qsgmaterial.cpp
@@ -64,7 +64,7 @@ const char *QSGMaterialShaderPrivate::loadShaderSource(QOpenGLShader::ShaderType
}
#ifndef QT_NO_DEBUG
-static bool qsg_leak_check = !qgetenv("QML_LEAK_CHECK").isEmpty();
+static const bool qsg_leak_check = !qEnvironmentVariableIsEmpty("QML_LEAK_CHECK");
#endif
/*!
diff --git a/src/quick/scenegraph/coreapi/qsgmaterialshader_p.h b/src/quick/scenegraph/coreapi/qsgmaterialshader_p.h
index fab6d00f84..6b31e406ca 100644
--- a/src/quick/scenegraph/coreapi/qsgmaterialshader_p.h
+++ b/src/quick/scenegraph/coreapi/qsgmaterialshader_p.h
@@ -34,6 +34,17 @@
#ifndef QSGMATERIALSHADER_P_H
#define QSGMATERIALSHADER_P_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 <private/qtquickglobal_p.h>
#include <QOpenGLShader>
diff --git a/src/quick/scenegraph/coreapi/qsgnode.cpp b/src/quick/scenegraph/coreapi/qsgnode.cpp
index 51f3976ed9..c09af7c0a3 100644
--- a/src/quick/scenegraph/coreapi/qsgnode.cpp
+++ b/src/quick/scenegraph/coreapi/qsgnode.cpp
@@ -42,7 +42,7 @@
QT_BEGIN_NAMESPACE
#ifndef QT_NO_DEBUG
-static bool qsg_leak_check = !qgetenv("QML_LEAK_CHECK").isEmpty();
+static const bool qsg_leak_check = !qEnvironmentVariableIsEmpty("QML_LEAK_CHECK");
static int qt_node_count = 0;
static void qt_print_node_count()
diff --git a/src/quick/scenegraph/coreapi/qsgnode_p.h b/src/quick/scenegraph/coreapi/qsgnode_p.h
index c455e342c8..7fbb65ef81 100644
--- a/src/quick/scenegraph/coreapi/qsgnode_p.h
+++ b/src/quick/scenegraph/coreapi/qsgnode_p.h
@@ -34,6 +34,17 @@
#ifndef QSGNODE_P_H
#define QSGNODE_P_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 <qglobal.h>
#include "qsgnode.h"
diff --git a/src/quick/scenegraph/coreapi/qsgnodeupdater.cpp b/src/quick/scenegraph/coreapi/qsgnodeupdater.cpp
index 8293c106b5..f7c9fe7fae 100644
--- a/src/quick/scenegraph/coreapi/qsgnodeupdater.cpp
+++ b/src/quick/scenegraph/coreapi/qsgnodeupdater.cpp
@@ -63,24 +63,6 @@ void QSGNodeUpdater::updateStates(QSGNode *n)
visitNode(n);
}
-/*!
- \fn void QSGNodeUpdater::setToplevelOpacity(qreal opacity)
-
- Sets the toplevel opacity that will be multiplied with the
-
- The default opacity is 1. Any other value will cause artifacts, and is
- primarily useful for debug purposes.
-
- The changing the value during an update pass will have undefined results
- */
-
-/*!
- \fn qreal QSGNodeUpdater::toplevelOpacity() const
-
- Returns the toplevel opacity for the node updater. The default
- value is 1.
- */
-
/*!
Returns true if \a node is has something that blocks it in the chain from
diff --git a/src/quick/scenegraph/coreapi/qsgnodeupdater_p.h b/src/quick/scenegraph/coreapi/qsgnodeupdater_p.h
index e578586a19..2e408d0dbe 100644
--- a/src/quick/scenegraph/coreapi/qsgnodeupdater_p.h
+++ b/src/quick/scenegraph/coreapi/qsgnodeupdater_p.h
@@ -34,6 +34,17 @@
#ifndef QSGNODEUPDATER_P_H
#define QSGNODEUPDATER_P_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 <private/qtquickglobal_p.h>
#include <QtGui/private/qdatabuffer_p.h>
diff --git a/src/quick/scenegraph/coreapi/qsgrenderer.cpp b/src/quick/scenegraph/coreapi/qsgrenderer.cpp
index a9752cb9a9..775277e588 100644
--- a/src/quick/scenegraph/coreapi/qsgrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrenderer.cpp
@@ -40,12 +40,21 @@
QT_BEGIN_NAMESPACE
-static bool qsg_sanity_check = qgetenv("QSG_SANITY_CHECK").toInt();
+static const bool qsg_sanity_check = qEnvironmentVariableIntValue("QSG_SANITY_CHECK");
static QElapsedTimer frameTimer;
static qint64 preprocessTime;
static qint64 updatePassTime;
+int qt_sg_envInt(const char *name, int defaultValue)
+{
+ if (Q_LIKELY(!qEnvironmentVariableIsSet(name)))
+ return defaultValue;
+ bool ok = false;
+ int value = qgetenv(name).toInt(&ok);
+ return ok ? value : defaultValue;
+}
+
void QSGBindable::clear(QSGAbstractRenderer::ClearMode mode) const
{
GLuint bits = 0;
diff --git a/src/quick/scenegraph/coreapi/qsgrenderer_p.h b/src/quick/scenegraph/coreapi/qsgrenderer_p.h
index 7e4d52730a..319d0a46b6 100644
--- a/src/quick/scenegraph/coreapi/qsgrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgrenderer_p.h
@@ -34,6 +34,17 @@
#ifndef QSGRENDERER_P_H
#define QSGRENDERER_P_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 "qsgabstractrenderer.h"
#include "qsgabstractrenderer_p.h"
#include "qsgnode.h"
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/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h
index 1253711a94..c7ed398d1b 100644
--- a/src/quick/scenegraph/qsgadaptationlayer_p.h
+++ b/src/quick/scenegraph/qsgadaptationlayer_p.h
@@ -34,6 +34,17 @@
#ifndef QSGADAPTATIONLAYER_P_H
#define QSGADAPTATIONLAYER_P_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 <QtQuick/qsgnode.h>
#include <QtQuick/qsgtexture.h>
#include <QtCore/qobject.h>
@@ -160,6 +171,7 @@ public:
virtual void setFillColor(const QColor &c) = 0;
virtual void setContentsScale(qreal s) = 0;
virtual void setFastFBOResizing(bool dynamic) = 0;
+ virtual void setTextureSize(const QSize &size) = 0;
virtual QImage toImage() const = 0;
virtual void update() = 0;
@@ -195,6 +207,8 @@ public:
virtual void setFormat(GLenum format) = 0;
virtual void setHasMipmaps(bool mipmap) = 0;
virtual void setDevicePixelRatio(qreal ratio) = 0;
+ virtual void setMirrorHorizontal(bool mirror) = 0;
+ virtual void setMirrorVertical(bool mirror) = 0;
Q_SLOT virtual void markDirtyTexture() = 0;
Q_SLOT virtual void invalidated() = 0;
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index 418d571ae6..dd6977e42e 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)
/*
@@ -140,8 +134,8 @@ static bool qsg_useConsistentTiming()
{
static int use = -1;
if (use < 0) {
- QByteArray fixed = qgetenv("QSG_FIXED_ANIMATION_STEP");
- use = !(fixed.isEmpty() || fixed == "no");
+ use = !qEnvironmentVariableIsEmpty("QSG_FIXED_ANIMATION_STEP") && qgetenv("QSG_FIXED_ANIMATION_STEP") != "no"
+ ? 1 : 0;
qCDebug(QSG_LOG_INFO, "Using %s", bool(use) ? "fixed animation steps" : "sg animation driver");
}
return bool(use);
@@ -303,15 +297,16 @@ QSGContext::QSGContext(QObject *parent) :
QObject(*(new QSGContextPrivate), parent)
{
Q_D(QSGContext);
- QByteArray mode = qgetenv("QSG_DISTANCEFIELD_ANTIALIASING");
- if (!mode.isEmpty())
+ if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty("QSG_DISTANCEFIELD_ANTIALIASING"))) {
+ const QByteArray mode = qgetenv("QSG_DISTANCEFIELD_ANTIALIASING");
d->distanceFieldAntialiasingDecided = true;
- if (mode == "subpixel")
- d->distanceFieldAntialiasing = QSGGlyphNode::HighQualitySubPixelAntialiasing;
- else if (mode == "subpixel-lowq")
- d->distanceFieldAntialiasing = QSGGlyphNode::LowQualitySubPixelAntialiasing;
- else if (mode == "gray")
- d->distanceFieldAntialiasing = QSGGlyphNode::GrayAntialiasing;
+ if (mode == "subpixel")
+ d->distanceFieldAntialiasing = QSGGlyphNode::HighQualitySubPixelAntialiasing;
+ else if (mode == "subpixel-lowq")
+ d->distanceFieldAntialiasing = QSGGlyphNode::LowQualitySubPixelAntialiasing;
+ else if (mode == "gray")
+ d->distanceFieldAntialiasing = QSGGlyphNode::GrayAntialiasing;
+ }
// Adds compatibility with Qt 5.3 and earlier's QSG_RENDER_TIMING
if (qEnvironmentVariableIsSet("QSG_RENDER_TIMING")) {
@@ -339,12 +334,14 @@ void QSGContext::renderContextInitialized(QSGRenderContext *renderContext)
d->mutex.lock();
if (d->antialiasingMethod == UndecidedAntialiasing) {
- QByteArray aaType = qgetenv("QSG_ANTIALIASING_METHOD");
- if (aaType == "msaa") {
- d->antialiasingMethod = MsaaAntialiasing;
- } else if (aaType == "vertex") {
- d->antialiasingMethod = VertexAntialiasing;
- } else {
+ if (Q_UNLIKELY(qEnvironmentVariableIsSet("QSG_ANTIALIASING_METHOD"))) {
+ const QByteArray aaType = qgetenv("QSG_ANTIALIASING_METHOD");
+ if (aaType == "msaa")
+ d->antialiasingMethod = MsaaAntialiasing;
+ else if (aaType == "vertex")
+ d->antialiasingMethod = VertexAntialiasing;
+ }
+ if (d->antialiasingMethod == UndecidedAntialiasing) {
if (renderContext->openglContext()->format().samples() > 0)
d->antialiasingMethod = MsaaAntialiasing;
else
@@ -572,35 +569,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 +645,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 +736,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..b1900cba76 100644
--- a/src/quick/scenegraph/qsgcontext_p.h
+++ b/src/quick/scenegraph/qsgcontext_p.h
@@ -34,6 +34,17 @@
#ifndef QSGCONTEXT_H
#define QSGCONTEXT_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 <QtCore/QObject>
#include <QtCore/qabstractanimation.h>
@@ -88,6 +99,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 +124,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/qsgcontextplugin_p.h b/src/quick/scenegraph/qsgcontextplugin_p.h
index 66f28f3ac0..eb30ed18a4 100644
--- a/src/quick/scenegraph/qsgcontextplugin_p.h
+++ b/src/quick/scenegraph/qsgcontextplugin_p.h
@@ -34,6 +34,17 @@
#ifndef QSGCONTEXTPLUGIN_H
#define QSGCONTEXTPLUGIN_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 <private/qtquickglobal_p.h>
#include <QtQuick/qquickimageprovider.h>
#include <QtCore/qplugin.h>
diff --git a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h
index cffe02330a..59fa9850bc 100644
--- a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h
+++ b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h
@@ -34,6 +34,17 @@
#ifndef QSGDEFAULTDISTANCEFIELDGLYPHCACHE_H
#define QSGDEFAULTDISTANCEFIELDGLYPHCACHE_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 "qsgadaptationlayer_p.h"
#include <QtGui/qopenglfunctions.h>
#include <qopenglshaderprogram.h>
diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
index c84e6628a5..9f8788123b 100644
--- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
+++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
@@ -73,7 +73,7 @@ static inline int qsg_device_pixel_ratio(QOpenGLContext *ctx)
else
devicePixelRatio = w->devicePixelRatio();
} else {
- devicePixelRatio = ctx->screen()->devicePixelRatio();
+ devicePixelRatio = ctx->screen() ? ctx->screen()->devicePixelRatio() : qGuiApp->devicePixelRatio();
}
return devicePixelRatio;
}
@@ -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/qsgdefaultglyphnode_p.h b/src/quick/scenegraph/qsgdefaultglyphnode_p.h
index 157c5f480c..cd178b932d 100644
--- a/src/quick/scenegraph/qsgdefaultglyphnode_p.h
+++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.h
@@ -34,6 +34,17 @@
#ifndef QSGDEFAULTGLYPHNODE_P_H
#define QSGDEFAULTGLYPHNODE_P_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 <private/qsgadaptationlayer_p.h>
#include <QtQuick/qsgnode.h>
diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p_p.h b/src/quick/scenegraph/qsgdefaultglyphnode_p_p.h
index 736b2de9ea..64d7116bbd 100644
--- a/src/quick/scenegraph/qsgdefaultglyphnode_p_p.h
+++ b/src/quick/scenegraph/qsgdefaultglyphnode_p_p.h
@@ -34,6 +34,17 @@
#ifndef QSGDEFAULTGLYPHNODE_P_P_H
#define QSGDEFAULTGLYPHNODE_P_P_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 <qcolor.h>
#include <QtGui/private/qopengltextureglyphcache_p.h>
#include <QtQuick/qsgmaterial.h>
diff --git a/src/quick/scenegraph/qsgdefaultimagenode.cpp b/src/quick/scenegraph/qsgdefaultimagenode.cpp
index db79804908..0591d0fe2f 100644
--- a/src/quick/scenegraph/qsgdefaultimagenode.cpp
+++ b/src/quick/scenegraph/qsgdefaultimagenode.cpp
@@ -284,7 +284,7 @@ void QSGDefaultImageNode::update()
void QSGDefaultImageNode::preprocess()
{
bool doDirty = false;
- QSGLayer *t = qobject_cast<QSGLayer *>(m_material.texture());
+ QSGDynamicTexture *t = qobject_cast<QSGDynamicTexture *>(m_material.texture());
if (t) {
doDirty = t->updateTexture();
updateGeometry();
diff --git a/src/quick/scenegraph/qsgdefaultimagenode_p.h b/src/quick/scenegraph/qsgdefaultimagenode_p.h
index c77321ae51..ff611e102b 100644
--- a/src/quick/scenegraph/qsgdefaultimagenode_p.h
+++ b/src/quick/scenegraph/qsgdefaultimagenode_p.h
@@ -35,6 +35,17 @@
#ifndef QSGDEFAULTIMAGENODE_P_H
#define QSGDEFAULTIMAGENODE_P_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 <private/qsgadaptationlayer_p.h>
#include <QtQuick/qsgtexturematerial.h>
diff --git a/src/quick/scenegraph/qsgdefaultlayer.cpp b/src/quick/scenegraph/qsgdefaultlayer.cpp
index cca0712ece..fa69f911dd 100644
--- a/src/quick/scenegraph/qsgdefaultlayer.cpp
+++ b/src/quick/scenegraph/qsgdefaultlayer.cpp
@@ -97,6 +97,8 @@ QSGDefaultLayer::QSGDefaultLayer(QSGRenderContext *context)
, m_multisamplingChecked(false)
, m_multisampling(false)
, m_grab(false)
+ , m_mirrorHorizontal(false)
+ , m_mirrorVertical(true)
{
}
@@ -259,6 +261,16 @@ void QSGDefaultLayer::setRecursive(bool recursive)
m_recursive = recursive;
}
+void QSGDefaultLayer::setMirrorHorizontal(bool mirror)
+{
+ m_mirrorHorizontal = mirror;
+}
+
+void QSGDefaultLayer::setMirrorVertical(bool mirror)
+{
+ m_mirrorVertical = mirror;
+}
+
void QSGDefaultLayer::markDirtyTexture()
{
m_dirtyTexture = true;
@@ -365,7 +377,10 @@ void QSGDefaultLayer::grab()
m_renderer->setDeviceRect(m_size);
m_renderer->setViewportRect(m_size);
- QRectF mirrored(m_rect.left(), m_rect.bottom(), m_rect.width(), -m_rect.height());
+ QRectF mirrored(m_mirrorHorizontal ? m_rect.right() : m_rect.left(),
+ m_mirrorVertical ? m_rect.bottom() : m_rect.top(),
+ m_mirrorHorizontal ? -m_rect.width() : m_rect.width(),
+ m_mirrorVertical ? -m_rect.height() : m_rect.height());
m_renderer->setProjectionMatrixToRect(mirrored);
m_renderer->setClearColor(Qt::transparent);
@@ -428,3 +443,11 @@ QImage QSGDefaultLayer::toImage() const
return QImage();
}
+
+QRectF QSGDefaultLayer::normalizedTextureSubRect() const
+{
+ return QRectF(m_mirrorHorizontal ? 1 : 0,
+ m_mirrorVertical ? 0 : 1,
+ m_mirrorHorizontal ? -1 : 1,
+ m_mirrorVertical ? 1 : -1);
+}
diff --git a/src/quick/scenegraph/qsgdefaultlayer_p.h b/src/quick/scenegraph/qsgdefaultlayer_p.h
index 0ba7109ef6..7fb30436d1 100644
--- a/src/quick/scenegraph/qsgdefaultlayer_p.h
+++ b/src/quick/scenegraph/qsgdefaultlayer_p.h
@@ -33,6 +33,17 @@
#ifndef QSGDEFAULTLAYER_P_H
#define QSGDEFAULTLAYER_P_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 <private/qsgadaptationlayer_p.h>
#include <private/qsgcontext_p.h>
#include <qsgsimplerectnode.h>
@@ -78,10 +89,18 @@ public:
void setDevicePixelRatio(qreal ratio) Q_DECL_OVERRIDE { m_device_pixel_ratio = ratio; }
+ bool mirrorHorizontal() const { return bool(m_mirrorHorizontal); }
+ void setMirrorHorizontal(bool mirror) Q_DECL_OVERRIDE;
+
+ bool mirrorVertical() const { return bool(m_mirrorVertical); }
+ void setMirrorVertical(bool mirror) Q_DECL_OVERRIDE;
+
void scheduleUpdate() Q_DECL_OVERRIDE;
QImage toImage() const Q_DECL_OVERRIDE;
+ QRectF normalizedTextureSubRect() const Q_DECL_OVERRIDE;
+
public Q_SLOTS:
void markDirtyTexture() Q_DECL_OVERRIDE;
void invalidated() Q_DECL_OVERRIDE;
@@ -115,6 +134,8 @@ private:
uint m_multisamplingChecked : 1;
uint m_multisampling : 1;
uint m_grab : 1;
+ uint m_mirrorHorizontal : 1;
+ uint m_mirrorVertical : 1;
};
#endif // QSGDEFAULTLAYER_P_H
diff --git a/src/quick/scenegraph/qsgdefaultrectanglenode_p.h b/src/quick/scenegraph/qsgdefaultrectanglenode_p.h
index 18e679d8b4..0987b1f9b4 100644
--- a/src/quick/scenegraph/qsgdefaultrectanglenode_p.h
+++ b/src/quick/scenegraph/qsgdefaultrectanglenode_p.h
@@ -35,6 +35,17 @@
#ifndef QSGDEFAULTRECTANGLENODE_P_H
#define QSGDEFAULTRECTANGLENODE_P_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 <private/qsgadaptationlayer_p.h>
#include <QtQuick/qsgvertexcolormaterial.h>
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/qsgdistancefieldglyphnode_p.h b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.h
index bce9379bee..ab171c4fb8 100644
--- a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.h
+++ b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.h
@@ -34,6 +34,17 @@
#ifndef QSGDISTANCEFIELDGLYPHNODE_P_H
#define QSGDISTANCEFIELDGLYPHNODE_P_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 <private/qsgadaptationlayer_p.h>
#include <QtQuick/qsgtexture.h>
diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode_p_p.h b/src/quick/scenegraph/qsgdistancefieldglyphnode_p_p.h
index 9aba26e5f0..d6538a39ed 100644
--- a/src/quick/scenegraph/qsgdistancefieldglyphnode_p_p.h
+++ b/src/quick/scenegraph/qsgdistancefieldglyphnode_p_p.h
@@ -34,6 +34,17 @@
#ifndef QSGDISTANCEFIELDGLYPHNODE_P_P_H
#define QSGDISTANCEFIELDGLYPHNODE_P_P_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 <QtQuick/qsgmaterial.h>
#include "qsgdistancefieldglyphnode_p.h"
#include "qsgadaptationlayer_p.h"
diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp
index 4d3f34c71c..68947d3a3c 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
@@ -183,13 +199,15 @@ QSGRenderLoop *QSGRenderLoop::instance()
else if (qmlForceThreadedRenderer())
loopType = ThreadedRenderLoop;
- const QByteArray loopName = qgetenv("QSG_RENDER_LOOP");
- if (loopName == QByteArrayLiteral("windows"))
- loopType = WindowsRenderLoop;
- else if (loopName == QByteArrayLiteral("basic"))
- loopType = BasicRenderLoop;
- else if (loopName == QByteArrayLiteral("threaded"))
- loopType = ThreadedRenderLoop;
+ if (Q_UNLIKELY(qEnvironmentVariableIsSet("QSG_RENDER_LOOP"))) {
+ const QByteArray loopName = qgetenv("QSG_RENDER_LOOP");
+ if (loopName == QByteArrayLiteral("windows"))
+ loopType = WindowsRenderLoop;
+ else if (loopName == QByteArrayLiteral("basic"))
+ loopType = BasicRenderLoop;
+ else if (loopName == QByteArrayLiteral("threaded"))
+ loopType = ThreadedRenderLoop;
+ }
switch (loopType) {
case ThreadedRenderLoop:
@@ -382,7 +400,8 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame);
if (data.grabOnly) {
- grabContent = qt_gl_read_framebuffer(window->size() * window->effectiveDevicePixelRatio(), false, false);
+ bool alpha = window->format().alphaBufferSize() > 0 && window->color().alpha() != 255;
+ grabContent = qt_gl_read_framebuffer(window->size() * window->effectiveDevicePixelRatio(), alpha, alpha);
data.grabOnly = false;
}
diff --git a/src/quick/scenegraph/qsgrenderloop_p.h b/src/quick/scenegraph/qsgrenderloop_p.h
index 4293015b96..1292e7ad9b 100644
--- a/src/quick/scenegraph/qsgrenderloop_p.h
+++ b/src/quick/scenegraph/qsgrenderloop_p.h
@@ -34,6 +34,17 @@
#ifndef QSGRenderLoop_P_H
#define QSGRenderLoop_P_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 <QtGui/QImage>
#include <QtGui/QSurface>
#include <private/qtquickglobal_p.h>
@@ -45,6 +56,7 @@ class QQuickWindow;
class QSGContext;
class QSGRenderContext;
class QAnimationDriver;
+class QRunnable;
class Q_QUICK_PRIVATE_EXPORT QSGRenderLoop : public QObject
{
@@ -72,6 +84,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..8d6bea9e67 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,22 @@ 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);
+ bool alpha = ce->window->format().alphaBufferSize() > 0 && ce->window->color().alpha() != 255;
+ *ce->image = qt_gl_read_framebuffer(windowSize * ce->window->effectiveDevicePixelRatio(), alpha, alpha);
}
qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- waking gui to handle result";
waitCondition.wakeOne();
@@ -417,6 +430,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 +693,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 +1020,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 +1269,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..3fef6a0a88 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop_p.h
+++ b/src/quick/scenegraph/qsgthreadedrenderloop_p.h
@@ -34,6 +34,17 @@
#ifndef QSGTHREADEDRENDERLOOP_P_H
#define QSGTHREADEDRENDERLOOP_P_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 <QtCore/QThread>
#include <QtGui/QOpenGLContext>
#include <private/qsgcontext_p.h>
@@ -71,6 +82,7 @@ public:
void releaseResources(QQuickWindow *window);
bool event(QEvent *);
+ void postJob(QQuickWindow *window, QRunnable *job);
bool interleaveIncubation() const;
diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
index 7fd9651618..04a46bf929 100644
--- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp
+++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
@@ -312,7 +312,8 @@ QImage QSGWindowsRenderLoop::grab(QQuickWindow *window)
d->syncSceneGraph();
d->renderSceneGraph(window->size());
- QImage image = qt_gl_read_framebuffer(window->size() * window->effectiveDevicePixelRatio(), false, false);
+ bool alpha = window->format().alphaBufferSize() > 0 && window->color().alpha() != 255;
+ QImage image = qt_gl_read_framebuffer(window->size() * window->effectiveDevicePixelRatio(), alpha, alpha);
return image;
}
diff --git a/src/quick/scenegraph/qsgwindowsrenderloop_p.h b/src/quick/scenegraph/qsgwindowsrenderloop_p.h
index fd2dde6f2f..654a0ebbfd 100644
--- a/src/quick/scenegraph/qsgwindowsrenderloop_p.h
+++ b/src/quick/scenegraph/qsgwindowsrenderloop_p.h
@@ -34,6 +34,17 @@
#ifndef QSGWINDOWSRENDERLOOP_P_H
#define QSGWINDOWSRENDERLOOP_P_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 <QtCore/QObject>
#include <QtCore/QElapsedTimer>
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/qsgareaallocator_p.h b/src/quick/scenegraph/util/qsgareaallocator_p.h
index d2823ce3ac..f7f753bb9c 100644
--- a/src/quick/scenegraph/util/qsgareaallocator_p.h
+++ b/src/quick/scenegraph/util/qsgareaallocator_p.h
@@ -34,6 +34,17 @@
#ifndef QSGAREAALLOCATOR_P_H
#define QSGAREAALLOCATOR_P_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 <private/qtquickglobal_p.h>
#include <QtCore/qsize.h>
diff --git a/src/quick/scenegraph/util/qsgatlastexture.cpp b/src/quick/scenegraph/util/qsgatlastexture.cpp
index b862fa6a2b..8e8e870505 100644
--- a/src/quick/scenegraph/util/qsgatlastexture.cpp
+++ b/src/quick/scenegraph/util/qsgatlastexture.cpp
@@ -54,21 +54,13 @@ QT_BEGIN_NAMESPACE
#define GL_BGRA 0x80E1
#endif
+int qt_sg_envInt(const char *name, int defaultValue);
static QElapsedTimer qsg_renderer_timer;
namespace QSGAtlasTexture
{
-static int qsg_envInt(const char *name, int defaultValue)
-{
- QByteArray content = qgetenv(name);
-
- bool ok = false;
- int value = content.toInt(&ok);
- return ok ? value : defaultValue;
-}
-
Manager::Manager()
: m_atlas(0)
{
@@ -79,8 +71,8 @@ Manager::Manager()
int max;
gl->functions()->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max);
- int w = qMin(max, qsg_envInt("QSG_ATLAS_WIDTH", qMax(512U, qNextPowerOfTwo(surfaceSize.width() - 1))));
- int h = qMin(max, qsg_envInt("QSG_ATLAS_HEIGHT", qMax(512U, qNextPowerOfTwo(surfaceSize.height() - 1))));
+ int w = qMin(max, qt_sg_envInt("QSG_ATLAS_WIDTH", qMax(512U, qNextPowerOfTwo(surfaceSize.width() - 1))));
+ int h = qMin(max, qt_sg_envInt("QSG_ATLAS_HEIGHT", qMax(512U, qNextPowerOfTwo(surfaceSize.height() - 1))));
if (surface->surfaceClass() == QSurface::Window) {
QWindow *window = static_cast<QWindow *>(surface);
@@ -91,7 +83,7 @@ Manager::Manager()
}
}
- m_atlas_size_limit = qsg_envInt("QSG_ATLAS_SIZE_LIMIT", qMax(w, h) / 2);
+ m_atlas_size_limit = qt_sg_envInt("QSG_ATLAS_SIZE_LIMIT", qMax(w, h) / 2);
m_atlas_size = QSize(w, h);
qCDebug(QSG_LOG_INFO, "texture atlas dimensions: %dx%d", w, h);
@@ -112,13 +104,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..e77e0fa104 100644
--- a/src/quick/scenegraph/util/qsgatlastexture_p.h
+++ b/src/quick/scenegraph/util/qsgatlastexture_p.h
@@ -34,6 +34,17 @@
#ifndef QSGATLASTEXTURE_P_H
#define QSGATLASTEXTURE_P_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 <QtCore/QSize>
#include <QtGui/qopengl.h>
@@ -58,7 +69,7 @@ public:
Manager();
~Manager();
- QSGTexture *create(const QImage &image);
+ QSGTexture *create(const QImage &image, bool hasAlphaChannel);
void invalidate();
private:
@@ -114,6 +125,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/qsgdefaultpainternode.cpp b/src/quick/scenegraph/util/qsgdefaultpainternode.cpp
index be8deb2aa3..38bcc7a3f3 100644
--- a/src/quick/scenegraph/util/qsgdefaultpainternode.cpp
+++ b/src/quick/scenegraph/util/qsgdefaultpainternode.cpp
@@ -76,6 +76,8 @@ QSGDefaultPainterNode::QSGDefaultPainterNode(QQuickPaintedItem *item)
, m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)
, m_texture(0)
, m_gl_device(0)
+ , m_fillColor(Qt::transparent)
+ , m_contentsScale(1.0)
, m_dirtyContents(false)
, m_opaquePainting(false)
, m_linear_filtering(false)
@@ -84,8 +86,6 @@ QSGDefaultPainterNode::QSGDefaultPainterNode(QQuickPaintedItem *item)
, m_extensionsChecked(false)
, m_multisamplingSupported(false)
, m_fastFBOResizing(false)
- , m_fillColor(Qt::transparent)
- , m_contentsScale(1.0)
, m_dirtyGeometry(false)
, m_dirtyRenderTarget(false)
, m_dirtyTexture(false)
@@ -136,18 +136,35 @@ void QSGDefaultPainterNode::paint()
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
}
- painter.scale(m_contentsScale, m_contentsScale);
-
- QRect sclip(qFloor(dirtyRect.x()/m_contentsScale),
- qFloor(dirtyRect.y()/m_contentsScale),
- qCeil(dirtyRect.width()/m_contentsScale+dirtyRect.x()/m_contentsScale-qFloor(dirtyRect.x()/m_contentsScale)),
- qCeil(dirtyRect.height()/m_contentsScale+dirtyRect.y()/m_contentsScale-qFloor(dirtyRect.y()/m_contentsScale)));
+ QRect clipRect;
+ QRect dirtyTextureRect;
+
+ if (m_contentsScale == 1) {
+ qreal scaleX = m_textureSize.width() / (qreal) m_size.width();
+ qreal scaleY = m_textureSize.height() / (qreal) m_size.height();
+ painter.scale(scaleX, scaleY);
+ clipRect = dirtyRect;
+ dirtyTextureRect = QRectF(dirtyRect.x() * scaleX,
+ dirtyRect.y() * scaleY,
+ dirtyRect.width() * scaleX,
+ dirtyRect.height() * scaleY).toAlignedRect();
+ } else {
+ painter.scale(m_contentsScale, m_contentsScale);
+ QRect sclip(qFloor(dirtyRect.x()/m_contentsScale),
+ qFloor(dirtyRect.y()/m_contentsScale),
+ qCeil(dirtyRect.width()/m_contentsScale+dirtyRect.x()/m_contentsScale-qFloor(dirtyRect.x()/m_contentsScale)),
+ qCeil(dirtyRect.height()/m_contentsScale+dirtyRect.y()/m_contentsScale-qFloor(dirtyRect.y()/m_contentsScale)));
+ clipRect = sclip;
+ dirtyTextureRect = dirtyRect;
+ }
- if (!m_dirtyRect.isNull())
- painter.setClipRect(sclip);
+ // only clip if we were originally updating only a subrect
+ if (!m_dirtyRect.isNull()) {
+ painter.setClipRect(clipRect);
+ }
painter.setCompositionMode(QPainter::CompositionMode_Source);
- painter.fillRect(sclip, m_fillColor);
+ painter.fillRect(clipRect, m_fillColor);
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
m_item->paint(&painter);
@@ -155,9 +172,9 @@ void QSGDefaultPainterNode::paint()
if (m_actualRenderTarget == QQuickPaintedItem::Image) {
m_texture->setImage(m_image);
- m_texture->setDirtyRect(dirtyRect);
+ m_texture->setDirtyRect(dirtyTextureRect);
} else if (m_multisampledFbo) {
- QOpenGLFramebufferObject::blitFramebuffer(m_fbo, dirtyRect, m_multisampledFbo, dirtyRect);
+ QOpenGLFramebufferObject::blitFramebuffer(m_fbo, dirtyTextureRect, m_multisampledFbo, dirtyTextureRect);
}
if (m_multisampledFbo)
@@ -276,7 +293,7 @@ void QSGDefaultPainterNode::updateRenderTarget()
if (!m_image.isNull() && !m_dirtyGeometry)
return;
- m_image = QImage(m_size, QImage::Format_ARGB32_Premultiplied);
+ m_image = QImage(m_textureSize, QImage::Format_ARGB32_Premultiplied);
m_image.fill(Qt::transparent);
}
@@ -302,12 +319,12 @@ void QSGDefaultPainterNode::updateFBOSize()
int fboWidth;
int fboHeight;
if (m_fastFBOResizing) {
- fboWidth = qMax(QT_MINIMUM_DYNAMIC_FBO_SIZE, qNextPowerOfTwo(m_size.width() - 1));
- fboHeight = qMax(QT_MINIMUM_DYNAMIC_FBO_SIZE, qNextPowerOfTwo(m_size.height() - 1));
+ fboWidth = qMax(QT_MINIMUM_DYNAMIC_FBO_SIZE, qNextPowerOfTwo(m_textureSize.width() - 1));
+ fboHeight = qMax(QT_MINIMUM_DYNAMIC_FBO_SIZE, qNextPowerOfTwo(m_textureSize.height() - 1));
} else {
QSize minimumFBOSize = m_context->sceneGraphContext()->minimumFBOSize();
- fboWidth = qMax(minimumFBOSize.width(), m_size.width());
- fboHeight = qMax(minimumFBOSize.height(), m_size.height());
+ fboWidth = qMax(minimumFBOSize.width(), m_textureSize.width());
+ fboHeight = qMax(minimumFBOSize.height(), m_textureSize.height());
}
m_fboSize = QSize(fboWidth, fboHeight);
@@ -331,6 +348,15 @@ void QSGDefaultPainterNode::setSize(const QSize &size)
return;
m_size = size;
+ m_dirtyGeometry = true;
+}
+
+void QSGDefaultPainterNode::setTextureSize(const QSize &size)
+{
+ if (size == m_textureSize)
+ return;
+
+ m_textureSize = size;
updateFBOSize();
if (m_fbo)
diff --git a/src/quick/scenegraph/util/qsgdefaultpainternode_p.h b/src/quick/scenegraph/util/qsgdefaultpainternode_p.h
index 62daa54432..6b6f485915 100644
--- a/src/quick/scenegraph/util/qsgdefaultpainternode_p.h
+++ b/src/quick/scenegraph/util/qsgdefaultpainternode_p.h
@@ -34,6 +34,17 @@
#ifndef QSGDEFAULTPAINTERNODE_P_H
#define QSGDEFAULTPAINTERNODE_P_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 <private/qsgadaptationlayer_p.h>
#include "qsgtexturematerial.h"
#include "qsgtexture_p.h"
@@ -94,6 +105,9 @@ public:
void setFastFBOResizing(bool dynamic);
bool fastFBOResizing() const { return m_fastFBOResizing; }
+ void setTextureSize(const QSize &textureSize);
+ QSize textureSize() const { return m_textureSize; }
+
QImage toImage() const;
void update();
@@ -126,21 +140,25 @@ private:
QSize m_size;
QSize m_fboSize;
- bool m_dirtyContents;
+ QSize m_textureSize;
QRect m_dirtyRect;
- bool m_opaquePainting;
- bool m_linear_filtering;
- bool m_mipmapping;
- bool m_smoothPainting;
- bool m_extensionsChecked;
- bool m_multisamplingSupported;
- bool m_fastFBOResizing;
QColor m_fillColor;
+#if QT_VERSION >= 0x060000
+#warning "Remove m_contentsScale and assume 1 everywhere"
+#endif
qreal m_contentsScale;
- bool m_dirtyGeometry;
- bool m_dirtyRenderTarget;
- bool m_dirtyTexture;
+ bool m_dirtyContents : 1;
+ bool m_opaquePainting : 1;
+ bool m_linear_filtering : 1;
+ bool m_mipmapping : 1;
+ bool m_smoothPainting : 1;
+ bool m_extensionsChecked : 1;
+ bool m_multisamplingSupported : 1;
+ bool m_fastFBOResizing : 1;
+ bool m_dirtyGeometry : 1;
+ bool m_dirtyRenderTarget : 1;
+ bool m_dirtyTexture : 1;
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgdepthstencilbuffer_p.h b/src/quick/scenegraph/util/qsgdepthstencilbuffer_p.h
index e9d07ae605..c6d0de4435 100644
--- a/src/quick/scenegraph/util/qsgdepthstencilbuffer_p.h
+++ b/src/quick/scenegraph/util/qsgdepthstencilbuffer_p.h
@@ -34,6 +34,17 @@
#ifndef QSGDEPTHSTENCILBUFFER_P_H
#define QSGDEPTHSTENCILBUFFER_P_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 <QtCore/qsize.h>
#include <QtGui/private/qopenglcontext_p.h>
#include <QtGui/private/qopenglextensions_p.h>
diff --git a/src/quick/scenegraph/util/qsgdistancefieldutil.cpp b/src/quick/scenegraph/util/qsgdistancefieldutil.cpp
index 8e02681703..96b606aa3c 100644
--- a/src/quick/scenegraph/util/qsgdistancefieldutil.cpp
+++ b/src/quick/scenegraph/util/qsgdistancefieldutil.cpp
@@ -39,18 +39,27 @@
QT_BEGIN_NAMESPACE
+static float qt_sg_envFloat(const char *name, float defaultValue)
+{
+ if (Q_LIKELY(!qEnvironmentVariableIsSet(name)))
+ return defaultValue;
+ bool ok = false;
+ const float value = qgetenv(name).toFloat(&ok);
+ return ok ? value : defaultValue;
+}
+
static float defaultThresholdFunc(float glyphScale)
{
- static float base = qgetenv("QT_DF_BASE").isEmpty() ? 0.5f : qgetenv("QT_DF_BASE").toFloat();
- static float baseDev = qgetenv("QT_DF_BASEDEVIATION").isEmpty() ? 0.065f : qgetenv("QT_DF_BASEDEVIATION").toFloat();
- static float devScaleMin = qgetenv("QT_DF_SCALEFORMAXDEV").isEmpty() ? 0.15f : qgetenv("QT_DF_SCALEFORMAXDEV").toFloat();
- static float devScaleMax = qgetenv("QT_DF_SCALEFORNODEV").isEmpty() ? 0.3f : qgetenv("QT_DF_SCALEFORNODEV").toFloat();
+ static const float base = qt_sg_envFloat("QT_DF_BASE", 0.5f);
+ static const float baseDev = qt_sg_envFloat("QT_DF_BASEDEVIATION", 0.065f);
+ static const float devScaleMin = qt_sg_envFloat("QT_DF_SCALEFORMAXDEV", 0.15f);
+ static const float devScaleMax = qt_sg_envFloat("QT_DF_SCALEFORNODEV", 0.3f);
return base - ((qBound(devScaleMin, glyphScale, devScaleMax) - devScaleMin) / (devScaleMax - devScaleMin) * -baseDev + baseDev);
}
static float defaultAntialiasingSpreadFunc(float glyphScale)
{
- static float range = qgetenv("QT_DF_RANGE").isEmpty() ? 0.06f : qgetenv("QT_DF_RANGE").toFloat();
+ static const float range = qt_sg_envFloat("QT_DF_RANGE", 0.06f);
return range / glyphScale;
}
diff --git a/src/quick/scenegraph/util/qsgdistancefieldutil_p.h b/src/quick/scenegraph/util/qsgdistancefieldutil_p.h
index 7ed4b44a6d..3ee29230d5 100644
--- a/src/quick/scenegraph/util/qsgdistancefieldutil_p.h
+++ b/src/quick/scenegraph/util/qsgdistancefieldutil_p.h
@@ -34,6 +34,17 @@
#ifndef QSGDISTANCEFIELDUTIL_H
#define QSGDISTANCEFIELDUTIL_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 <qrawfont.h>
#include <private/qfontengine_p.h>
#include <private/qsgadaptationlayer_p.h>
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/scenegraph/util/qsgengine_p.h b/src/quick/scenegraph/util/qsgengine_p.h
index 770c4a536c..9bae09ea71 100644
--- a/src/quick/scenegraph/util/qsgengine_p.h
+++ b/src/quick/scenegraph/util/qsgengine_p.h
@@ -34,6 +34,17 @@
#ifndef QSGENGINE_P_H
#define QSGENGINE_P_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 "qsgengine.h"
#include <private/qobject_p.h>
diff --git a/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp b/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp
index 93a9c98ffb..0d6375de1e 100644
--- a/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp
+++ b/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp
@@ -373,7 +373,7 @@ QString QSGShaderSourceBuilder::resolveShaderPath(const QString &path) const
if (contextProfile() != QSurfaceFormat::CoreProfile) {
return path;
} else {
- int idx = path.lastIndexOf(QStringLiteral("."));
+ int idx = path.lastIndexOf(QLatin1Char('.'));
QString resolvedPath;
if (idx != -1)
resolvedPath = path.left(idx)
diff --git a/src/quick/scenegraph/util/qsgshadersourcebuilder_p.h b/src/quick/scenegraph/util/qsgshadersourcebuilder_p.h
index a270acb6ab..180ced7990 100644
--- a/src/quick/scenegraph/util/qsgshadersourcebuilder_p.h
+++ b/src/quick/scenegraph/util/qsgshadersourcebuilder_p.h
@@ -34,6 +34,17 @@
#ifndef QSGSHADERSOURCEBUILDER_P_H
#define QSGSHADERSOURCEBUILDER_P_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 <private/qtquickglobal_p.h>
#include <QtGui/qsurfaceformat.h>
diff --git a/src/quick/scenegraph/util/qsgtexture.cpp b/src/quick/scenegraph/util/qsgtexture.cpp
index c89ad7a608..df9e569ca3 100644
--- a/src/quick/scenegraph/util/qsgtexture.cpp
+++ b/src/quick/scenegraph/util/qsgtexture.cpp
@@ -65,7 +65,7 @@
static QElapsedTimer qsg_renderer_timer;
#ifndef QT_NO_DEBUG
-static bool qsg_leak_check = !qgetenv("QML_LEAK_CHECK").isEmpty();
+static const bool qsg_leak_check = !qEnvironmentVariableIsEmpty("QML_LEAK_CHECK");
#endif
diff --git a/src/quick/scenegraph/util/qsgtexture_p.h b/src/quick/scenegraph/util/qsgtexture_p.h
index c4edee6d29..221b85c2f7 100644
--- a/src/quick/scenegraph/util/qsgtexture_p.h
+++ b/src/quick/scenegraph/util/qsgtexture_p.h
@@ -34,6 +34,17 @@
#ifndef QSGTEXTURE_P_H
#define QSGTEXTURE_P_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 <QtQuick/qtquickglobal.h>
#include <private/qobject_p.h>
diff --git a/src/quick/scenegraph/util/qsgtexturematerial_p.h b/src/quick/scenegraph/util/qsgtexturematerial_p.h
index 7146ea95ec..5abd25977c 100644
--- a/src/quick/scenegraph/util/qsgtexturematerial_p.h
+++ b/src/quick/scenegraph/util/qsgtexturematerial_p.h
@@ -34,6 +34,17 @@
#ifndef TEXTUREMATERIAL_P_H
#define TEXTUREMATERIAL_P_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 "qsgtexturematerial.h"
#include <private/qtquickglobal_p.h>
diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp
index ec3abf7090..1d0dbf64b3 100644
--- a/src/quick/util/qquickanimation.cpp
+++ b/src/quick/util/qquickanimation.cpp
@@ -2179,7 +2179,7 @@ void QQuickPropertyAnimation::setTo(const QVariant &t)
\li \inlineimage qeasingcurve-incubic.png
\row
\li \c Easing.OutCubic
- \li Easing curve for a cubic (t^3) function: decelerating from zero velocity.
+ \li Easing curve for a cubic (t^3) function: decelerating to zero velocity.
\li \inlineimage qeasingcurve-outcubic.png
\row
\li \c Easing.InOutCubic
@@ -2195,7 +2195,7 @@ void QQuickPropertyAnimation::setTo(const QVariant &t)
\li \inlineimage qeasingcurve-inquart.png
\row
\li \c Easing.OutQuart
- \li Easing curve for a quartic (t^4) function: decelerating from zero velocity.
+ \li Easing curve for a quartic (t^4) function: decelerating to zero velocity.
\li \inlineimage qeasingcurve-outquart.png
\row
\li \c Easing.InOutQuart
@@ -2211,7 +2211,7 @@ void QQuickPropertyAnimation::setTo(const QVariant &t)
\li \inlineimage qeasingcurve-inquint.png
\row
\li \c Easing.OutQuint
- \li Easing curve for a quintic (t^5) function: decelerating from zero velocity.
+ \li Easing curve for a quintic (t^5) function: decelerating to zero velocity.
\li \inlineimage qeasingcurve-outquint.png
\row
\li \c Easing.InOutQuint
@@ -2227,7 +2227,7 @@ void QQuickPropertyAnimation::setTo(const QVariant &t)
\li \inlineimage qeasingcurve-insine.png
\row
\li \c Easing.OutSine
- \li Easing curve for a sinusoidal (sin(t)) function: decelerating from zero velocity.
+ \li Easing curve for a sinusoidal (sin(t)) function: decelerating to zero velocity.
\li \inlineimage qeasingcurve-outsine.png
\row
\li \c Easing.InOutSine
@@ -2243,7 +2243,7 @@ void QQuickPropertyAnimation::setTo(const QVariant &t)
\li \inlineimage qeasingcurve-inexpo.png
\row
\li \c Easing.OutExpo
- \li Easing curve for an exponential (2^t) function: decelerating from zero velocity.
+ \li Easing curve for an exponential (2^t) function: decelerating to zero velocity.
\li \inlineimage qeasingcurve-outexpo.png
\row
\li \c Easing.InOutExpo
@@ -2259,7 +2259,7 @@ void QQuickPropertyAnimation::setTo(const QVariant &t)
\li \inlineimage qeasingcurve-incirc.png
\row
\li \c Easing.OutCirc
- \li Easing curve for a circular (sqrt(1-t^2)) function: decelerating from zero velocity.
+ \li Easing curve for a circular (sqrt(1-t^2)) function: decelerating to zero velocity.
\li \inlineimage qeasingcurve-outcirc.png
\row
\li \c Easing.InOutCirc
@@ -2276,7 +2276,7 @@ void QQuickPropertyAnimation::setTo(const QVariant &t)
\li \inlineimage qeasingcurve-inelastic.png
\row
\li \c Easing.OutElastic
- \li Easing curve for an elastic (exponentially decaying sine wave) function: decelerating from zero velocity.
+ \li Easing curve for an elastic (exponentially decaying sine wave) function: decelerating to zero velocity.
\br The peak amplitude can be set with the \e amplitude parameter, and the period of decay by the \e period parameter.
\li \inlineimage qeasingcurve-outelastic.png
\row
@@ -2309,7 +2309,7 @@ void QQuickPropertyAnimation::setTo(const QVariant &t)
\li \inlineimage qeasingcurve-inbounce.png
\row
\li \c Easing.OutBounce
- \li Easing curve for a bounce (exponentially decaying parabolic bounce) function: decelerating from zero velocity.
+ \li Easing curve for a bounce (exponentially decaying parabolic bounce) function: decelerating to zero velocity.
\li \inlineimage qeasingcurve-outbounce.png
\row
\li \c Easing.InOutBounce
diff --git a/src/quick/util/qquickanimation_p.h b/src/quick/util/qquickanimation_p.h
index 0f6224a831..4d3532ce84 100644
--- a/src/quick/util/qquickanimation_p.h
+++ b/src/quick/util/qquickanimation_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKANIMATION_H
#define QQUICKANIMATION_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 "qquickstate_p.h"
#include <QtGui/qvector3d.h>
@@ -57,7 +68,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 +85,7 @@ public:
virtual ~QQuickAbstractAnimation();
enum Loops { Infinite = -2 };
+ Q_ENUM(Loops)
bool isRunning() const;
void setRunning(bool);
@@ -367,7 +378,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 +394,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/qquickanimationcontroller_p.h b/src/quick/util/qquickanimationcontroller_p.h
index 171090b6a7..efd1dbafc4 100644
--- a/src/quick/util/qquickanimationcontroller_p.h
+++ b/src/quick/util/qquickanimationcontroller_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKANIMATIONCONTROLLER_H
#define QQUICKANIMATIONCONTROLLER_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 <qqml.h>
#include "qquickanimation_p.h"
diff --git a/src/quick/util/qquickanimator.cpp b/src/quick/util/qquickanimator.cpp
index 61fb7481d9..8a5cad4011 100644
--- a/src/quick/util/qquickanimator.cpp
+++ b/src/quick/util/qquickanimator.cpp
@@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE
directly on Qt Quick's scene graph, rather than the QML objects and their
properties like regular Animation types do. This has the benefit that
Animator based animations can animate on the \l
- {Threaded Render Loop}{scene graph's rendering thread} even when the
+ {Threaded Render Loop ("threaded")}{scene graph's rendering thread} even when the
UI thread is blocked.
The value of the QML property will be updated after the animation has
diff --git a/src/quick/util/qquickanimator_p.h b/src/quick/util/qquickanimator_p.h
index 4d3a8e9e4f..1ba0367839 100644
--- a/src/quick/util/qquickanimator_p.h
+++ b/src/quick/util/qquickanimator_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKANIMATOR_P_H
#define QQUICKANIMATOR_P_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 "qquickanimation_p.h"
QT_BEGIN_NAMESPACE
@@ -136,10 +147,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/qquickanimator_p_p.h b/src/quick/util/qquickanimator_p_p.h
index ad16b1c361..f5f0295f74 100644
--- a/src/quick/util/qquickanimator_p_p.h
+++ b/src/quick/util/qquickanimator_p_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKANIMATOR_P_P_H
#define QQUICKANIMATOR_P_P_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 "qquickanimator_p.h"
#include "qquickanimation_p_p.h"
#include <QtQuick/qquickitem.h>
diff --git a/src/quick/util/qquickanimatorcontroller.cpp b/src/quick/util/qquickanimatorcontroller.cpp
index c875e18978..cfb6037d14 100644
--- a/src/quick/util/qquickanimatorcontroller.cpp
+++ b/src/quick/util/qquickanimatorcontroller.cpp
@@ -217,8 +217,8 @@ void QQuickAnimatorController::beforeNodeSync()
void QQuickAnimatorController::afterNodeSync()
{
foreach (QQuickAnimatorJob *job, m_activeLeafAnimations) {
- if (job->isUniform() && job->target())
- static_cast<QQuickUniformAnimatorJob *>(job)->afterNodeSync();
+ if (job->target())
+ job->afterNodeSync();
}
}
diff --git a/src/quick/util/qquickanimatorcontroller_p.h b/src/quick/util/qquickanimatorcontroller_p.h
index 4de485c37c..5dd9b09e0b 100644
--- a/src/quick/util/qquickanimatorcontroller_p.h
+++ b/src/quick/util/qquickanimatorcontroller_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKANIMATORCONTROLLER_P_H
#define QQUICKANIMATORCONTROLLER_P_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 "qquickanimatorjob_p.h"
#include <QtQuick/qsgnode.h>
#include <QtQuick/qquickitem.h>
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..82c9da1d2e 100644
--- a/src/quick/util/qquickanimatorjob_p.h
+++ b/src/quick/util/qquickanimatorjob_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKANIMATORJOB_P_H
#define QQUICKANIMATORJOB_P_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 <private/qabstractanimationjob_p.h>
#include <private/qquickanimator_p.h>
#include <private/qtquickglobal_p.h>
@@ -125,6 +136,7 @@ public:
virtual void initialize(QQuickAnimatorController *controller);
virtual void writeBack() = 0;
virtual void nodeWasDestroyed() = 0;
+ virtual void afterNodeSync() { }
bool isTransform() const { return m_isTransform; }
bool isUniform() const { return m_isUniform; }
@@ -151,7 +163,6 @@ protected:
int m_duration;
- uint m_feedback : 1;
uint m_isTransform : 1;
uint m_isUniform : 1;
uint m_hasBeenRunning : 1;
@@ -212,22 +223,22 @@ protected:
class Q_QUICK_PRIVATE_EXPORT QQuickScaleAnimatorJob : public QQuickTransformAnimatorJob
{
public:
- void updateCurrentTime(int time);
- void writeBack();
+ void updateCurrentTime(int time) Q_DECL_OVERRIDE;
+ void writeBack() Q_DECL_OVERRIDE;
};
class Q_QUICK_PRIVATE_EXPORT QQuickXAnimatorJob : public QQuickTransformAnimatorJob
{
public:
- void updateCurrentTime(int time);
- void writeBack();
+ void updateCurrentTime(int time) Q_DECL_OVERRIDE;
+ void writeBack() Q_DECL_OVERRIDE;
};
class Q_QUICK_PRIVATE_EXPORT QQuickYAnimatorJob : public QQuickTransformAnimatorJob
{
public:
- void updateCurrentTime(int time);
- void writeBack();
+ void updateCurrentTime(int time) Q_DECL_OVERRIDE;
+ void writeBack() Q_DECL_OVERRIDE;
};
class Q_QUICK_PRIVATE_EXPORT QQuickRotationAnimatorJob : public QQuickTransformAnimatorJob
@@ -235,8 +246,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickRotationAnimatorJob : public QQuickTransformA
public:
QQuickRotationAnimatorJob();
- void updateCurrentTime(int time);
- void writeBack();
+ void updateCurrentTime(int time) Q_DECL_OVERRIDE;
+ void writeBack() Q_DECL_OVERRIDE;
void setDirection(QQuickRotationAnimator::RotationDirection direction) { m_direction = direction; }
QQuickRotationAnimator::RotationDirection direction() const { return m_direction; }
@@ -250,10 +261,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickOpacityAnimatorJob : public QQuickAnimatorJob
public:
QQuickOpacityAnimatorJob();
- void initialize(QQuickAnimatorController *controller);
- void updateCurrentTime(int time);
- void writeBack();
- void nodeWasDestroyed();
+ void initialize(QQuickAnimatorController *controller) Q_DECL_OVERRIDE;
+ void updateCurrentTime(int time) Q_DECL_OVERRIDE;
+ void writeBack() Q_DECL_OVERRIDE;
+ void nodeWasDestroyed() Q_DECL_OVERRIDE;
private:
QSGOpacityNode *m_opacityNode;
@@ -264,16 +275,16 @@ class Q_QUICK_PRIVATE_EXPORT QQuickUniformAnimatorJob : public QQuickAnimatorJob
public:
QQuickUniformAnimatorJob();
- void setTarget(QQuickItem *target);
+ void setTarget(QQuickItem *target) Q_DECL_OVERRIDE;
void setUniform(const QByteArray &uniform) { m_uniform = uniform; }
QByteArray uniform() const { return m_uniform; }
- void afterNodeSync();
+ void afterNodeSync() Q_DECL_OVERRIDE;
- void updateCurrentTime(int time);
- void writeBack();
- void nodeWasDestroyed();
+ void updateCurrentTime(int time) Q_DECL_OVERRIDE;
+ void writeBack() Q_DECL_OVERRIDE;
+ void nodeWasDestroyed() Q_DECL_OVERRIDE;
private:
QByteArray m_uniform;
diff --git a/src/quick/util/qquickapplication_p.h b/src/quick/util/qquickapplication_p.h
index c22d8cfe6b..082f68101a 100644
--- a/src/quick/util/qquickapplication_p.h
+++ b/src/quick/util/qquickapplication_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKAPPLICATION_P_H
#define QQUICKAPPLICATION_P_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 <QtCore/QObject>
#include <qqml.h>
#include <QtQml/private/qqmlglobal_p.h>
diff --git a/src/quick/util/qquickbehavior_p.h b/src/quick/util/qquickbehavior_p.h
index d566ca8ba1..a8bff1511b 100644
--- a/src/quick/util/qquickbehavior_p.h
+++ b/src/quick/util/qquickbehavior_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKBEHAVIOR_H
#define QQUICKBEHAVIOR_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 <private/qtquickglobal_p.h>
#include <private/qqmlpropertyvalueinterceptor_p.h>
diff --git a/src/quick/util/qquickfontloader.cpp b/src/quick/util/qquickfontloader.cpp
index 67df47fb37..496acaa8e3 100644
--- a/src/quick/util/qquickfontloader.cpp
+++ b/src/quick/util/qquickfontloader.cpp
@@ -47,6 +47,8 @@
#include <qqmlinfo.h>
#include <qqmlfile.h>
+#include <QtCore/QCoreApplication>
+
QT_BEGIN_NAMESPACE
#define FONTLOADER_MAXIMUM_REDIRECT_RECURSION 16
@@ -132,10 +134,50 @@ public:
QUrl url;
QString name;
QQuickFontLoader::Status status;
- static QHash<QUrl, QQuickFontObject*> fonts;
};
-QHash<QUrl, QQuickFontObject*> QQuickFontLoaderPrivate::fonts;
+static void q_QFontLoaderFontsStaticReset();
+static void q_QFontLoaderFontsAddReset()
+{
+ qAddPostRoutine(q_QFontLoaderFontsStaticReset);
+}
+class QFontLoaderFonts
+{
+public:
+ QFontLoaderFonts()
+ {
+ qAddPostRoutine(q_QFontLoaderFontsStaticReset);
+ qAddPreRoutine(q_QFontLoaderFontsAddReset);
+ }
+
+ ~QFontLoaderFonts()
+ {
+ qRemovePostRoutine(q_QFontLoaderFontsStaticReset);
+ reset();
+ }
+
+
+ void reset()
+ {
+ QVector<QQuickFontObject *> deleted;
+ QHash<QUrl, QQuickFontObject*>::iterator it;
+ for (it = map.begin(); it != map.end(); ++it) {
+ if (!deleted.contains(it.value())) {
+ deleted.append(it.value());
+ delete it.value();
+ }
+ }
+ map.clear();
+ }
+
+ QHash<QUrl, QQuickFontObject *> map;
+};
+Q_GLOBAL_STATIC(QFontLoaderFonts, fontLoaderFonts);
+
+static void q_QFontLoaderFontsStaticReset()
+{
+ fontLoaderFonts()->reset();
+}
/*!
\qmltype FontLoader
@@ -193,29 +235,29 @@ void QQuickFontLoader::setSource(const QUrl &url)
QString localFile = QQmlFile::urlToLocalFileOrQrc(d->url);
if (!localFile.isEmpty()) {
- if (!d->fonts.contains(d->url)) {
+ if (!fontLoaderFonts()->map.contains(d->url)) {
int id = QFontDatabase::addApplicationFont(localFile);
if (id != -1) {
updateFontInfo(QFontDatabase::applicationFontFamilies(id).at(0), Ready);
QQuickFontObject *fo = new QQuickFontObject(id);
- d->fonts[d->url] = fo;
+ fontLoaderFonts()->map[d->url] = fo;
} else {
updateFontInfo(QString(), Error);
}
} else {
- updateFontInfo(QFontDatabase::applicationFontFamilies(d->fonts[d->url]->id).at(0), Ready);
+ updateFontInfo(QFontDatabase::applicationFontFamilies(fontLoaderFonts()->map[d->url]->id).at(0), Ready);
}
} else {
- if (!d->fonts.contains(d->url)) {
+ if (!fontLoaderFonts()->map.contains(d->url)) {
QQuickFontObject *fo = new QQuickFontObject;
- d->fonts[d->url] = fo;
+ fontLoaderFonts()->map[d->url] = fo;
fo->download(d->url, qmlEngine(this)->networkAccessManager());
d->status = Loading;
emit statusChanged();
QObject::connect(fo, SIGNAL(fontDownloaded(QString,QQuickFontLoader::Status)),
this, SLOT(updateFontInfo(QString,QQuickFontLoader::Status)));
} else {
- QQuickFontObject *fo = d->fonts[d->url];
+ QQuickFontObject *fo = fontLoaderFonts()->map[d->url];
if (fo->id == -1) {
d->status = Loading;
emit statusChanged();
diff --git a/src/quick/util/qquickfontloader_p.h b/src/quick/util/qquickfontloader_p.h
index b6ca0b3c94..1e2a70be7d 100644
--- a/src/quick/util/qquickfontloader_p.h
+++ b/src/quick/util/qquickfontloader_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKFONTLOADER_H
#define QQUICKFONTLOADER_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 <qqml.h>
#include <QtCore/qobject.h>
@@ -46,7 +57,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 +64,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/qquickfontmetrics.cpp b/src/quick/util/qquickfontmetrics.cpp
index a87ec7d60a..0e3556be86 100644
--- a/src/quick/util/qquickfontmetrics.cpp
+++ b/src/quick/util/qquickfontmetrics.cpp
@@ -319,8 +319,7 @@ QRectF QQuickFontMetrics::tightBoundingRect(const QString &text) const
}
/*!
- \qmlmethod string QtQuick::FontMetrics::elidedText(string text, enum mode,
- qreal width, int flags)
+ \qmlmethod string QtQuick::FontMetrics::elidedText(string text, enumeration mode, real width, int flags)
This method returns a returns an elided version of the string (i.e., a
string with "..." in it) if the string \a text is wider than \a width.
diff --git a/src/quick/util/qquickfontmetrics_p.h b/src/quick/util/qquickfontmetrics_p.h
index 88880a2be8..37aaef7345 100644
--- a/src/quick/util/qquickfontmetrics_p.h
+++ b/src/quick/util/qquickfontmetrics_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKFONTMETRICS_H
#define QQUICKFONTMETRICS_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 <qqml.h>
#include <QtGui/QFontMetricsF>
diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp
index 6aa7bedc5b..2ea1a062d8 100644
--- a/src/quick/util/qquickglobal.cpp
+++ b/src/quick/util/qquickglobal.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2015 BasysKom GmbH.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -285,6 +286,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 +309,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;
@@ -368,7 +374,7 @@ public:
return QMatrix4x4(matVals);
}
- const QMetaObject *getMetaObjectForMetaType(int type)
+ const QMetaObject *getMetaObjectForMetaType(int type) Q_DECL_OVERRIDE
{
switch (type) {
case QMetaType::QColor:
@@ -392,132 +398,37 @@ public:
return 0;
}
- template<typename T>
- bool typedInit(void *data, size_t dataSize)
- {
- ASSERT_VALID_SIZE(dataSize, sizeof(T));
- T *t = reinterpret_cast<T *>(data);
- new (t) T();
- return true;
- }
-
- bool init(int type, void *data, size_t dataSize)
+ bool init(int type, QVariant& dst) Q_DECL_OVERRIDE
{
switch (type) {
case QMetaType::QColor:
- return typedInit<QColor>(data, dataSize);
- case QMetaType::QFont:
- return typedInit<QFont>(data, dataSize);
- case QMetaType::QVector2D:
- return typedInit<QVector2D>(data, dataSize);
- case QMetaType::QVector3D:
- return typedInit<QVector3D>(data, dataSize);
- case QMetaType::QVector4D:
- return typedInit<QVector4D>(data, dataSize);
- case QMetaType::QQuaternion:
- return typedInit<QQuaternion>(data, dataSize);
- case QMetaType::QMatrix4x4:
- {
- if (dataSize >= sizeof(QMatrix4x4))
- return typedInit<QMatrix4x4>(data, dataSize);
-
- // special case: init matrix-containing qvariant.
- Q_ASSERT(dataSize >= sizeof(QVariant));
- QVariant *matvar = reinterpret_cast<QVariant *>(data);
- new (matvar) QVariant(QMatrix4x4());
+ dst.setValue<QColor>(QColor());
return true;
- }
- default: break;
- }
-
- return false;
- }
-
- template<typename T>
- bool typedDestroy(void *data, size_t dataSize)
- {
- ASSERT_VALID_SIZE(dataSize, sizeof(T));
- T *t = reinterpret_cast<T *>(data);
- t->~T();
- return true;
- }
-
- bool destroy(int type, void *data, size_t dataSize)
- {
- switch (type) {
- case QMetaType::QColor:
- return typedDestroy<QColor>(data, dataSize);
case QMetaType::QFont:
- return typedDestroy<QFont>(data, dataSize);
- case QMetaType::QVector2D:
- return typedDestroy<QVector2D>(data, dataSize);
- case QMetaType::QVector3D:
- return typedDestroy<QVector3D>(data, dataSize);
- case QMetaType::QVector4D:
- return typedDestroy<QVector4D>(data, dataSize);
- case QMetaType::QQuaternion:
- return typedDestroy<QQuaternion>(data, dataSize);
- case QMetaType::QMatrix4x4:
- {
- if (dataSize >= sizeof(QMatrix4x4))
- return typedDestroy<QMatrix4x4>(data, dataSize);
-
- // special case: destroying matrix-containing qvariant.
- Q_ASSERT(dataSize >= sizeof(QVariant));
- QVariant *matvar = reinterpret_cast<QVariant *>(data);
- matvar->~QVariant();
+ dst.setValue<QFont>(QFont());
return true;
- }
- default: break;
- }
-
- return false;
- }
-
- template<typename T>
- bool typedCopyConstruct(const void *src, void *dst, size_t dstSize)
- {
- ASSERT_VALID_SIZE(dstSize, sizeof(T));
- const T *srcT = reinterpret_cast<const T *>(src);
- T *destT = reinterpret_cast<T *>(dst);
- new (destT) T(*srcT);
- return true;
- }
-
- bool copy(int type, const void *src, void *dst, size_t dstSize)
- {
- switch (type) {
- case QMetaType::QColor:
- return typedCopyConstruct<QColor>(src, dst, dstSize);
- case QMetaType::QFont:
- return typedCopyConstruct<QFont>(src, dst, dstSize);
case QMetaType::QVector2D:
- return typedCopyConstruct<QVector2D>(src, dst, dstSize);
+ dst.setValue<QVector2D>(QVector2D());
+ return true;
case QMetaType::QVector3D:
- return typedCopyConstruct<QVector3D>(src, dst, dstSize);
+ dst.setValue<QVector3D>(QVector3D());
+ return true;
case QMetaType::QVector4D:
- return typedCopyConstruct<QVector4D>(src, dst, dstSize);
+ dst.setValue<QVector4D>(QVector4D());
+ return true;
case QMetaType::QQuaternion:
- return typedCopyConstruct<QQuaternion>(src, dst, dstSize);
+ dst.setValue<QQuaternion>(QQuaternion());
+ return true;
case QMetaType::QMatrix4x4:
- {
- if (dstSize >= sizeof(QMatrix4x4))
- return typedCopyConstruct<QMatrix4x4>(src, dst, dstSize);
-
- // special case: copying matrix into variant.
- Q_ASSERT(dstSize >= sizeof(QVariant));
- const QMatrix4x4 *srcMatrix = reinterpret_cast<const QMatrix4x4 *>(src);
- QVariant *dstMatrixVar = reinterpret_cast<QVariant *>(dst);
- new (dstMatrixVar) QVariant(*srcMatrix);
+ dst.setValue<QMatrix4x4>(QMatrix4x4());
return true;
- }
default: break;
}
return false;
}
- bool create(int type, int argc, const void *argv[], QVariant *v)
+ bool create(int type, int argc, const void *argv[], QVariant *v) Q_DECL_OVERRIDE
{
switch (type) {
case QMetaType::QFont: // must specify via js-object.
@@ -555,7 +466,11 @@ public:
}
break;
case QMetaType::QMatrix4x4:
- if (argc == 1) {
+ if (argc == 0) {
+ QMatrix4x4 m;
+ *v = QVariant(m);
+ return true;
+ } else if (argc == 1) {
const qreal *vals = reinterpret_cast<const qreal*>(argv[0]);
QMatrix4x4 m(vals[0], vals[1], vals[2], vals[3],
vals[4], vals[5], vals[6], vals[7],
@@ -580,7 +495,7 @@ public:
return true;
}
- bool createFromString(int type, const QString &s, void *data, size_t dataSize)
+ bool createFromString(int type, const QString &s, void *data, size_t dataSize) Q_DECL_OVERRIDE
{
bool ok = false;
@@ -596,22 +511,14 @@ public:
case QMetaType::QQuaternion:
return createFromStringTyped<QQuaternion>(data, dataSize, quaternionFromString(s, &ok));
case QMetaType::QMatrix4x4:
- {
- if (dataSize >= sizeof(QMatrix4x4))
- return createFromStringTyped<QMatrix4x4>(data, dataSize, matrix4x4FromString(s, &ok));
-
- Q_ASSERT(dataSize >= sizeof(QVariant));
- QVariant *matVar = reinterpret_cast<QVariant *>(data);
- new (matVar) QVariant(matrix4x4FromString(s, &ok));
- return true;
- }
+ return createFromStringTyped<QMatrix4x4>(data, dataSize, matrix4x4FromString(s, &ok));
default: break;
}
return false;
}
- bool createStringFrom(int type, const void *data, QString *s)
+ bool createStringFrom(int type, const void *data, QString *s) Q_DECL_OVERRIDE
{
if (type == QMetaType::QColor) {
const QColor *color = reinterpret_cast<const QColor *>(data);
@@ -622,7 +529,7 @@ public:
return false;
}
- bool variantFromString(const QString &s, QVariant *v)
+ bool variantFromString(const QString &s, QVariant *v) Q_DECL_OVERRIDE
{
QColor c(s);
if (c.isValid()) {
@@ -665,7 +572,7 @@ public:
return false;
}
- bool variantFromString(int type, const QString &s, QVariant *v)
+ bool variantFromString(int type, const QString &s, QVariant *v) Q_DECL_OVERRIDE
{
bool ok = false;
@@ -708,7 +615,7 @@ public:
return false;
}
- bool variantFromJsObject(int type, QQmlV4Handle object, QV4::ExecutionEngine *v4, QVariant *v)
+ bool variantFromJsObject(int type, QQmlV4Handle object, QV4::ExecutionEngine *v4, QVariant *v) Q_DECL_OVERRIDE
{
QV4::Scope scope(v4);
#ifndef QT_NO_DEBUG
@@ -729,12 +636,12 @@ public:
}
template<typename T>
- bool typedEqual(const void *lhs, const void *rhs)
+ bool typedEqual(const void *lhs, const QVariant& rhs)
{
- return (*(reinterpret_cast<const T *>(lhs)) == *(reinterpret_cast<const T *>(rhs)));
+ return (*(reinterpret_cast<const T *>(lhs)) == rhs.value<T>());
}
- bool equal(int type, const void *lhs, const void *rhs, size_t rhsSize)
+ bool equal(int type, const void *lhs, const QVariant &rhs) Q_DECL_OVERRIDE
{
switch (type) {
case QMetaType::QColor:
@@ -750,14 +657,7 @@ public:
case QMetaType::QQuaternion:
return typedEqual<QQuaternion>(lhs, rhs);
case QMetaType::QMatrix4x4:
- {
- if (rhsSize >= sizeof(QMatrix4x4))
- return typedEqual<QMatrix4x4>(lhs, rhs);
-
- Q_ASSERT(rhsSize >= sizeof(QVariant));
- QMatrix4x4 rhsmat = reinterpret_cast<const QVariant *>(rhs)->value<QMatrix4x4>();
- return typedEqual<QMatrix4x4>(lhs, &rhsmat);
- }
+ return typedEqual<QMatrix4x4>(lhs, rhs);
default: break;
}
@@ -774,8 +674,9 @@ public:
return true;
}
- bool store(int type, const void *src, void *dst, size_t dstSize)
+ bool store(int type, const void *src, void *dst, size_t dstSize) Q_DECL_OVERRIDE
{
+ Q_UNUSED(dstSize);
switch (type) {
case QMetaType::QColor:
{
@@ -785,81 +686,41 @@ public:
new (color) QColor(QColor::fromRgba(*rgb));
return true;
}
- case QMetaType::QFont:
- return typedStore<QFont>(src, dst, dstSize);
- case QMetaType::QVector2D:
- return typedStore<QVector2D>(src, dst, dstSize);
- case QMetaType::QVector3D:
- return typedStore<QVector3D>(src, dst, dstSize);
- case QMetaType::QVector4D:
- return typedStore<QVector4D>(src, dst, dstSize);
- case QMetaType::QQuaternion:
- return typedStore<QQuaternion>(src, dst, dstSize);
- case QMetaType::QMatrix4x4:
- {
- if (dstSize >= sizeof(QMatrix4x4))
- return typedStore<QMatrix4x4>(src, dst, dstSize);
-
- // special case: storing matrix into variant
- // eg, QVMEMO QVMEVariant data cell is big enough to store
- // QVariant, but not large enough to store QMatrix4x4.
- Q_ASSERT(dstSize >= sizeof(QVariant));
- const QMatrix4x4 *srcMat = reinterpret_cast<const QMatrix4x4 *>(src);
- QVariant *dstMatVar = reinterpret_cast<QVariant *>(dst);
- new (dstMatVar) QVariant(*srcMat);
- return true;
- }
- default: break;
+ default: break;
}
return false;
}
template<typename T>
- bool typedRead(int srcType, const void *src, size_t srcSize, int dstType, void *dst)
+ bool typedRead(const QVariant& src, int dstType, void *dst)
{
T *dstT = reinterpret_cast<T *>(dst);
- if (srcType == dstType) {
- ASSERT_VALID_SIZE(srcSize, sizeof(T));
- const T *srcT = reinterpret_cast<const T *>(src);
- *dstT = *srcT;
+ if (src.type() == static_cast<uint>(dstType)) {
+ *dstT = src.value<T>();
} else {
*dstT = T();
}
return true;
}
- bool read(int srcType, const void *src, size_t srcSize, int dstType, void *dst)
+ bool read(const QVariant &src, void *dst, int dstType) Q_DECL_OVERRIDE
{
switch (dstType) {
case QMetaType::QColor:
- return typedRead<QColor>(srcType, src, srcSize, dstType, dst);
+ return typedRead<QColor>(src, dstType, dst);
case QMetaType::QFont:
- return typedRead<QFont>(srcType, src, srcSize, dstType, dst);
+ return typedRead<QFont>(src, dstType, dst);
case QMetaType::QVector2D:
- return typedRead<QVector2D>(srcType, src, srcSize, dstType, dst);
+ return typedRead<QVector2D>(src, dstType, dst);
case QMetaType::QVector3D:
- return typedRead<QVector3D>(srcType, src, srcSize, dstType, dst);
+ return typedRead<QVector3D>(src, dstType, dst);
case QMetaType::QVector4D:
- return typedRead<QVector4D>(srcType, src, srcSize, dstType, dst);
+ return typedRead<QVector4D>(src, dstType, dst);
case QMetaType::QQuaternion:
- return typedRead<QQuaternion>(srcType, src, srcSize, dstType, dst);
+ return typedRead<QQuaternion>(src, dstType, dst);
case QMetaType::QMatrix4x4:
- {
- if (srcSize >= sizeof(QMatrix4x4))
- return typedRead<QMatrix4x4>(srcType, src, srcSize, dstType, dst);
-
- // the source data may be stored in a QVariant.
- QMatrix4x4 *dstMat = reinterpret_cast<QMatrix4x4 *>(dst);
- if (srcType == dstType) {
- Q_ASSERT(srcSize >= sizeof(QVariant));
- const QVariant *srcMatVar = reinterpret_cast<const QVariant *>(src);
- *dstMat = srcMatVar->value<QMatrix4x4>();
- } else {
- *dstMat = QMatrix4x4();
- }
- return true;
- }
+ return typedRead<QMatrix4x4>(src, dstType, dst);
default: break;
}
@@ -867,51 +728,33 @@ public:
}
template<typename T>
- bool typedWrite(const void *src, void *dst, size_t dstSize)
+ bool typedWrite(const void *src, QVariant& dst)
{
- ASSERT_VALID_SIZE(dstSize, sizeof(T));
const T *srcT = reinterpret_cast<const T *>(src);
- T *dstT = reinterpret_cast<T *>(dst);
- if (*dstT != *srcT) {
- *dstT = *srcT;
+ if (dst.value<T>() != *srcT) {
+ dst = *srcT;
return true;
}
return false;
}
- bool write(int type, const void *src, void *dst, size_t dstSize)
+ bool write(int type, const void *src, QVariant& dst) Q_DECL_OVERRIDE
{
switch (type) {
case QMetaType::QColor:
- return typedWrite<QColor>(src, dst, dstSize);
+ return typedWrite<QColor>(src, dst);
case QMetaType::QFont:
- return typedWrite<QFont>(src, dst, dstSize);
+ return typedWrite<QFont>(src, dst);
case QMetaType::QVector2D:
- return typedWrite<QVector2D>(src, dst, dstSize);
+ return typedWrite<QVector2D>(src, dst);
case QMetaType::QVector3D:
- return typedWrite<QVector3D>(src, dst, dstSize);
+ return typedWrite<QVector3D>(src, dst);
case QMetaType::QVector4D:
- return typedWrite<QVector4D>(src, dst, dstSize);
+ return typedWrite<QVector4D>(src, dst);
case QMetaType::QQuaternion:
- return typedWrite<QQuaternion>(src, dst, dstSize);
+ return typedWrite<QQuaternion>(src, dst);
case QMetaType::QMatrix4x4:
- {
- if (dstSize >= sizeof(QMatrix4x4))
- return typedWrite<QMatrix4x4>(src, dst, dstSize);
-
- // special case: storing matrix into variant
- // eg, QVMEMO QVMEVariant data cell is big enough to store
- // QVariant, but not large enough to store QMatrix4x4.
- Q_ASSERT(dstSize >= sizeof(QVariant));
- const QMatrix4x4 *srcMat = reinterpret_cast<const QMatrix4x4 *>(src);
- QVariant *dstMatVar = reinterpret_cast<QVariant *>(dst);
- QMatrix4x4 dstMatVal = dstMatVar->value<QMatrix4x4>();
- if (dstMatVal != *srcMat) {
- *dstMatVar = QVariant(*srcMat);
- return true;
- }
- return false;
- }
+ return typedWrite<QMatrix4x4>(src, dst);
default: break;
}
diff --git a/src/quick/util/qquickimageprovider.cpp b/src/quick/util/qquickimageprovider.cpp
index 6038967e18..d11229717a 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,25 @@ QImage QQuickTextureFactory::image() const
return QImage();
}
+/*!
+ Returns a QQuickTextureFactory holding the given image.
+
+ This is typically used as a helper in QQuickImageResponse::textureFactory.
+
+ \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 +140,71 @@ 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. The engine takes ownership of the returned QQuickTextureFactory.
+
+ \note This method will be called only when needed. For example, it may not be called if there is an
+ error or the job is cancelled. Therefore, allocate the QQuickTextureFactory instance only in this
+ method or otherwise ensure its deletion.
+ */
+
+
+/*!
\class QQuickImageProvider
\since 5.0
\inmodule QtQuick
@@ -213,7 +300,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 +310,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
@@ -366,6 +459,42 @@ QQuickTextureFactory *QQuickImageProvider::requestTexture(const QString &id, QSi
}
/*!
+ \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.
+*/
+
+/*!
\fn QImage QQuickImageProvider::requestImage(const QString &id, QSize *size, const QSize& requestedSize, bool requestedAutoTransform);
\internal
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..b39b6e5c01 100644
--- a/src/quick/util/qquickpath_p.h
+++ b/src/quick/util/qquickpath_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKPATH_H
#define QQUICKPATH_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 <qqml.h>
#include <private/qqmlnullablevalue_p.h>
@@ -265,7 +276,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/qquickpathinterpolator_p.h b/src/quick/util/qquickpathinterpolator_p.h
index 895aa56078..38c5debbed 100644
--- a/src/quick/util/qquickpathinterpolator_p.h
+++ b/src/quick/util/qquickpathinterpolator_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKPATHINTERPOLATOR_P_H
#define QQUICKPATHINTERPOLATOR_P_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 <qqml.h>
#include <QObject>
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp
index a1c9205539..ed6da8ac91 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
@@ -78,7 +77,7 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_DEBUG
-static bool qsg_leak_check = !qgetenv("QML_LEAK_CHECK").isEmpty();
+static const bool qsg_leak_check = !qEnvironmentVariableIsEmpty("QML_LEAK_CHECK");
#endif
// The cache limit describes the maximum "junk" in the cache.
@@ -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
@@ -182,6 +171,7 @@ public:
virtual bool event(QEvent *e);
private slots:
void networkRequestDone();
+ void asyncResponseFinished();
private:
QQuickPixmapReader *reader;
};
@@ -206,8 +196,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;
@@ -221,7 +212,8 @@ private:
QNetworkAccessManager *networkAccessManager();
QNetworkAccessManager *accessManager;
- QHash<QNetworkReply*,QQuickPixmapReply*> replies;
+ QHash<QNetworkReply*,QQuickPixmapReply*> networkJobs;
+ QHash<QQuickImageResponse*,QQuickPixmapReply*> asyncResponses;
static int replyDownloadProgress;
static int replyFinished;
@@ -445,8 +437,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;
@@ -461,7 +453,7 @@ QQuickPixmapReader::~QQuickPixmapReader()
void QQuickPixmapReader::networkRequestDone(QNetworkReply *reply)
{
- QQuickPixmapReply *job = replies.take(reply);
+ QQuickPixmapReply *job = networkJobs.take(reply);
if (job) {
job->redirectCount++;
@@ -478,7 +470,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;
}
}
@@ -500,7 +492,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();
@@ -509,6 +501,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)
{
@@ -535,6 +555,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);
@@ -544,16 +570,23 @@ 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();
+ asyncResponse->deleteLater();
+ }
}
PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingError>(job->url));
// deleteLater, since not owned by this thread
@@ -566,27 +599,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();
}
}
@@ -597,79 +637,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());
@@ -677,7 +735,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
@@ -688,7 +746,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);
}
}
}
@@ -781,8 +839,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
@@ -1091,7 +1147,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:
@@ -1099,9 +1155,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
@@ -1122,7 +1183,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());
@@ -1259,7 +1320,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/qquickpixmapcache_p.h b/src/quick/util/qquickpixmapcache_p.h
index 482a2e5653..6ab318ba7b 100644
--- a/src/quick/util/qquickpixmapcache_p.h
+++ b/src/quick/util/qquickpixmapcache_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKPIXMAPCACHE_H
#define QQUICKPIXMAPCACHE_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 <QtCore/qcoreapplication.h>
#include <QtCore/qstring.h>
#include <QtGui/qpixmap.h>
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..bda341412b 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);
}
@@ -451,7 +451,7 @@ QQuickPropertyChanges::ActionList QQuickPropertyChanges::actions()
QQmlBinding *newBinding = 0;
if (e.id != QQmlBinding::Invalid) {
QV4::Scope scope(QQmlEnginePrivate::getV4Engine(qmlEngine(this)));
- QV4::ScopedValue function(scope, QV4::QmlBindingWrapper::createQmlCallableForFunction(context, object(), d->cdata->compilationUnit->runtimeFunctions[e.id]));
+ QV4::ScopedValue function(scope, QV4::FunctionObject::createQmlFunction(context, object(), d->cdata->compilationUnit->runtimeFunctions[e.id]));
newBinding = new QQmlBinding(function, object(), context);
}
// QQmlBinding *newBinding = e.id != QQmlBinding::Invalid ? QQmlBinding::createBinding(e.id, object(), qmlContext(this)) : 0;
@@ -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/qquickpropertychanges_p.h b/src/quick/util/qquickpropertychanges_p.h
index 15e5ec2936..d5938fd102 100644
--- a/src/quick/util/qquickpropertychanges_p.h
+++ b/src/quick/util/qquickpropertychanges_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKPROPERTYCHANGES_H
#define QQUICKPROPERTYCHANGES_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 "qquickstatechangescript_p.h"
#include <private/qqmlcustomparser_p.h>
diff --git a/src/quick/util/qquickshortcut.cpp b/src/quick/util/qquickshortcut.cpp
index 36c6933af4..e6f66f7bf1 100644
--- a/src/quick/util/qquickshortcut.cpp
+++ b/src/quick/util/qquickshortcut.cpp
@@ -134,6 +134,37 @@ void QQuickShortcut::setSequence(const QVariant &sequence)
}
/*!
+ \qmlproperty string QtQuick::Shortcut::nativeText
+ \since 5.6
+
+ This property provides the shortcut's key sequence as a platform specific
+ string. This means that it will be shown translated, and on OS X it will
+ resemble a key sequence from the menu bar. It is best to display this text
+ to the user (for example, on a tooltip).
+
+ \sa sequence, portableText
+*/
+QString QQuickShortcut::nativeText() const
+{
+ return m_shortcut.toString(QKeySequence::NativeText);
+}
+
+/*!
+ \qmlproperty string QtQuick::Shortcut::portableText
+ \since 5.6
+
+ This property provides the shortcut's key sequence as a string in a
+ "portable" format, suitable for reading and writing to a file. In many
+ cases, it will look similar to the native text on Windows and X11.
+
+ \sa sequence, nativeText
+*/
+QString QQuickShortcut::portableText() const
+{
+ return m_shortcut.toString(QKeySequence::PortableText);
+}
+
+/*!
\qmlproperty bool QtQuick::Shortcut::enabled
This property holds whether the shortcut is enabled.
diff --git a/src/quick/util/qquickshortcut_p.h b/src/quick/util/qquickshortcut_p.h
index e16ac9df20..d8a233af78 100644
--- a/src/quick/util/qquickshortcut_p.h
+++ b/src/quick/util/qquickshortcut_p.h
@@ -57,6 +57,8 @@ class QQuickShortcut : public QObject, public QQmlParserStatus
Q_OBJECT
Q_INTERFACES(QQmlParserStatus)
Q_PROPERTY(QVariant sequence READ sequence WRITE setSequence NOTIFY sequenceChanged FINAL)
+ Q_PROPERTY(QString nativeText READ nativeText NOTIFY sequenceChanged FINAL REVISION 1)
+ Q_PROPERTY(QString portableText READ portableText NOTIFY sequenceChanged FINAL REVISION 1)
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged FINAL)
Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat NOTIFY autoRepeatChanged FINAL)
Q_PROPERTY(Qt::ShortcutContext context READ context WRITE setContext NOTIFY contextChanged FINAL)
@@ -68,6 +70,9 @@ public:
QVariant sequence() const;
void setSequence(const QVariant &sequence);
+ QString nativeText() const;
+ QString portableText() const;
+
bool isEnabled() const;
void setEnabled(bool enabled);
diff --git a/src/quick/util/qquicksmoothedanimation_p.h b/src/quick/util/qquicksmoothedanimation_p.h
index 68479aa629..9f18170283 100644
--- a/src/quick/util/qquicksmoothedanimation_p.h
+++ b/src/quick/util/qquicksmoothedanimation_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKSMOOTHEDANIMATION_H
#define QQUICKSMOOTHEDANIMATION_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 <qqml.h>
#include "qquickanimation_p.h"
@@ -47,7 +58,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 +65,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/qquickspringanimation_p.h b/src/quick/util/qquickspringanimation_p.h
index 082fd341f7..b924c4c72e 100644
--- a/src/quick/util/qquickspringanimation_p.h
+++ b/src/quick/util/qquickspringanimation_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKSPRINGANIMATION_H
#define QQUICKSPRINGANIMATION_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 <qqml.h>
#include "qquickanimation_p.h"
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..6d051ff578 100644
--- a/src/quick/util/qquickstate_p.h
+++ b/src/quick/util/qquickstate_p.h
@@ -34,18 +34,30 @@
#ifndef QQUICKSTATE_H
#define QQUICKSTATE_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 <qqml.h>
#include <qqmlproperty.h>
#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 +75,8 @@ public:
QVariant fromValue;
QVariant toValue;
- QQmlAbstractBinding *fromBinding;
- QWeakPointer<QQmlAbstractBinding> toBinding;
+ QQmlAbstractBinding::Ptr fromBinding;
+ QQmlAbstractBinding::Ptr toBinding;
QQuickStateActionEvent *event;
//strictly for matching
@@ -80,13 +92,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..f9580a53df 100644
--- a/src/quick/util/qquickstatechangescript_p.h
+++ b/src/quick/util/qquickstatechangescript_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKSTATEOPERATIONS_H
#define QQUICKSTATEOPERATIONS_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 "qquickstate_p.h"
#include <qqmlscriptstring.h>
@@ -62,7 +73,7 @@ public:
QString name() const;
void setName(const QString &);
- virtual void execute(Reason reason = ActualChange);
+ virtual void execute();
};
diff --git a/src/quick/util/qquickstategroup_p.h b/src/quick/util/qquickstategroup_p.h
index 8ea2dbc4b3..03676a68fb 100644
--- a/src/quick/util/qquickstategroup_p.h
+++ b/src/quick/util/qquickstategroup_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKSTATEGROUP_H
#define QQUICKSTATEGROUP_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 "qquickstate_p.h"
QT_BEGIN_NAMESPACE
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/qquickstyledtext_p.h b/src/quick/util/qquickstyledtext_p.h
index 2f07a740e5..cd6710ff26 100644
--- a/src/quick/util/qquickstyledtext_p.h
+++ b/src/quick/util/qquickstyledtext_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKSTYLEDTEXT_H
#define QQUICKSTYLEDTEXT_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 <QSize>
#include <QPointF>
#include <QList>
diff --git a/src/quick/util/qquicksvgparser_p.h b/src/quick/util/qquicksvgparser_p.h
index ed9a7558d0..60661a7840 100644
--- a/src/quick/util/qquicksvgparser_p.h
+++ b/src/quick/util/qquicksvgparser_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKSVGPARSER_P_H
#define QQUICKSVGPARSER_P_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 <QtCore/qstring.h>
#include <QtGui/qpainterpath.h>
diff --git a/src/quick/util/qquicksystempalette_p.h b/src/quick/util/qquicksystempalette_p.h
index 143efa1c12..99654d76f7 100644
--- a/src/quick/util/qquicksystempalette_p.h
+++ b/src/quick/util/qquicksystempalette_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKSYSTEMPALETTE_H
#define QQUICKSYSTEMPALETTE_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 <qqml.h>
#include <QtCore/qobject.h>
@@ -45,7 +56,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 +79,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/qquicktextmetrics.cpp b/src/quick/util/qquicktextmetrics.cpp
index 1dd787f4a5..13ccb515ce 100644
--- a/src/quick/util/qquicktextmetrics.cpp
+++ b/src/quick/util/qquicktextmetrics.cpp
@@ -244,7 +244,7 @@ QRectF QQuickTextMetrics::tightBoundingRect() const
}
/*!
- \qmlmethod string QtQuick::TextMetrics::elidedText
+ \qmlproperty string QtQuick::TextMetrics::elidedText
This property holds an elided version of the string (i.e., a string with
"..." in it) if the string \l text is wider than \l elideWidth. If the
diff --git a/src/quick/util/qquicktextmetrics_p.h b/src/quick/util/qquicktextmetrics_p.h
index c0265d9507..96e304b907 100644
--- a/src/quick/util/qquicktextmetrics_p.h
+++ b/src/quick/util/qquicktextmetrics_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKTEXTMETRICS_H
#define QQUICKTEXTMETRICS_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 <qqml.h>
#include <QtGui/QFontMetricsF>
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/qquicktransition.cpp b/src/quick/util/qquicktransition.cpp
index 5c1c34b62f..2eaf8261af 100644
--- a/src/quick/util/qquicktransition.cpp
+++ b/src/quick/util/qquicktransition.cpp
@@ -432,7 +432,7 @@ bool QQuickTransition::running() const
This property holds a list of the animations to be run for this transition.
- \snippet qml/dynamicscene/dynamicscene.qml top-level transitions
+ \snippet ../qml/dynamicscene/dynamicscene.qml top-level transitions
The top-level animations are run in parallel. To run them sequentially,
define them within a SequentialAnimation:
diff --git a/src/quick/util/qquicktransition_p.h b/src/quick/util/qquicktransition_p.h
index 826df6794b..d4cd1a087b 100644
--- a/src/quick/util/qquicktransition_p.h
+++ b/src/quick/util/qquicktransition_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKTRANSITION_H
#define QQUICKTRANSITION_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 "qquickstate_p.h"
#include <private/qabstractanimationjob_p.h>
#include <qqml.h>
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/qquicktransitionmanager_p_p.h b/src/quick/util/qquicktransitionmanager_p_p.h
index a6d91d7efd..f39cde77b0 100644
--- a/src/quick/util/qquicktransitionmanager_p_p.h
+++ b/src/quick/util/qquicktransitionmanager_p_p.h
@@ -45,14 +45,14 @@
// We mean it.
//
-#include "qquickstatechangescript_p.h"
#include "qquickanimation_p.h"
QT_BEGIN_NAMESPACE
-class QQuickStatePrivate;
+class QQuickState;
+class QQuickStateAction;
class QQuickTransitionManagerPrivate;
-class Q_AUTOTEST_EXPORT QQuickTransitionManager
+class Q_QUICK_PRIVATE_EXPORT QQuickTransitionManager
{
public:
QQuickTransitionManager();
diff --git a/src/quick/util/qquickutilmodule.cpp b/src/quick/util/qquickutilmodule.cpp
index 4d156a2d9a..0af2343504 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");
@@ -106,4 +114,6 @@ void QQuickUtilModule::defineModule()
qmlRegisterType<QQuickTextMetrics>("QtQuick", 2, 4, "TextMetrics");
qmlRegisterType<QQuickShortcut>("QtQuick", 2, 5, "Shortcut");
+
+ qmlRegisterType<QQuickShortcut,1>("QtQuick", 2, 6, "Shortcut");
}
diff --git a/src/quick/util/qquickutilmodule_p.h b/src/quick/util/qquickutilmodule_p.h
index 77d0e7dd3b..c2e80d22ce 100644
--- a/src/quick/util/qquickutilmodule_p.h
+++ b/src/quick/util/qquickutilmodule_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKUTILMODULE_H
#define QQUICKUTILMODULE_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 <qqml.h>
QT_BEGIN_NAMESPACE
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..da071ef2f5
--- /dev/null
+++ b/src/quick/util/qquickvalidator_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** 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
+
+//
+// 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 <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..4c2b488660 100644
--- a/src/quick/util/qquickvaluetypes_p.h
+++ b/src/quick/util/qquickvaluetypes_p.h
@@ -34,6 +34,17 @@
#ifndef QQUICKVALUETYPES_P_H
#define QQUICKVALUETYPES_P_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 <qqml.h>
#include <qtquickglobal.h>
#include <private/qqmlvaluetype_p.h>
@@ -244,6 +255,13 @@ public:
void setM43(qreal value) { v(3, 2) = value; }
void setM44(qreal value) { v(3, 3) = value; }
+ Q_INVOKABLE void translate(const QVector3D &t) { v.translate(t); }
+ Q_INVOKABLE void rotate(float angle, const QVector3D &axis) { v.rotate(angle, axis); }
+ Q_INVOKABLE void scale(float s) { v.scale(s); }
+ Q_INVOKABLE void scale(float sx, float sy, float sz) { v.scale(sx, sy, sz); }
+ Q_INVOKABLE void scale(const QVector3D &s) { v.scale(s); }
+ Q_INVOKABLE void lookAt(const QVector3D &eye, const QVector3D &center, const QVector3D &up) { v.lookAt(eye, center, up); }
+
Q_INVOKABLE QMatrix4x4 times(const QMatrix4x4 &m) const;
Q_INVOKABLE QVector4D times(const QVector4D &vec) const;
Q_INVOKABLE QVector3D times(const QVector3D &vec) const;
@@ -266,10 +284,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 +309,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