summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brasser <michael.brasser@nokia.com>2009-06-11 22:32:42 (GMT)
committerMichael Brasser <michael.brasser@nokia.com>2009-06-11 22:32:42 (GMT)
commit1e2409cf6acaa8b390e65745821d21f2a8bb344d (patch)
tree3962fbc0bf92e2826fe6ba488c16240e8d1cf2de
parent9d9cf497c1d21fe80b5bdd0db2a2fa145ebe9ab0 (diff)
parentf10791eb1c45b090f60a2c2ecca3cc5fd237278e (diff)
downloadQt-1e2409cf6acaa8b390e65745821d21f2a8bb344d.zip
Qt-1e2409cf6acaa8b390e65745821d21f2a8bb344d.tar.gz
Qt-1e2409cf6acaa8b390e65745821d21f2a8bb344d.tar.bz2
Merge branch 'kinetic-declarativeui' of git@scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
-rw-r--r--demos/embeddeddialogs/main.cpp1
-rw-r--r--dist/changes-4.6.033
-rw-r--r--doc/src/declarative/basictypes.qdoc20
-rw-r--r--doc/src/declarative/modules.qdoc100
-rw-r--r--doc/src/declarative/qmlforcpp.qdoc3
-rw-r--r--doc/src/diagrams/programs/easingcurve/main.cpp36
-rw-r--r--doc/src/richtext.qdoc5
-rw-r--r--examples/graphicsview/elasticnodes/node.cpp1
-rw-r--r--examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.cpp5
-rw-r--r--src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp8
-rw-r--r--src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp22
-rw-r--r--src/3rdparty/webkit/WebKit/qt/docs/qtwebkit.qdoc3
-rw-r--r--src/corelib/animation/qparallelanimationgroup.cpp33
-rw-r--r--src/corelib/codecs/qisciicodec.cpp2
-rw-r--r--src/corelib/io/io.pri1
-rw-r--r--src/corelib/io/qfileinfo.cpp65
-rw-r--r--src/corelib/io/qfileinfo_p.h126
-rw-r--r--src/corelib/kernel/qabstractitemmodel.cpp31
-rw-r--r--src/corelib/kernel/qabstractitemmodel_p.h1
-rw-r--r--src/corelib/kernel/qobject.cpp89
-rw-r--r--src/corelib/kernel/qobject.h3
-rw-r--r--src/corelib/kernel/qobject_p.h5
-rw-r--r--src/corelib/kernel/qtimer.cpp2
-rw-r--r--src/corelib/kernel/qvariant.cpp2
-rw-r--r--src/corelib/tools/qlocale.cpp2
-rw-r--r--src/corelib/tools/qlocale_data_p.h10
-rw-r--r--src/corelib/tools/qstringbuilder.cpp12
-rw-r--r--src/corelib/tools/qstringbuilder.h12
-rw-r--r--src/corelib/xml/qxmlstream.cpp7
-rw-r--r--src/declarative/canvas/qsimplecanvas.cpp53
-rw-r--r--src/declarative/canvas/qsimplecanvas_opengl.cpp308
-rw-r--r--src/declarative/canvas/qsimplecanvas_p.h6
-rw-r--r--src/declarative/canvas/qsimplecanvasitem.cpp8
-rw-r--r--src/declarative/canvas/qsimplecanvasitem.h42
-rw-r--r--src/declarative/canvas/qsimplecanvasitem_p.h8
-rw-r--r--src/declarative/extra/qmlxmllistmodel.cpp8
-rw-r--r--src/declarative/extra/qmlxmllistmodel.h6
-rw-r--r--src/declarative/fx/qfxanimatedimageitem.cpp5
-rw-r--r--src/declarative/fx/qfxblendedimage.cpp34
-rw-r--r--src/declarative/fx/qfxblendedimage.h14
-rw-r--r--src/declarative/fx/qfxhighlightfilter.cpp12
-rw-r--r--src/declarative/fx/qfxhighlightfilter.h8
-rw-r--r--src/declarative/fx/qfximage.cpp533
-rw-r--r--src/declarative/fx/qfximage.h8
-rw-r--r--src/declarative/fx/qfximage_p.h29
-rw-r--r--src/declarative/fx/qfxitem.cpp26
-rw-r--r--src/declarative/fx/qfxitem.h6
-rw-r--r--src/declarative/fx/qfxitem_p.h3
-rw-r--r--src/declarative/fx/qfxparticles.cpp18
-rw-r--r--src/declarative/fx/qfxparticles.h6
-rw-r--r--src/declarative/fx/qfxrect.cpp545
-rw-r--r--src/declarative/fx/qfxrect_p.h31
-rw-r--r--src/declarative/fx/qfxtext.cpp110
-rw-r--r--src/declarative/fx/qfxwebview.cpp18
-rw-r--r--src/declarative/fx/qfxwebview.h6
-rw-r--r--src/declarative/opengl/gltexture.cpp102
-rw-r--r--src/declarative/opengl/gltexture.h6
-rw-r--r--src/declarative/qml/parser/parser.pri34
-rw-r--r--src/declarative/qml/parser/qmljs.g (renamed from src/declarative/qml/parser/javascript.g)56
-rw-r--r--src/declarative/qml/parser/qmljsast.cpp (renamed from src/declarative/qml/parser/javascriptast.cpp)20
-rw-r--r--src/declarative/qml/parser/qmljsast_p.h (renamed from src/declarative/qml/parser/javascriptast_p.h)225
-rw-r--r--src/declarative/qml/parser/qmljsastfwd_p.h (renamed from src/declarative/qml/parser/javascriptastfwd_p.h)7
-rw-r--r--src/declarative/qml/parser/qmljsastvisitor.cpp (renamed from src/declarative/qml/parser/javascriptastvisitor.cpp)6
-rw-r--r--src/declarative/qml/parser/qmljsastvisitor_p.h (renamed from src/declarative/qml/parser/javascriptastvisitor_p.h)14
-rw-r--r--src/declarative/qml/parser/qmljsengine_p.cpp (renamed from src/declarative/qml/parser/javascriptengine_p.cpp)10
-rw-r--r--src/declarative/qml/parser/qmljsengine_p.h (renamed from src/declarative/qml/parser/javascriptengine_p.h)22
-rw-r--r--src/declarative/qml/parser/qmljsgrammar.cpp (renamed from src/declarative/qml/parser/javascriptgrammar.cpp)18
-rw-r--r--src/declarative/qml/parser/qmljsgrammar_p.h (renamed from src/declarative/qml/parser/javascriptgrammar_p.h)8
-rw-r--r--src/declarative/qml/parser/qmljslexer.cpp (renamed from src/declarative/qml/parser/javascriptlexer.cpp)264
-rw-r--r--src/declarative/qml/parser/qmljslexer_p.h (renamed from src/declarative/qml/parser/javascriptlexer_p.h)8
-rw-r--r--src/declarative/qml/parser/qmljsmemorypool_p.h (renamed from src/declarative/qml/parser/javascriptmemorypool_p.h)8
-rw-r--r--src/declarative/qml/parser/qmljsnodepool_p.h (renamed from src/declarative/qml/parser/javascriptnodepool_p.h)10
-rw-r--r--src/declarative/qml/parser/qmljsparser.cpp (renamed from src/declarative/qml/parser/javascriptparser.cpp)29
-rw-r--r--src/declarative/qml/parser/qmljsparser_p.h (renamed from src/declarative/qml/parser/javascriptparser_p.h)21
-rw-r--r--src/declarative/qml/parser/qmljsprettypretty.cpp (renamed from src/declarative/qml/parser/javascriptprettypretty.cpp)14
-rw-r--r--src/declarative/qml/parser/qmljsprettypretty_p.h (renamed from src/declarative/qml/parser/javascriptprettypretty_p.h)10
-rw-r--r--src/declarative/qml/qml.pri3
-rw-r--r--src/declarative/qml/qmlbasicscript.cpp198
-rw-r--r--src/declarative/qml/qmlbasicscript_p.h11
-rw-r--r--src/declarative/qml/qmlbindablevalue.cpp100
-rw-r--r--src/declarative/qml/qmlbindablevalue.h1
-rw-r--r--src/declarative/qml/qmlcompiler.cpp150
-rw-r--r--src/declarative/qml/qmlcompiler_p.h46
-rw-r--r--src/declarative/qml/qmlcomponent.cpp1
-rw-r--r--src/declarative/qml/qmlcomponent.h1
-rw-r--r--src/declarative/qml/qmldom.cpp10
-rw-r--r--src/declarative/qml/qmldom.h2
-rw-r--r--src/declarative/qml/qmlengine.cpp102
-rw-r--r--src/declarative/qml/qmlengine.h1
-rw-r--r--src/declarative/qml/qmlengine_p.h15
-rw-r--r--src/declarative/qml/qmlexpression.h2
-rw-r--r--src/declarative/qml/qmlinstruction.cpp5
-rw-r--r--src/declarative/qml/qmlinstruction_p.h16
-rw-r--r--src/declarative/qml/qmlmetaproperty.cpp436
-rw-r--r--src/declarative/qml/qmlparser.cpp4
-rw-r--r--src/declarative/qml/qmlparser_p.h11
-rw-r--r--src/declarative/qml/qmlproxymetaobject.cpp2
-rw-r--r--src/declarative/qml/qmlscriptparser.cpp35
-rw-r--r--src/declarative/qml/qmlvme.cpp319
-rw-r--r--src/declarative/qml/qmlvmemetaobject.cpp3
-rw-r--r--src/declarative/qml/qpodvector_p.h124
-rw-r--r--src/declarative/qml/rewriter/rewriter.cpp8
-rw-r--r--src/declarative/qml/rewriter/rewriter_p.h6
-rw-r--r--src/declarative/qml/rewriter/textwriter.cpp2
-rw-r--r--src/declarative/qml/rewriter/textwriter_p.h4
-rw-r--r--src/declarative/util/qfxview.cpp6
-rw-r--r--src/declarative/util/qmlscript.cpp17
-rw-r--r--src/declarative/util/qmlscript.h6
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp1150
-rw-r--r--src/gui/graphicsview/qgraphicsitem.h4
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h245
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp988
-rw-r--r--src/gui/graphicsview/qgraphicsscene.h5
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h43
-rw-r--r--src/gui/graphicsview/qgraphicsview.cpp296
-rw-r--r--src/gui/graphicsview/qgraphicsview.h5
-rw-r--r--src/gui/graphicsview/qgraphicsview_p.h10
-rw-r--r--src/gui/graphicsview/qgraphicswidget.cpp3
-rw-r--r--src/gui/graphicsview/qgraphicswidget_p.cpp2
-rw-r--r--src/gui/image/qpicture_p.h2
-rw-r--r--src/gui/itemviews/qabstractitemview.cpp4
-rw-r--r--src/gui/itemviews/qheaderview.cpp3
-rw-r--r--src/gui/itemviews/qlistwidget.cpp5
-rw-r--r--src/gui/itemviews/qsortfilterproxymodel.cpp7
-rw-r--r--src/gui/itemviews/qstandarditemmodel.cpp4
-rw-r--r--src/gui/itemviews/qtableview.cpp6
-rw-r--r--src/gui/itemviews/qtablewidget.cpp20
-rw-r--r--src/gui/itemviews/qtablewidget_p.h1
-rw-r--r--src/gui/itemviews/qtreeview.cpp15
-rw-r--r--src/gui/itemviews/qtreewidget.cpp25
-rw-r--r--src/gui/itemviews/qtreewidget_p.h1
-rw-r--r--src/gui/kernel/qaction.cpp25
-rw-r--r--src/gui/kernel/qapplication_x11.cpp87
-rw-r--r--src/gui/kernel/qt_x11_p.h6
-rw-r--r--src/gui/kernel/qwidget_p.h8
-rw-r--r--src/gui/kernel/qwidget_x11.cpp28
-rw-r--r--src/gui/kernel/qwidgetaction.cpp4
-rw-r--r--src/gui/math3d/qgenericmatrix.cpp2
-rw-r--r--src/gui/math3d/qgenericmatrix.h2
-rw-r--r--src/gui/math3d/qmatrix4x4.cpp2
-rw-r--r--src/gui/math3d/qmatrix4x4.h2
-rw-r--r--src/gui/math3d/qquaternion.cpp2
-rw-r--r--src/gui/math3d/qquaternion.h2
-rw-r--r--src/gui/math3d/qvector2d.cpp2
-rw-r--r--src/gui/math3d/qvector2d.h2
-rw-r--r--src/gui/math3d/qvector3d.cpp2
-rw-r--r--src/gui/math3d/qvector3d.h2
-rw-r--r--src/gui/math3d/qvector4d.cpp2
-rw-r--r--src/gui/math3d/qvector4d.h2
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp4
-rw-r--r--src/gui/painting/qpaintengineex.cpp4
-rw-r--r--src/gui/painting/qpaintengineex_p.h2
-rw-r--r--src/gui/painting/qpainter.cpp24
-rw-r--r--src/gui/painting/qpainter_p.h4
-rw-r--r--src/gui/painting/qprinter.cpp3
-rw-r--r--src/gui/painting/qtextureglyphcache_p.h2
-rw-r--r--src/gui/styles/qcleanlooksstyle.cpp3
-rw-r--r--src/gui/styles/qgtkstyle.cpp2
-rw-r--r--src/gui/styles/qplastiquestyle.cpp3
-rw-r--r--src/gui/text/qcssparser.cpp42
-rw-r--r--src/gui/text/qcssparser_p.h1
-rw-r--r--src/gui/text/qfontengine.cpp6
-rw-r--r--src/gui/text/qfontengine_p.h1
-rw-r--r--src/gui/text/qfontengineglyphcache_p.h4
-rw-r--r--src/gui/text/qtexthtmlparser.cpp2
-rw-r--r--src/gui/util/qdesktopservices_win.cpp7
-rw-r--r--src/gui/widgets/qdockarealayout.cpp8
-rw-r--r--src/gui/widgets/qdockwidget.cpp7
-rw-r--r--src/gui/widgets/qmenubar.cpp6
-rw-r--r--src/gui/widgets/qtoolbarlayout.cpp2
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager.cpp3
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadersource_p.h14
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp420
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h26
-rw-r--r--src/opengl/qegl.cpp10
-rw-r--r--src/opengl/qgl.cpp15
-rw-r--r--src/opengl/qgl_p.h3
-rw-r--r--src/opengl/qglextensions.cpp3
-rw-r--r--src/opengl/qglframebufferobject.cpp2
-rw-r--r--src/opengl/qglpixelbuffer.cpp4
-rw-r--r--src/opengl/qpixmapdata_gl.cpp5
-rw-r--r--src/plugins/imageformats/jpeg/qjpeghandler.cpp3
-rw-r--r--src/plugins/imageformats/tiff/qtiffhandler.cpp342
-rw-r--r--tests/auto/bic/bic.pro6
-rw-r--r--tests/auto/bic/tst_bic.cpp33
-rw-r--r--tests/auto/declarative/numberformatter/tst_numberformatter.cpp1
-rw-r--r--tests/auto/math3d/qmatrixnxn/tst_qmatrixnxn.cpp2
-rw-r--r--tests/auto/math3d/qquaternion/tst_qquaternion.cpp2
-rw-r--r--tests/auto/math3d/qvectornd/tst_qvectornd.cpp2
-rw-r--r--tests/auto/math3d/shared/math3dincludes.h2
-rw-r--r--tests/auto/qcssparser/tst_cssparser.cpp45
-rw-r--r--tests/auto/qfileinfo/tst_qfileinfo.cpp56
-rw-r--r--tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp506
-rw-r--r--tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp2
-rw-r--r--tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp8
-rw-r--r--tests/auto/qgraphicsview/tst_qgraphicsview.cpp59
-rw-r--r--tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp36
-rw-r--r--tests/auto/qimagereader/qimagereader.qrc2
-rw-r--r--tests/auto/qimagereader/tst_qimagereader.cpp26
-rw-r--r--tests/auto/qimagewriter/tst_qimagewriter.cpp26
-rw-r--r--tests/auto/qlistwidget/tst_qlistwidget.cpp39
-rw-r--r--tests/auto/qwidget/tst_qwidget.cpp94
-rw-r--r--tools/linguist/lupdate/qml.cpp14
-rw-r--r--tools/qdoc3/htmlgenerator.cpp68
-rw-r--r--tools/qdoc3/test/classic.css49
-rwxr-xr-xutil/local_database/qlocalexml2cpp.py6
206 files changed, 5912 insertions, 4215 deletions
diff --git a/demos/embeddeddialogs/main.cpp b/demos/embeddeddialogs/main.cpp
index cfb31c4..c9b6ee1 100644
--- a/demos/embeddeddialogs/main.cpp
+++ b/demos/embeddeddialogs/main.cpp
@@ -76,7 +76,6 @@ int main(int argc, char *argv[])
view.scale(0.5, 0.5);
view.setRenderHints(view.renderHints() | QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
view.setBackgroundBrush(QPixmap(":/No-Ones-Laughing-3.jpg"));
- view.setCacheMode(QGraphicsView::CacheBackground);
view.setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
view.show();
view.setWindowTitle("Embedded Dialogs Demo");
diff --git a/dist/changes-4.6.0 b/dist/changes-4.6.0
index bedf58a..ba58bcf 100644
--- a/dist/changes-4.6.0
+++ b/dist/changes-4.6.0
@@ -40,17 +40,30 @@ information about a particular change.
reasons for this is that Qt Software focuses on OpenGL for desktop
hardware accelerated rendering.
- - QStyleOptionGraphicsItem::exposedRect and QStyleOptionGraphicsItem::matrix
- does no longer contain fine-grained values when passed in drawItems()/paint()
- unless the QGraphicsItem::ItemUsesExtendedStyleOptions flag is enabled.
- By default, exposedRect is initialized to the item's bounding rect
- and the matrix is untransformed.
-
- - QStyleOptionGraphicsItem::levelOfDetails is obsoleted and its value
- is always initialized to 1. For a more fine-grained value use
- QStyleOptionGraphicsItem::levelOfDetailFromTransform(const QTransform &).
-
- When mixing OpenGL and QPainter calls you need to first call syncState()
on the paint engine, for example "painter->paintEngine()->syncState()".
This is to ensure that the engine flushes any pending drawing and sets up
the GL modelview/projection matrices properly.
+
+ - Graphics View has undergone heavy optimization work, and as a result of
+ this work, the following behavior changes were introduced.
+
+ a) QStyleOptionGraphicsItem::exposedRect now contains the item's bounding
+ rectangle, and QStyleOptionGraphicsItem::matrix is uninitialized by
+ default. You can enable an exact exposed rectangle and a correct matrix
+ by enabling the flag QGraphicsItem::ItemUsesExtendedStyleOptions.
+
+ b) QStyleOptionGraphicsItem::levelOfDetails is obsoleted and its value is
+ always initialized to 1. Instead you can call
+ QStyleOptionGraphicsItem::levelOfDetailFromTransform(const QTransform &)
+ to determine the level of detail.
+
+ c) QGraphicsView no longer calls QGraphicsView::drawItems(), and in turn
+ QGraphicsScene::drawItems(), by default. You can get the old behavior
+ back by enabling QGraphicsView::IndirectPainting.
+
+ d) QGraphicsItem no longer calls itemChange() for position and
+ transformation changes. If you want to receive notifications for changes
+ to the item's position and transformation, you can set the flag
+ QGraphicsItem::ItemSendsGeometryChanges (which is enabled by default by
+ QGraphicsWidget and QGraphicsProxyWidget).
diff --git a/doc/src/declarative/basictypes.qdoc b/doc/src/declarative/basictypes.qdoc
index f7eee50..2ef91e6 100644
--- a/doc/src/declarative/basictypes.qdoc
+++ b/doc/src/declarative/basictypes.qdoc
@@ -82,6 +82,26 @@
\raw HTML
\endraw
+ \target basicqmlurl
+ \raw HTML
+ <br>
+ <table>
+ <tr><td><div class="qmltype">url</div></td></tr>
+ </table>
+ \endraw
+
+ URLs are resource locators, such as file names. They can be either absolute, like "http://qtsoftware.com",
+ or relative, like "pics/logo.png". Relative URLs are resolved relative to the URL of the component where
+ the URL is converted from a JavaScript string expression to a url property value.
+
+ Setting a url looks like this:
+ \code
+ Image { source: "pics/logo.png" }
+ \endcode
+
+ \raw HTML
+ \endraw
+
\target basicqmlcolor
\raw HTML
<br>
diff --git a/doc/src/declarative/modules.qdoc b/doc/src/declarative/modules.qdoc
index 5933223..194be40 100644
--- a/doc/src/declarative/modules.qdoc
+++ b/doc/src/declarative/modules.qdoc
@@ -20,3 +20,103 @@ the component issuing the import.
The import statement cannot be used by remote content.
*/
+
+/*
+
+Ideas for full module support....
+
+
+* Modularity within applications
+
+This is the currently-supported mechanism.
+
+By using the "import" statement, a subdirectory of types can be added to the
+empty namespace. Alternatively, a type in a subdirectory can be referenced
+explicitly.
+
+So, given these files:
+
+ ./SubModule1/Type1.qml
+ ./SubModule2/Type1.qml
+
+This is valid QML:
+
+ import "SubModule1"
+ Type1 { ... }
+ SubModule2.Type1 { ... }
+
+
+* System-installed modules (dependencies)
+
+To use system-installed modules, the dependency must be explicitly stated
+using the "require" statement. Types in required modules must still be
+explicitly qualified. Dependencies cannot be added to the empty namespace.
+
+ QMLPATH=/opt/Nokia/qml:/usr/share/lib/qml
+ /opt/Nokia/qml/Module1/Type1.qml
+ /usr/share/lib/qml/Module1/Type1.qml
+
+ require "Module1"
+ Module1.Type1 { ... }
+
+
+* Grouping of components within application modules
+
+Sub-sub directories allow further grouping of types.
+
+ ./SubModule1/Group1/*.qml
+ ./SubModule1/Group2/*.qml
+
+ SubModule1.Group1.Type1 { ... }
+ SubModule1.Group1.Type2 { ... }
+ SubModule1.Group2.Type1 { ... }
+ SubModule1.Group2.Type2 { ... }
+
+ import "SubModule1/Group1"
+ Type1 { ... }
+
+ import "SubModule1"
+ Group1.Type1 { ... }
+
+
+* Grouping of components within system-installed modules
+
+System-installed types may also be grouped into types. The hierarchy is a
+global namespace, so such grouping is recommended to reduce clashes.
+
+ /opt/Nokia/qml/Module1/Group1/*.qml
+ /opt/Nokia/qml/Module1/Group2/*.qml
+
+ require "Module1"
+ Module1.Group1.Type1 { ... }
+ Module1.Group1.Type2 { ... }
+ Module1.Group2.Type1 { ... }
+ Module1.Group2.Type2 { ... }
+
+ require "Module1/Group1"
+ Group1.Type1 { ... }
+
+ // Alternative syntax
+ /opt/qml/com/nokia/qml/Module1/Group1/*.qml
+ require "com.nokia.qml.Module1.Group1"
+ Group1.Type1 { ... }
+
+
+* Private sub-components
+
+Directories begining with _ cannot be referenced except by types in the
+directory immediately containing it.
+
+ /opt/Nokia/qml/Module1/_private/Type1.qml
+ ./SubModule1/_private/Type1.qml
+
+ SubModule1._private.Type1 { ... } // Not allowed
+ import "SubModule1._private" // Not allowed
+ require "SubModule1._private" // Not allowed
+ require "SubModule1"
+ Module1._private.Type1 { ... } // Not allowed
+
+ import "_private" // allowed
+ Type1 { ... }
+
+*/
diff --git a/doc/src/declarative/qmlforcpp.qdoc b/doc/src/declarative/qmlforcpp.qdoc
index 2898499..4095071 100644
--- a/doc/src/declarative/qmlforcpp.qdoc
+++ b/doc/src/declarative/qmlforcpp.qdoc
@@ -186,7 +186,8 @@
name \a QmlName. Of course there's nothing stopping you using the same
name for both the C++ and the QML name!
Any type can be added to the QML engine using these macros. The only
- requirements are that \a T inherits QObject and that it has a default constructor.
+ requirements are that \a T inherits QObject, is not abstract,
+ and that it has a default constructor.
\section1 Property Binding
diff --git a/doc/src/diagrams/programs/easingcurve/main.cpp b/doc/src/diagrams/programs/easingcurve/main.cpp
index 98e9d37..8d399a3 100644
--- a/doc/src/diagrams/programs/easingcurve/main.cpp
+++ b/doc/src/diagrams/programs/easingcurve/main.cpp
@@ -1,11 +1,41 @@
/****************************************************************************
**
-** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the $MODULE$ of the Qt Toolkit.
+** This file is part of the examples of the Qt Toolkit.
**
-** $TROLLTECH_DUAL_LICENSE$
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/doc/src/richtext.qdoc b/doc/src/richtext.qdoc
index fbd8adb..6ea82f8 100644
--- a/doc/src/richtext.qdoc
+++ b/doc/src/richtext.qdoc
@@ -1058,8 +1058,11 @@ Ideas for other sections:
\o Specifies where an image or a text will be placed in another element. Note that the \c float property is
only supported for tables and images.
\row \o \c text-transform
- \o [ uppercase | lowercase | smallcaps ]
+ \o [ uppercase | lowercase ]
\o Select the transformation that will be performed on the text prior to displaying it.
+ \row \o \c font-variant
+ \o small-caps
+ \o Perform the smallcaps transformation on the text prior to displaying it.
\row \o \c word-spacing
\o <width>px
\o Specifies an alternate spacing between each word.
diff --git a/examples/graphicsview/elasticnodes/node.cpp b/examples/graphicsview/elasticnodes/node.cpp
index 6942fa0..53fe994 100644
--- a/examples/graphicsview/elasticnodes/node.cpp
+++ b/examples/graphicsview/elasticnodes/node.cpp
@@ -52,6 +52,7 @@ Node::Node(GraphWidget *graphWidget)
: graph(graphWidget)
{
setFlag(ItemIsMovable);
+ setFlag(ItemSendsGeometryChanges);
setCacheMode(DeviceCoordinateCache);
setZValue(1);
}
diff --git a/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.cpp b/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.cpp
index d360de9..2368608 100644
--- a/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.cpp
+++ b/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.cpp
@@ -42,13 +42,12 @@
#include "random_ai_plugin.h"
#include <QState>
+#include <QTime>
#include <QtPlugin>
-#include <time.h>
-
QState *RandomAiPlugin::create(QState *parentState, QObject *tank)
{
- qsrand(uint(time(NULL)));
+ qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
QState *topLevel = new QState(parentState);
diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp
index 01b68eb..77add54 100644
--- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp
+++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp
@@ -1986,10 +1986,12 @@ bool QWebPage::isContentEditable() const
/*!
\property QWebPage::forwardUnsupportedContent
- \brief whether QWebPage should forward unsupported content through the
- unsupportedContent signal
+ \brief whether QWebPage should forward unsupported content
- If disabled the download of such content is aborted immediately.
+ If enabled, the unsupportedContent() signal is emitted with a network reply that
+ can be used to read the content.
+
+ If disabled, the download of such content is aborted immediately.
By default unsupported content is not forwarded.
*/
diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp
index 1ad23f6..b516263 100644
--- a/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp
+++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp
@@ -213,17 +213,25 @@ QWebSettings *QWebSettings::globalSettings()
Each QWebPage object has its own QWebSettings object, which configures the
settings for that page. If a setting is not configured, then it is looked
up in the global settings object, which can be accessed using
- QWebSettings::globalSettings().
+ globalSettings().
- QWebSettings allows configuring font properties such as font size and font
- family, the location of a custom stylesheet, and generic attributes like java
- script, plugins, etc. The \l{QWebSettings::WebAttribute}{WebAttribute}
- enum further describes this.
+ QWebSettings allows configuration of browser properties, such as font sizes and
+ families, the location of a custom style sheet, and generic attributes like
+ JavaScript and plugins. Individual attributes are set using the setAttribute()
+ function. The \l{QWebSettings::WebAttribute}{WebAttribute} enum further describes
+ each attribute.
- QWebSettings also configures global properties such as the web page memory
- cache and the web page icon database, local database storage and offline
+ QWebSettings also configures global properties such as the Web page memory
+ cache and the Web page icon database, local database storage and offline
applications storage.
+ \section1 Enabling Plugins
+
+ Support for browser plugins can enabled by setting the
+ \l{QWebSettings::PluginsEnabled}{PluginsEnabled} attribute. For many applications,
+ this attribute is enabled for all pages by setting it on the
+ \l{globalSettings()}{global settings object}.
+
\section1 Web Application Support
WebKit provides support for features specified in \l{HTML 5} that improve the
diff --git a/src/3rdparty/webkit/WebKit/qt/docs/qtwebkit.qdoc b/src/3rdparty/webkit/WebKit/qt/docs/qtwebkit.qdoc
index 06305e0..119c126 100644
--- a/src/3rdparty/webkit/WebKit/qt/docs/qtwebkit.qdoc
+++ b/src/3rdparty/webkit/WebKit/qt/docs/qtwebkit.qdoc
@@ -96,7 +96,8 @@
Since WebKit supports the Netscape Plugin API, Qt applications can display
Web pages that embed common plugins, as long as the user has the appropriate
- binary files for those plugins installed.
+ binary files for those plugins installed and the \l{QWebSettings::PluginsEnabled}
+ attribute is set for the application.
The following locations are searched for plugins:
diff --git a/src/corelib/animation/qparallelanimationgroup.cpp b/src/corelib/animation/qparallelanimationgroup.cpp
index c148cb5d..6ec4679 100644
--- a/src/corelib/animation/qparallelanimationgroup.cpp
+++ b/src/corelib/animation/qparallelanimationgroup.cpp
@@ -135,13 +135,14 @@ void QParallelAnimationGroup::updateCurrentTime(int)
// simulate completion of the loop
int dura = duration();
if (dura > 0) {
- foreach (QAbstractAnimation *animation, d->animations) {
- animation->setCurrentTime(dura); // will stop
+ for (int i = 0; i < d->animations.size(); ++i) {
+ d->animations.at(i)->setCurrentTime(dura); // will stop
}
}
} else if (d->currentLoop < d->lastLoop) {
// simulate completion of the loop seeking backwards
- foreach (QAbstractAnimation *animation, d->animations) {
+ for (int i = 0; i < d->animations.size(); ++i) {
+ QAbstractAnimation *animation = d->animations.at(i);
animation->setCurrentTime(0);
animation->stop();
}
@@ -154,7 +155,8 @@ void QParallelAnimationGroup::updateCurrentTime(int)
__LINE__, d->currentTime, d->currentLoop, d->lastLoop, timeFwd, d->lastCurrentTime, state());
#endif
// finally move into the actual time of the current loop
- foreach (QAbstractAnimation *animation, d->animations) {
+ for (int i = 0; i < d->animations.size(); ++i) {
+ QAbstractAnimation *animation = d->animations.at(i);
const int dura = animation->totalDuration();
if (dura == -1 && d->isUncontrolledAnimationFinished(animation))
continue;
@@ -200,17 +202,18 @@ void QParallelAnimationGroup::updateState(QAbstractAnimation::State oldState,
switch (newState) {
case Stopped:
- foreach (QAbstractAnimation *animation, d->animations)
- animation->stop();
+ for (int i = 0; i < d->animations.size(); ++i)
+ d->animations.at(i)->stop();
d->disconnectUncontrolledAnimations();
break;
case Paused:
- foreach (QAbstractAnimation *animation, d->animations)
- animation->pause();
+ for (int i = 0; i < d->animations.size(); ++i)
+ d->animations.at(i)->pause();
break;
case Running:
d->connectUncontrolledAnimations();
- foreach (QAbstractAnimation *animation, d->animations) {
+ for (int i = 0; i < d->animations.size(); ++i) {
+ QAbstractAnimation *animation = d->animations.at(i);
animation->stop();
animation->setDirection(d->direction);
animation->start();
@@ -243,8 +246,8 @@ void QParallelAnimationGroupPrivate::_q_uncontrolledAnimationFinished()
return;
int maxDuration = 0;
- foreach (QAbstractAnimation *a, animations)
- maxDuration = qMax(maxDuration, a->totalDuration());
+ for (int i = 0; i < animations.size(); ++i)
+ maxDuration = qMax(maxDuration, animations.at(i)->totalDuration());
if (currentTime >= maxDuration)
q->stop();
@@ -267,7 +270,8 @@ void QParallelAnimationGroupPrivate::connectUncontrolledAnimations()
{
Q_Q(QParallelAnimationGroup);
- foreach (QAbstractAnimation *animation, animations) {
+ for (int i = 0; i < animations.size(); ++i) {
+ QAbstractAnimation *animation = animations.at(i);
if (animation->duration() == -1 || animation->loopCount() < 0) {
uncontrolledFinishTime[animation] = -1;
QObject::connect(animation, SIGNAL(finished()), q, SLOT(_q_uncontrolledAnimationFinished()));
@@ -288,8 +292,9 @@ void QParallelAnimationGroup::updateDirection(QAbstractAnimation::Direction dire
Q_D(QParallelAnimationGroup);
//we need to update the direction of the current animation
if (state() != Stopped) {
- foreach(QAbstractAnimation *anim, d->animations) {
- anim->setDirection(direction);
+ for (int i = 0; i < d->animations.size(); ++i) {
+ QAbstractAnimation *animation = d->animations.at(i);
+ animation->setDirection(direction);
}
} else {
if (direction == Forward) {
diff --git a/src/corelib/codecs/qisciicodec.cpp b/src/corelib/codecs/qisciicodec.cpp
index dd2bc8d..de1e477 100644
--- a/src/corelib/codecs/qisciicodec.cpp
+++ b/src/corelib/codecs/qisciicodec.cpp
@@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE
struct Codecs {
- const char *name;
+ const char name[10];
ushort base;
};
diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri
index 8f37e25..5033b21 100644
--- a/src/corelib/io/io.pri
+++ b/src/corelib/io/io.pri
@@ -10,6 +10,7 @@ HEADERS += \
io/qdiriterator.h \
io/qfile.h \
io/qfileinfo.h \
+ io/qfileinfo_p.h \
io/qiodevice.h \
io/qiodevice_p.h \
io/qnoncontiguousbytedevice_p.h \
diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp
index 36b1ed8..4f1b943 100644
--- a/src/corelib/io/qfileinfo.cpp
+++ b/src/corelib/io/qfileinfo.cpp
@@ -48,73 +48,10 @@
#include "qatomic.h"
#include "qhash.h"
#include "qdir.h"
+#include "qfileinfo_p.h"
QT_BEGIN_NAMESPACE
-class QFileInfoPrivate
-{
-public:
- QFileInfoPrivate(const QFileInfo *copy=0);
- ~QFileInfoPrivate();
-
- void initFileEngine(const QString &);
-
- enum Access {
- ReadAccess,
- WriteAccess,
- ExecuteAccess
- };
- bool hasAccess(Access access) const;
-
- uint getFileFlags(QAbstractFileEngine::FileFlags) const;
- QDateTime &getFileTime(QAbstractFileEngine::FileTime) const;
- QString getFileName(QAbstractFileEngine::FileName) const;
-
- enum { CachedFileFlags=0x01, CachedLinkTypeFlag=0x02, CachedBundleTypeFlag=0x04,
- CachedMTime=0x10, CachedCTime=0x20, CachedATime=0x40,
- CachedSize =0x08 };
- struct Data {
- inline Data()
- : ref(1), fileEngine(0), cache_enabled(1)
- { clear(); }
- inline Data(const Data &copy)
- : ref(1), fileEngine(QAbstractFileEngine::create(copy.fileName)),
- fileName(copy.fileName), cache_enabled(copy.cache_enabled)
- { clear(); }
- inline ~Data() { delete fileEngine; }
- inline void clearFlags() {
- fileFlags = 0;
- cachedFlags = 0;
- if (fileEngine)
- (void)fileEngine->fileFlags(QFSFileEngine::Refresh);
- }
- inline void clear() {
- fileNames.clear();
- clearFlags();
- }
- mutable QAtomicInt ref;
-
- QAbstractFileEngine *fileEngine;
- mutable QString fileName;
- mutable QHash<int, QString> fileNames;
-
- mutable uint cachedFlags : 31;
- mutable uint cache_enabled : 1;
- mutable uint fileFlags;
- mutable qint64 fileSize;
- mutable QDateTime fileTimes[3];
- inline bool getCachedFlag(uint c) const
- { return cache_enabled ? (cachedFlags & c) : 0; }
- inline void setCachedFlag(uint c)
- { if (cache_enabled) cachedFlags |= c; }
- } *data;
- inline void reset() {
- detach();
- data->clear();
- }
- void detach();
-};
-
QFileInfoPrivate::QFileInfoPrivate(const QFileInfo *copy)
{
if(copy) {
diff --git a/src/corelib/io/qfileinfo_p.h b/src/corelib/io/qfileinfo_p.h
new file mode 100644
index 0000000..8155bcb
--- /dev/null
+++ b/src/corelib/io/qfileinfo_p.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFILEINFO_P_H
+#define QFILEINFO_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 "qfileinfo.h"
+
+QT_BEGIN_NAMESPACE
+
+class QFileInfoPrivate
+{
+public:
+ QFileInfoPrivate(const QFileInfo *copy=0);
+ ~QFileInfoPrivate();
+
+ void initFileEngine(const QString &);
+
+ enum Access {
+ ReadAccess,
+ WriteAccess,
+ ExecuteAccess
+ };
+ bool hasAccess(Access access) const;
+
+ uint getFileFlags(QAbstractFileEngine::FileFlags) const;
+ QDateTime &getFileTime(QAbstractFileEngine::FileTime) const;
+ QString getFileName(QAbstractFileEngine::FileName) const;
+
+ enum { CachedFileFlags=0x01, CachedLinkTypeFlag=0x02, CachedBundleTypeFlag=0x04,
+ CachedMTime=0x10, CachedCTime=0x20, CachedATime=0x40,
+ CachedSize =0x08 };
+ struct Data {
+ inline Data()
+ : ref(1), fileEngine(0), cache_enabled(1)
+ { clear(); }
+ inline Data(const Data &copy)
+ : ref(1), fileEngine(QAbstractFileEngine::create(copy.fileName)),
+ fileName(copy.fileName), cache_enabled(copy.cache_enabled)
+ { clear(); }
+ inline ~Data() { delete fileEngine; }
+ inline void clearFlags() {
+ fileFlags = 0;
+ cachedFlags = 0;
+ if (fileEngine)
+ (void)fileEngine->fileFlags(QFSFileEngine::Refresh);
+ }
+ inline void clear() {
+ fileNames.clear();
+ clearFlags();
+ }
+ mutable QAtomicInt ref;
+
+ QAbstractFileEngine *fileEngine;
+ mutable QString fileName;
+ mutable QHash<int, QString> fileNames;
+
+ mutable uint cachedFlags : 31;
+ mutable uint cache_enabled : 1;
+ mutable uint fileFlags;
+ mutable qint64 fileSize;
+ mutable QDateTime fileTimes[3];
+ inline bool getCachedFlag(uint c) const
+ { return cache_enabled ? (cachedFlags & c) : 0; }
+ inline void setCachedFlag(uint c)
+ { if (cache_enabled) cachedFlags |= c; }
+ } *data;
+ inline void reset() {
+ detach();
+ data->clear();
+ }
+ void detach();
+};
+
+QT_END_NAMESPACE
+
+#endif // QFILEINFO_P_H
diff --git a/src/corelib/kernel/qabstractitemmodel.cpp b/src/corelib/kernel/qabstractitemmodel.cpp
index dd4f3f3..e57ca33 100644
--- a/src/corelib/kernel/qabstractitemmodel.cpp
+++ b/src/corelib/kernel/qabstractitemmodel.cpp
@@ -482,6 +482,37 @@ const QHash<int,QByteArray> &QAbstractItemModelPrivate::defaultRoleNames()
return roleNames;
}
+/*!
+ \internal
+ return true if \a value contains a numerical type
+
+ This function is used by our Q{Tree,Widget,Table}WidgetModel classes to sort.
+ We cannot rely on QVariant::canConvert because this would take strings as double
+ and then not sort strings correctly
+*/
+bool QAbstractItemModelPrivate::canConvertToDouble(const QVariant &value)
+{
+ switch (value.userType()) {
+ case QVariant::Bool:
+ case QVariant::Int:
+ case QVariant::UInt:
+ case QVariant::LongLong:
+ case QVariant::ULongLong:
+ case QVariant::Double:
+ case QVariant::Char:
+ case QMetaType::Float:
+ case QMetaType::Short:
+ case QMetaType::UShort:
+ case QMetaType::UChar:
+ case QMetaType::ULong:
+ case QMetaType::Long:
+ return true;
+ default:
+ return false;
+ }
+ return false;
+}
+
void QAbstractItemModelPrivate::removePersistentIndexData(QPersistentModelIndexData *data)
{
if (data->index.isValid()) {
diff --git a/src/corelib/kernel/qabstractitemmodel_p.h b/src/corelib/kernel/qabstractitemmodel_p.h
index fb42e77..b7325e3 100644
--- a/src/corelib/kernel/qabstractitemmodel_p.h
+++ b/src/corelib/kernel/qabstractitemmodel_p.h
@@ -89,6 +89,7 @@ public:
void columnsAboutToBeRemoved(const QModelIndex &parent, int first, int last);
void columnsRemoved(const QModelIndex &parent, int first, int last);
static QAbstractItemModel *staticEmptyModel();
+ static bool canConvertToDouble(const QVariant &value);
inline QModelIndex createIndex(int row, int column, void *data = 0) const {
return q_func()->createIndex(row, column, data);
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index a5f569b..de2db43 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -123,7 +123,7 @@ extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *)
}
QObjectPrivate::QObjectPrivate(int version)
- : threadData(0), currentSender(0), currentChildBeingDeleted(0), connectionLists(0)
+ : threadData(0), currentSender(0), currentChildBeingDeleted(0), connectionLists(0), senders(0)
{
if (version != QObjectPrivateVersion)
qFatal("Cannot mix incompatible Qt libraries");
@@ -144,6 +144,7 @@ QObjectPrivate::QObjectPrivate(int version)
inThreadChangeEvent = false;
deleteWatch = 0;
metaObject = 0;
+ hasGuards = false;
}
QObjectPrivate::~QObjectPrivate()
@@ -289,8 +290,8 @@ QObjectList QObjectPrivate::senderList() const
{
QObjectList returnValue;
QMutexLocker locker(signalSlotLock(q_func()));
- for (int i = 0; i < senders.count(); ++i)
- returnValue << senders.at(i)->sender;
+ for (Connection *c = senders; c; c = c->next)
+ returnValue << c->sender;
return returnValue;
}
@@ -361,6 +362,7 @@ void QMetaObject::addGuard(QObject **ptr)
return;
}
QMutexLocker locker(guardHashLock());
+ QObjectPrivate::get(*ptr)->hasGuards = true;
hash->insert(*ptr, ptr);
}
@@ -376,12 +378,17 @@ void QMetaObject::removeGuard(QObject **ptr)
QMutexLocker locker(guardHashLock());
GuardHash::iterator it = hash->find(*ptr);
const GuardHash::iterator end = hash->end();
+ bool more = false; //if the QObject has more pointer attached to it.
for (; it.key() == *ptr && it != end; ++it) {
if (it.value() == ptr) {
- (void) hash->erase(it);
+ it = hash->erase(it);
+ if (!more) more = (it != end && it.key() == *ptr);
break;
}
+ more = true;
}
+ if (!more)
+ QObjectPrivate::get(*ptr)->hasGuards = false;
}
/*!\internal
@@ -395,24 +402,33 @@ void QMetaObject::changeGuard(QObject **ptr, QObject *o)
}
QMutexLocker locker(guardHashLock());
if (*ptr) {
+ bool more = false; //if the QObject has more pointer attached to it.
GuardHash::iterator it = hash->find(*ptr);
const GuardHash::iterator end = hash->end();
for (; it.key() == *ptr && it != end; ++it) {
if (it.value() == ptr) {
- (void) hash->erase(it);
+ it = hash->erase(it);
+ if (!more) more = (it != end && it.key() == *ptr);
break;
}
+ more = true;
}
+ if (!more)
+ QObjectPrivate::get(*ptr)->hasGuards = false;
}
*ptr = o;
- if (*ptr)
+ if (*ptr) {
hash->insert(*ptr, ptr);
+ QObjectPrivate::get(*ptr)->hasGuards = true;
+ }
}
/*! \internal
*/
void QObjectPrivate::clearGuards(QObject *object)
{
+ if (!QObjectPrivate::get(object)->hasGuards)
+ return;
GuardHash *hash = guardHash();
if (hash) {
QMutexLocker locker(guardHashLock());
@@ -758,8 +774,10 @@ QObject::~QObject()
QMutex *m = signalSlotLock(c->receiver);
bool needToUnlock = QOrderedMutexLocker::relock(locker.mutex(), m);
c = connectionList[i];
- if (c->receiver)
- c->receiver->d_func()->senders.removeOne(c);
+ if (c->receiver) {
+ *c->prev = c->next;
+ if (c->next) c->next->prev = c->prev;
+ }
if (needToUnlock)
m->unlock();
@@ -776,29 +794,25 @@ QObject::~QObject()
}
// disconnect all senders
- for (int i = 0; i < d->senders.count(); ) {
- QObjectPrivate::Connection *s = d->senders[i];
-
- QMutex *m = signalSlotLock(s->sender);
+ QObjectPrivate::Connection *node = d->senders;
+ while (node) {
+ QMutex *m = signalSlotLock(node->sender);
+ node->prev = &node;
bool needToUnlock = QOrderedMutexLocker::relock(locker.mutex(), m);
- if (m < locker.mutex()) {
- if (i >= d->senders.count() || s != d->senders[i]) {
- if (needToUnlock)
- m->unlock();
- continue;
- }
+ //the node has maybe been removed while the mutex was unlocked in relock?
+ if (!node || signalSlotLock(node->sender) != m) {
+ m->unlock();
+ continue;
}
- s->receiver = 0;
- QObjectConnectionListVector *senderLists = s->sender->d_func()->connectionLists;
+ node->receiver = 0;
+ QObjectConnectionListVector *senderLists = node->sender->d_func()->connectionLists;
if (senderLists)
senderLists->dirty = true;
if (needToUnlock)
m->unlock();
- ++i;
+ node = node->next;
}
-
- d->senders.clear();
}
if (d->pendTimer) {
@@ -2291,8 +2305,8 @@ QObject *QObject::sender() const
// Return 0 if d->currentSender isn't in d->senders
bool found = false;
- for (int i = 0; !found && i < d->senders.count(); ++i)
- found = (d->senders.at(i)->sender == d->currentSender->sender);
+ for (QObjectPrivate::Connection *c = d->senders; c && !found; c = c->next)
+ found = (c->sender == d->currentSender->sender);
if (!found)
return 0;
return d->currentSender->sender;
@@ -2809,9 +2823,13 @@ bool QMetaObject::connect(const QObject *sender, int signal_index,
c->method = method_index;
c->connectionType = type;
c->argumentTypes = types;
+ c->prev = &r->d_func()->senders;
+ c->next = *c->prev;
+ *c->prev = c;
+ if (c->next)
+ c->next->prev = &c->next;
s->d_func()->addConnection(signal_index, c);
- r->d_func()->senders.append(c);
if (signal_index < 0)
sender->d_func()->connectedSignals = ~0u;
@@ -2861,8 +2879,10 @@ bool QMetaObject::disconnect(const QObject *sender, int signal_index,
needToUnlock = QOrderedMutexLocker::relock(senderMutex, m);
c = connectionList[i];
}
- if (c->receiver)
- c->receiver->d_func()->senders.removeOne(c);
+ if (c->receiver) {
+ *c->prev = c->next;
+ if (c->next) c->next->prev = c->prev;
+ }
if (needToUnlock)
m->unlock();
@@ -2888,8 +2908,10 @@ bool QMetaObject::disconnect(const QObject *sender, int signal_index,
needToUnlock = QOrderedMutexLocker::relock(senderMutex, m);
c = connectionList[i];
}
- if (c->receiver)
- c->receiver->d_func()->senders.removeOne(c);
+ if (c->receiver) {
+ *c->prev = c->next;
+ if (c->next) c->next->prev = c->prev;
+ }
if (needToUnlock)
m->unlock();
@@ -3427,9 +3449,8 @@ void QObject::dumpObjectInfo()
// now look for connections where this object is the receiver
qDebug(" SIGNALS IN");
- if (!d->senders.isEmpty()) {
- for (int i = 0; i < d->senders.count(); ++i) {
- const QObjectPrivate::Connection *s = d->senders.at(i);
+ if (d->senders) {
+ for (QObjectPrivate::Connection *s = d->senders; s; s = s->next) {
const QMetaMethod slot = metaObject()->method(s->method);
qDebug(" <-- %s::%s %s",
s->sender->metaObject()->className(),
@@ -3437,7 +3458,7 @@ void QObject::dumpObjectInfo()
slot.signature());
}
} else {
- qDebug(" <None>");
+ qDebug(" <None>");
}
#endif
}
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index b6bdfb3..a386564 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -106,7 +106,8 @@ public:
uint receiveChildEvents : 1;
uint inEventHandler : 1;
uint inThreadChangeEvent : 1;
- uint unused : 23;
+ uint hasGuards : 1; //true iff there is one or more QPointer attached to this object
+ uint unused : 22;
int postedEvents;
QMetaObject *metaObject; // assert dynamic
};
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index bc7995c..172853f 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -162,6 +162,9 @@ public:
int method;
uint connectionType : 3; // 0 == auto, 1 == direct, 2 == queued, 4 == blocking
QBasicAtomicPointer<int> argumentTypes;
+ //senders linked list
+ Connection *next;
+ Connection **prev;
~Connection();
};
typedef QList<Connection *> ConnectionList;
@@ -170,7 +173,7 @@ public:
void addConnection(int signal, Connection *c);
void cleanConnectionLists();
- ConnectionList senders;
+ Connection *senders; //linked list;
static Sender *setCurrentSender(QObject *receiver,
Sender *sender);
diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp
index 8ca53b9..29bdf7e 100644
--- a/src/corelib/kernel/qtimer.cpp
+++ b/src/corelib/kernel/qtimer.cpp
@@ -251,7 +251,7 @@ void QTimer::stop()
/*!
- \reimp
+ \reimp
*/
void QTimer::timerEvent(QTimerEvent *e)
{
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 2ff9818..e6f1c48 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -1823,7 +1823,7 @@ QVariant::Type QVariant::nameToType(const char *name)
#ifndef QT_NO_DATASTREAM
enum { MapFromThreeCount = 35 };
-static const uint map_from_three[MapFromThreeCount] =
+static const ushort map_from_three[MapFromThreeCount] =
{
QVariant::Invalid,
QVariant::Map,
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index 00132d7..4898e10 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -772,7 +772,7 @@ QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const
Instead it can return a "Windows code". This maps windows codes to ISO country names. */
struct WindowsToISOListElt {
- int windows_code;
+ ushort windows_code;
char iso_name[6];
};
diff --git a/src/corelib/tools/qlocale_data_p.h b/src/corelib/tools/qlocale_data_p.h
index 37f59a4..e0eecf3 100644
--- a/src/corelib/tools/qlocale_data_p.h
+++ b/src/corelib/tools/qlocale_data_p.h
@@ -60,8 +60,8 @@ QT_BEGIN_NAMESPACE
*/
struct CountryLanguage
{
- quint32 languageId;
- quint32 countryId;
+ quint16 languageId;
+ quint16 countryId;
};
static const CountryLanguage ImperialMeasurementSystems[] = {
{ 31, 225 },
@@ -83,7 +83,7 @@ static const int ImperialMeasurementSystemsCount =
*/
-static const uint locale_index[] = {
+static const quint16 locale_index[] = {
0, // unused
0, // C
0, // Abkhazian
@@ -2313,7 +2313,7 @@ static const char language_name_list[] =
"Chewa\0"
;
-static const uint language_name_index[] = {
+static const quint16 language_name_index[] = {
0, // Unused
8, // C
10, // Abkhazian
@@ -2727,7 +2727,7 @@ static const char country_name_list[] =
"SerbiaAndMontenegro\0"
;
-static const uint country_name_index[] = {
+static const quint16 country_name_index[] = {
0, // AnyCountry
8, // Afghanistan
20, // Albania
diff --git a/src/corelib/tools/qstringbuilder.cpp b/src/corelib/tools/qstringbuilder.cpp
index 03d8160..740deb4 100644
--- a/src/corelib/tools/qstringbuilder.cpp
+++ b/src/corelib/tools/qstringbuilder.cpp
@@ -3,14 +3,14 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the $MODULE$ of the Qt Toolkit.
+** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
-** Commercial Usage
-** Licensees holding valid Qt Commercial licenses may use this file in
-** accordance with the Qt Commercial License Agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Nokia.
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h
index 2c31476..30a7c67 100644
--- a/src/corelib/tools/qstringbuilder.h
+++ b/src/corelib/tools/qstringbuilder.h
@@ -3,14 +3,14 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the $MODULE$ of the Qt Toolkit.
+** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
-** Commercial Usage
-** Licensees holding valid Qt Commercial licenses may use this file in
-** accordance with the Qt Commercial License Agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Nokia.
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp
index 5e1fec3..fddcecf 100644
--- a/src/corelib/xml/qxmlstream.cpp
+++ b/src/corelib/xml/qxmlstream.cpp
@@ -629,7 +629,7 @@ while (<STDIN>) {
$sizes[$i++] = $counter;
$counter += length 1 + $_;
}
-print " \"\\0\";\n\nstatic const int QXmlStreamReader_tokenTypeString_indices[] = {\n ";
+print " \"\\0\";\n\nstatic const short QXmlStreamReader_tokenTypeString_indices[] = {\n ";
for ($j = 0; $j < $i; ++$j) {
printf "$sizes[$j], ";
}
@@ -660,10 +660,9 @@ static const char QXmlStreamReader_tokenTypeString_string[] =
"Comment\0"
"DTD\0"
"EntityReference\0"
- "ProcessingInstruction\0"
- "\0";
+ "ProcessingInstruction\0";
-static const int QXmlStreamReader_tokenTypeString_indices[] = {
+static const short QXmlStreamReader_tokenTypeString_indices[] = {
0, 8, 16, 30, 42, 55, 66, 77, 85, 89, 105, 0
};
diff --git a/src/declarative/canvas/qsimplecanvas.cpp b/src/declarative/canvas/qsimplecanvas.cpp
index e582226..cb46f94 100644
--- a/src/declarative/canvas/qsimplecanvas.cpp
+++ b/src/declarative/canvas/qsimplecanvas.cpp
@@ -830,24 +830,25 @@ void QSimpleCanvas::queueUpdate()
void QSimpleCanvas::addDirty(QSimpleCanvasItem *c)
{
+ Q_ASSERT(d->isSimpleCanvas());
queueUpdate();
- if (d->isSimpleCanvas()) {
- d->oldDirty |= c->d_func()->data()->lastPaintRect;
+ d->oldDirty |= c->d_func()->data()->lastPaintRect;
#if defined(QFX_RENDER_OPENGL)
- // Check for filters
- QSimpleCanvasItem *fi = c->parent();
- while(fi) {
- if (fi->d_func()->data()->dirty) {
- break;
- } else if (fi->filter()) {
- fi->update();
- break;
- }
- fi = fi->parent();
+ // ### Is this parent crawl going to be a problem for scenes with nots
+ // of things changing?
+ // Check for filters
+ QSimpleCanvasItem *fi = c->parent();
+ while(fi) {
+ if (fi->d_func()->data()->dirty) {
+ break;
+ } else if (fi->filter()) {
+ fi->update();
+ break;
}
-#endif
- d->dirtyItems.append(c);
+ fi = fi->parent();
}
+#endif
+ d->dirtyItems.append(c);
}
QRect QSimpleCanvasPrivate::dirtyItemClip() const
@@ -867,7 +868,7 @@ QRect QSimpleCanvasPrivate::dirtyItemClip() const
return rv;
}
-QRegion QSimpleCanvasPrivate::resetDirty()
+QRect QSimpleCanvasPrivate::resetDirty()
{
if (isSimpleCanvas()) {
#if defined(QFX_RENDER_OPENGL)
@@ -883,11 +884,11 @@ QRegion QSimpleCanvasPrivate::resetDirty()
oldDirty = QRect();
if (fullUpdate())
- return QRegion();
+ return QRect();
else
- return QRegion(r);
+ return r;
} else {
- return QRegion();
+ return QRect();
}
}
@@ -914,19 +915,23 @@ QSimpleCanvasItem *QSimpleCanvas::focusItem(QSimpleCanvasItem *item) const
bool QSimpleCanvas::event(QEvent *e)
{
if (e->type() == QEvent::User && d->isSimpleCanvas()) {
+ int tbf = d->frameTimer.restart();
d->timer = 0;
d->isSetup = true;
#if defined(QFX_RENDER_OPENGL1)
unsigned int zero = 0;
d->root->d_func()->setupPainting(0, rect(), &zero);
+#elif defined(QFX_RENDER_OPENGL2)
+ ++d->paintVersion;
+ d->opaqueList = 0;
+ int z = 0;
+ d->root->d_func()->setupPainting(0, z, &d->opaqueList);
#else
++d->paintVersion;
d->root->d_func()->setupPainting(0, rect());
#endif
- QRegion r = d->resetDirty();
-
- int tbf = d->frameTimer.restart();
+ QRect r = d->resetDirty();
#if defined(QFX_RENDER_QPAINTER)
if (r.isEmpty() || fullUpdate())
@@ -935,12 +940,12 @@ bool QSimpleCanvas::event(QEvent *e)
repaint(r);
emit framePainted();
#else
- QRect br = r.boundingRect();
- QRect nr(br.x(), height() - br.y() - br.height(), br.width(), br.height());
+
+ QRect nr(r.x(), height() - r.y() - r.height(), r.width(), r.height());
if (r.isEmpty() || fullUpdate())
d->egl.updateGL();
- else
+ else
d->egl.updateGL(nr);
emit framePainted();
#endif
diff --git a/src/declarative/canvas/qsimplecanvas_opengl.cpp b/src/declarative/canvas/qsimplecanvas_opengl.cpp
index ec809ff..7969a2a 100644
--- a/src/declarative/canvas/qsimplecanvas_opengl.cpp
+++ b/src/declarative/canvas/qsimplecanvas_opengl.cpp
@@ -52,8 +52,8 @@
QT_BEGIN_NAMESPACE
void CanvasEGLWidget::paintGL()
{
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_canvas->paintGL();
}
@@ -112,13 +112,37 @@ void QSimpleCanvasPrivate::paintGL()
lrpTimer.start();
QSimpleCanvasItemPrivate::GLPaintParameters p;
+ QSimpleCanvasItem::GLPainter painter;
+
p.sceneRect = QRect(0, 0, q->width(), q->height());
p.clipRect = p.sceneRect;
p.stencilValue = 0;
p.opacity = 1;
p.forceParamRefresh = false;
- if (!isSetup)
- root->d_func()->setupPainting(0, QRect());
+ p.painter = &painter;
+ if (!isSetup) {
+ opaqueList = 0;
+ int z = 0;
+ root->d_func()->setupPainting(0, z, &opaqueList);
+ }
+
+ glEnable(GL_DEPTH_TEST);
+
+ glDisable(GL_BLEND);
+ painter.blendEnabled = false;
+ painter.activeOpacity = 1;
+ while (opaqueList) {
+ painter.item = opaqueList;
+ painter.activeTransform = opaqueList->d_func()->data()->transformActive;
+ // ### - I don't think this is right
+ painter.sceneClipRect = p.clipRect;
+
+ opaqueList->paintGLContents(painter);
+ opaqueList = opaqueList->d_func()->nextOpaque;
+ }
+ glEnable(GL_BLEND);
+ painter.blendEnabled = true;
+
root->d_func()->paint(p);
lrpTime = lrpTimer.elapsed();
@@ -195,7 +219,8 @@ void QSimpleCanvasItemPrivate::simplePaintChild(const GLPaintParameters &params,
childParams.boundingRect = child->boundingRect();
if (child->filter() && child->filter()->enabled()) {
- QSimpleCanvasItem::GLPainter painter(q);
+ QSimpleCanvasItem::GLPainter &painter = *params.painter;
+ painter.item = q;
painter.activeTransform = child->d_func()->data()->transformActive;
painter.activeOpacity = child->d_func()->data()->activeOpacity;
painter.sceneClipRect = params.clipRect;
@@ -229,34 +254,35 @@ void QSimpleCanvasItemPrivate::setupChildState(QSimpleCanvasItem *child)
QSimpleCanvasItemData *const childData = childPrivate->data();
childData->activeOpacity = myData->activeOpacity;
- if (childData->visible != 1)
+ if (childData->visible != 1.)
childData->activeOpacity *= childData->visible;
- if (childData->activeOpacity != 0) {
+ if (childData->activeOpacity != 0.) {
+ QSimpleCanvas::Matrix &am = childData->transformActive;
+ am = myData->transformActive;
+
// Calculate child's transform
const qreal x = childData->x;
const qreal y = childData->y;
const qreal scale = childPrivate->scale;
QSimpleCanvasItem::Flip flip = childData->flip;
- QSimpleCanvas::Matrix &am = childData->transformActive;
- am = myData->transformActive;
if (x != 0. || y != 0.)
am.translate(x, y);
if (scale != 1.) {
- QPointF to = childPrivate->transformOrigin();
- bool translate = (to.x() != 0. || to.y() != 0.);
- if (translate)
+ if (childPrivate->origin == QSimpleCanvasItem::TopLeft) {
+ am.scale(scale, scale);
+ } else {
+ QPointF to = childPrivate->transformOrigin();
am.translate(to.x(), to.y());
- am.scale(scale, scale);
- if (translate)
+ am.scale(scale, scale);
am.translate(-to.x(), -to.y());
+ }
}
if (childData->transformUser)
am *= *childData->transformUser;
-
if (flip) {
QRectF br = child->boundingRect();
am.translate(br.width() / 2., br.height() / 2);
@@ -268,8 +294,10 @@ void QSimpleCanvasItemPrivate::setupChildState(QSimpleCanvasItem *child)
}
}
-QRectF QSimpleCanvasItemPrivate::setupPainting(int version, const QRect &bounding)
+#define QSIMPLECANVAS_DISABLE_TREE_CLIPPING
+QRectF QSimpleCanvasItemPrivate::setupPainting(int version, int &z, QSimpleCanvasItem **opaqueList)
{
+ static QRectF scene(-1., -1., 2., 2.);
Q_Q(QSimpleCanvasItem);
bool hasContents = options & QSimpleCanvasItem::HasContents;
@@ -285,20 +313,55 @@ QRectF QSimpleCanvasItemPrivate::setupPainting(int version, const QRect &boundin
rv = active.mapRect(filteredBoundRect);
}
+#ifdef QSIMPLECANVAS_DISABLE_TREE_CLIPPING
+ myData->doNotPaint = false;
+ myData->doNotPaintChildren = false;
+#else
+ myData->doNotPaint = !hasContents || !rv.intersects(scene);
+ myData->doNotPaintChildren = hasContents && myData->doNotPaint &&
+ (clip != QSimpleCanvasItem::NoClip);
+#endif
+
+ if (!myData->doNotPaint &&
+ (options & QSimpleCanvasItem::IsOpaque) &&
+ (myData->activeOpacity == 1.) &&
+ (clip == 0)) {
+
+ nextOpaque = *opaqueList;
+ *opaqueList = q;
+ myData->doNotPaint = true;
- for (int ii = 0; ii < children.count(); ++ii) {
- QSimpleCanvasItem *child = children.at(ii);
- setupChildState(child);
+ }
- QSimpleCanvasItemData *childData = child->d_func()->data();
- if (childData->activeOpacity != 0)
- rv |= child->d_func()->setupPainting(version, bounding);
- }
+ int myZ = z++;
+
+ if (myData->doNotPaintChildren) {
+ rv = QRectF();
+ } else {
+ zOrderChildren();
+
+ for (int ii = 0; ii < children.count(); ++ii) {
+ QSimpleCanvasItem *child = children.at(ii);
+ setupChildState(child);
+
+ QSimpleCanvasItemData *childData = child->d_func()->data();
+ if (childData->activeOpacity != 0)
+ rv |= child->d_func()->setupPainting(version, z, opaqueList);
+ }
+
+#ifndef QSIMPLECANVAS_DISABLE_TREE_CLIPPING
+ myData->doNotPaintChildren |= !rv.intersects(scene);
+#endif
+ }
+
+ myData->transformActive.translate(0, 0, myZ);
myData->lastPaintRect = rv;
+
return rv;
}
+
void QSimpleCanvasItemPrivate::paint(GLPaintParameters &oldParams, QSimpleCanvasFilter::Layer layer)
{
if (!layer)
@@ -306,6 +369,10 @@ void QSimpleCanvasItemPrivate::paint(GLPaintParameters &oldParams, QSimpleCanvas
Q_Q(QSimpleCanvasItem);
+ bool doNotPaintChildren = data()->doNotPaintChildren;
+ if (doNotPaintChildren)
+ return;
+
GLPaintParameters params = oldParams;
qreal width = params.boundingRect.width();
@@ -327,12 +394,12 @@ void QSimpleCanvasItemPrivate::paint(GLPaintParameters &oldParams, QSimpleCanvas
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
ConstantColorShader *shader = basicShaders()->constantColor();
+ params.painter->invalidate();
shader->enable();
shader->setTransform(data()->transformActive);
shader->setAttributeArray(ConstantColorShader::Vertices, vertices, 2);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- shader->disableAttributeArray(ConstantColorShader::Vertices);
glStencilFunc(GL_EQUAL, params.stencilValue + 1, 0xFFFFFFFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
@@ -356,8 +423,6 @@ void QSimpleCanvasItemPrivate::paint(GLPaintParameters &oldParams, QSimpleCanvas
params.clipRect = sr;
}
- zOrderChildren();
-
int upto = 0;
for (upto = 0; upto < children.count(); ++upto) {
QSimpleCanvasItem *c = children.at(upto);
@@ -369,9 +434,11 @@ void QSimpleCanvasItemPrivate::paint(GLPaintParameters &oldParams, QSimpleCanvas
}
}
- if (layer & QSimpleCanvasFilter::Item &&
- q->options() & QSimpleCanvasItem::HasContents) {
- QSimpleCanvasItem::GLPainter painter(q);
+ bool doNotPaint = data()->doNotPaint;
+
+ if (!doNotPaint && layer & QSimpleCanvasFilter::Item) {
+ QSimpleCanvasItem::GLPainter &painter = *params.painter;
+ painter.item = q;
painter.activeTransform = data()->transformActive;
painter.activeOpacity = data()->activeOpacity;
painter.sceneClipRect = params.clipRect;
@@ -390,14 +457,14 @@ void QSimpleCanvasItemPrivate::paint(GLPaintParameters &oldParams, QSimpleCanvas
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glStencilFunc(GL_EQUAL, params.stencilValue + 1, 0xFFFFFFFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
-
+
+ params.painter->invalidate();
ConstantColorShader *shader = basicShaders()->constantColor();
shader->enable();
shader->setTransform(data()->transformActive);
shader->setAttributeArray(ConstantColorShader::Vertices, vertices, 2);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- shader->disableAttributeArray(ConstantColorShader::Vertices);
glStencilFunc(GL_EQUAL, params.stencilValue, 0xFFFFFFFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
@@ -405,43 +472,76 @@ void QSimpleCanvasItemPrivate::paint(GLPaintParameters &oldParams, QSimpleCanvas
}
}
+enum ShaderType { ST_None, ST_SingleTexture, ST_SingleTextureOpacity, ST_Color };
+
+QSimpleCanvasItem::GLPainter::GLPainter()
+: item(0), activeOpacity(1), blendEnabled(true), flags(0)
+{
+}
+
+QSimpleCanvasItem::GLPainter::GLPainter(QSimpleCanvasItem *i)
+: item(i), activeOpacity(1), blendEnabled(true), flags(0)
+{
+}
+
QGLShaderProgram *QSimpleCanvasItem::GLPainter::useTextureShader()
{
if (activeOpacity == 1.) {
- item->basicShaders()->singleTexture()->enable();
- item->basicShaders()->singleTexture()->setTransform(activeTransform);
- return item->basicShaders()->singleTexture();
+ SingleTextureShader *shader = item->basicShaders()->singleTexture();
+ if (flags != ST_SingleTexture) {
+ shader->enable();
+ flags = ST_SingleTexture;
+ }
+
+ shader->setTransform(activeTransform);
+ return shader;
} else {
- item->basicShaders()->singleTextureOpacity()->enable();
- item->basicShaders()->singleTextureOpacity()->setTransform(activeTransform);
- item->basicShaders()->singleTextureOpacity()->setOpacity(activeOpacity);
- return item->basicShaders()->singleTextureOpacity();
+ SingleTextureOpacityShader *shader = item->basicShaders()->singleTextureOpacity();
+
+ if (flags != ST_SingleTextureOpacity) {
+ shader->enable();
+ flags = ST_SingleTextureOpacity;
+ }
+
+ shader->setTransform(activeTransform);
+ shader->setOpacity(activeOpacity);
+ return shader;
}
+}
+void QSimpleCanvasItem::GLPainter::invalidate()
+{
+ flags = ST_None;
}
QGLShaderProgram *QSimpleCanvasItem::GLPainter::useColorShader(const QColor &color)
{
- QColor c = color;
- item->basicShaders()->constantColor()->enable();
- if (activeOpacity != 1.) {
- c.setAlpha(int(c.alpha() * activeOpacity));
+ QColor c = color;
+
+ ConstantColorShader *shader = item->basicShaders()->constantColor();
+
+ if (flags != ST_Color) {
+ shader->enable();
+ flags = ST_Color;
}
- item->basicShaders()->constantColor()->setColor(c);
- item->basicShaders()->constantColor()->setTransform(activeTransform);
+ if (activeOpacity != 1.)
+ c.setAlpha(int(c.alpha() * activeOpacity));
+
+ shader->setColor(c);
+ shader->setTransform(activeTransform);
- return item->basicShaders()->constantColor();
+ return shader;
}
-void QSimpleCanvasItem::GLPainter::drawPixmap(const QPointF &point,
- const GLTexture &texture)
+void QSimpleCanvasItem::GLPainter::drawPixmap(const QPointF &point,
+ const GLTexture &texture)
{
drawPixmap(QRectF(point, QSizeF(texture.width(), texture.height())), texture);
}
-void QSimpleCanvasItem::GLPainter::drawPixmap(const QRectF &rect,
- const GLTexture &img)
+void QSimpleCanvasItem::GLPainter::drawPixmap(const QRectF &rect,
+ const GLTexture &img)
{
QGLShaderProgram *shader = useTextureShader();
@@ -466,9 +566,115 @@ void QSimpleCanvasItem::GLPainter::drawPixmap(const QRectF &rect,
glBindTexture(GL_TEXTURE_2D, img.texture());
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+}
+
+void QSimpleCanvasItem::GLPainter::fillRect(const QRectF &rect,
+ const QColor &color)
+{
+ if (color.alpha() == 0xFF)
+ glDisable(GL_BLEND);
+
+ QGLShaderProgram *shader = useColorShader(color);
+ float x = rect.x();
+ float y = rect.y();
+ float width = rect.width();
+ float height = rect.height();
+
+ GLfloat vertices[] = { x, height,
+ width, height,
+ x, y,
+
+ width, height,
+ x, y,
+ width, y };
+
+ shader->setAttributeArray(ConstantColorShader::Vertices, vertices, 2);
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+
+ if (color.alpha() == 0xFF)
+ glEnable(GL_BLEND);
+}
+
+void QSimpleCanvasItem::CachedTexture::addRef()
+{
+ ++r;
+}
+
+void QSimpleCanvasItem::CachedTexture::release()
+{
+ Q_ASSERT(r > 0);
+ --r;
+
+ if (r == 0) {
+ if (!s.isEmpty())
+ d->cachedTextures.remove(s);
+ delete this;
+ }
+}
- shader->disableAttributeArray(SingleTextureShader::Vertices);
- shader->disableAttributeArray(SingleTextureShader::TextureCoords);
+int QSimpleCanvasItem::CachedTexture::pixmapWidth() const
+{
+ return w;
+}
+
+int QSimpleCanvasItem::CachedTexture::pixmapHeight() const
+{
+ return h;
+}
+
+QSimpleCanvasItem::CachedTexture::CachedTexture()
+: r(0), w(0), h(0)
+{
+}
+
+QSimpleCanvasItem::CachedTexture *
+QSimpleCanvasItem::cachedTexture(const QString &key)
+{
+ Q_D(QSimpleCanvasItem);
+ if (!d->canvas || key.isEmpty())
+ return 0;
+
+ QSimpleCanvasPrivate *canvas = d->canvas->d;
+ QHash<QString, QSimpleCanvasItem::CachedTexture *>::ConstIterator iter =
+ canvas->cachedTextures.find(key);
+ if (iter != canvas->cachedTextures.end()) {
+ (*iter)->addRef();
+ return (*iter);
+ } else {
+ return 0;
+ }
+}
+
+QSimpleCanvasItem::CachedTexture *
+QSimpleCanvasItem::cachedTexture(const QString &key, const QPixmap &pix)
+{
+ Q_D(QSimpleCanvasItem);
+ if (!d->canvas)
+ return 0;
+
+ QSimpleCanvasPrivate *canvas = d->canvas->d;
+ QHash<QString, QSimpleCanvasItem::CachedTexture *>::ConstIterator iter =
+ canvas->cachedTextures.end();
+ if (!key.isEmpty())
+ iter = canvas->cachedTextures.find(key);
+
+ if (iter != canvas->cachedTextures.end()) {
+ (*iter)->addRef();
+ return (*iter);
+ } else {
+ CachedTexture *rv = new CachedTexture;
+ rv->s = key;
+ rv->d = canvas;
+ rv->w = pix.width();
+ rv->h = pix.height();
+ rv->setImage(pix.toImage(), GLTexture::PowerOfTwo);
+ rv->setHorizontalWrap(GLTexture::Repeat);
+ rv->setVerticalWrap(GLTexture::Repeat);
+ rv->addRef();
+ if (!key.isEmpty())
+ canvas->cachedTextures.insert(key, rv);
+ return rv;
+ }
}
QT_END_NAMESPACE
diff --git a/src/declarative/canvas/qsimplecanvas_p.h b/src/declarative/canvas/qsimplecanvas_p.h
index d9ed4ac..3a0186e 100644
--- a/src/declarative/canvas/qsimplecanvas_p.h
+++ b/src/declarative/canvas/qsimplecanvas_p.h
@@ -43,6 +43,7 @@
#define QSIMPLECANVAS_P_H
#include "qsimplecanvas.h"
+#include "qsimplecanvasitem.h"
#include <qstack.h>
#include <qdatetime.h>
@@ -126,9 +127,10 @@ public:
#else
QRect oldDirty;
#endif
- QRegion resetDirty();
+ QRect resetDirty();
void paint(QPainter &p);
+ QSimpleCanvasItem *opaqueList;
int timer;
@@ -186,6 +188,8 @@ public:
}
mutable GLBasicShaders *basicShadersInstance;
+ QHash<QString, QSimpleCanvasItem::CachedTexture *> cachedTextures;
+
QList<QGLFramebufferObject *> frameBuffers;
QGLFramebufferObject *acquire(int, int);
void release(QGLFramebufferObject *);
diff --git a/src/declarative/canvas/qsimplecanvasitem.cpp b/src/declarative/canvas/qsimplecanvasitem.cpp
index f2222a9..cbdc324 100644
--- a/src/declarative/canvas/qsimplecanvasitem.cpp
+++ b/src/declarative/canvas/qsimplecanvasitem.cpp
@@ -51,8 +51,8 @@ QT_BEGIN_NAMESPACE
QSimpleCanvasItemData::QSimpleCanvasItemData()
: buttons(Qt::NoButton), flip(QSimpleCanvasItem::NoFlip),
dirty(false), transformValid(true), doNotPaint(false),
- doNotPaintChildren(false), x(0), y(0), z(0), visible(1),
- transformUser(0), transformVersion(0), activeOpacity(1)
+ doNotPaintChildren(false), x(0), y(0), z(0),
+ visible(1), transformUser(0), transformVersion(0), activeOpacity(1)
{
}
@@ -1300,6 +1300,9 @@ void QSimpleCanvasItem::setOptions(Options options, bool set)
d->options &= ~IsFocusRealm;
}
+ if (d->graphicsItem)
+ d->graphicsItem->setFlag(QGraphicsItem::ItemHasNoContents, !(d->options & HasContents));
+
if ((old & MouseFilter) != (d->options & MouseFilter)) {
if (d->graphicsItem) {
if (d->options & MouseFilter)
@@ -1487,6 +1490,7 @@ void QSimpleCanvasItemPrivate::convertToGraphicsItem(QGraphicsItem *parent)
Q_Q(QSimpleCanvasItem);
Q_ASSERT(!graphicsItem);
graphicsItem = new QSimpleGraphicsItem(q);
+ graphicsItem->setFlag(QGraphicsItem::ItemHasNoContents, !(q->options() & QSimpleCanvasItem::HasContents));
if (parent)
graphicsItem->setParentItem(parent);
diff --git a/src/declarative/canvas/qsimplecanvasitem.h b/src/declarative/canvas/qsimplecanvasitem.h
index f817799..dce3007 100644
--- a/src/declarative/canvas/qsimplecanvasitem.h
+++ b/src/declarative/canvas/qsimplecanvasitem.h
@@ -45,6 +45,9 @@
#include <QtDeclarative/qfxglobal.h>
#include <QtDeclarative/qmldebuggerstatus.h>
#include <QtDeclarative/qsimplecanvas.h>
+#if defined(QFX_RENDER_OPENGL)
+#include <QtDeclarative/gltexture.h>
+#endif
#include <QtCore/qobject.h>
#include <QtGui/qgraphicsitem.h>
@@ -90,7 +93,8 @@ public:
SimpleItem = 0x00000020,
IsFocusPanel = 0x00000040,
IsFocusRealm = 0x00000080,
- AcceptsInputMethods = 0x00000100};
+ AcceptsInputMethods = 0x00000100,
+ IsOpaque = 0x00000200 };
Q_DECLARE_FLAGS(Options, Option)
QSimpleCanvasItem(QSimpleCanvasItem *parent=0);
@@ -167,7 +171,8 @@ public:
class GLPainter
{
public:
- GLPainter(QSimpleCanvasItem *i) : item(i), activeOpacity(1) {}
+ GLPainter();
+ GLPainter(QSimpleCanvasItem *i);
QSimpleCanvasItem *item;
QSimpleCanvas::Matrix activeTransform;
qreal activeOpacity;
@@ -175,9 +180,16 @@ public:
QGLShaderProgram *useTextureShader();
QGLShaderProgram *useColorShader(const QColor &);
- void drawPixmap(const QPointF &, const GLTexture &);
- void drawPixmap(const QRectF &, const GLTexture &);
+ void drawPixmap(const QPointF &, const GLTexture &);
+ void drawPixmap(const QRectF &, const GLTexture &);
+ void fillRect(const QRectF &, const QColor &);
+
+ void invalidate();
+
+ bool blendEnabled;
+
private:
+ int flags;
GLPainter(const GLPainter &);
GLPainter &operator=(const GLPainter &);
};
@@ -227,6 +239,28 @@ public:
static QSimpleCanvasItem *findNextFocus(QSimpleCanvasItem *item);
GLBasicShaders *basicShaders() const;
+
+#if defined(QFX_RENDER_OPENGL)
+ class CachedTexture : public GLTexture
+ {
+ public:
+ void addRef();
+ void release();
+
+ int pixmapWidth() const;
+ int pixmapHeight() const;
+
+ private:
+ CachedTexture();
+ friend class QSimpleCanvasItem;
+ QSimpleCanvasPrivate *d;
+ QString s;
+ int r, w, h;
+ };
+
+ CachedTexture *cachedTexture(const QString &);
+ CachedTexture *cachedTexture(const QString &, const QPixmap &);
+#endif
static QPixmap string(const QString &, const QColor & = Qt::black, const QFont & = QFont());
diff --git a/src/declarative/canvas/qsimplecanvasitem_p.h b/src/declarative/canvas/qsimplecanvasitem_p.h
index e2deab2..6c21d9f 100644
--- a/src/declarative/canvas/qsimplecanvasitem_p.h
+++ b/src/declarative/canvas/qsimplecanvasitem_p.h
@@ -161,7 +161,7 @@ public:
QSimpleCanvasItem::ClipType clip:3;
QSimpleCanvasItem::TransformOrigin origin:4;
- int options:9;
+ int options:10;
bool focusable:1;
bool wantsActiveFocusPanelPendingCanvas:1;
bool hasBeenActiveFocusPanel:1;
@@ -218,9 +218,11 @@ public:
#endif
float opacity;
bool forceParamRefresh;
+
+ QSimpleCanvasItem::GLPainter *painter;
};
#if defined(QFX_RENDER_OPENGL2)
- QRectF setupPainting(int version, const QRect &bounding);
+ QRectF setupPainting(int version, int &z, QSimpleCanvasItem **);
#elif defined(QFX_RENDER_OPENGL1)
QRectF setupPainting(int version, const QRect &bounding, unsigned int *zero);
#endif
@@ -239,6 +241,8 @@ public:
#endif
+ QSimpleCanvasItem *nextOpaque;
+
void zOrderChildren();
bool freshenNeeded() const;
void doFreshenTransforms() const;
diff --git a/src/declarative/extra/qmlxmllistmodel.cpp b/src/declarative/extra/qmlxmllistmodel.cpp
index a7f5d72..62ede80 100644
--- a/src/declarative/extra/qmlxmllistmodel.cpp
+++ b/src/declarative/extra/qmlxmllistmodel.cpp
@@ -270,7 +270,7 @@ public:
, queryId(-1), roleObjects(this) {}
bool isClassComplete;
- QString src;
+ QUrl src;
QString query;
QString namespaces;
int size;
@@ -388,13 +388,13 @@ QString QmlXmlListModel::toString(int role) const
return d->roleNames.at(index);
}
-QString QmlXmlListModel::source() const
+QUrl QmlXmlListModel::source() const
{
Q_D(const QmlXmlListModel);
return d->src;
}
-void QmlXmlListModel::setSource(const QString &src)
+void QmlXmlListModel::setSource(const QUrl &src)
{
Q_D(QmlXmlListModel);
if (d->src != src) {
@@ -483,7 +483,7 @@ void QmlXmlListModel::reload()
emit progressChanged(d->progress);
emit statusChanged(d->status);
- QNetworkRequest req((QUrl(d->src)));
+ QNetworkRequest req(d->src);
req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
d->reply = qmlContext(this)->engine()->networkAccessManager()->get(req);
QObject::connect(d->reply, SIGNAL(finished()), this, SLOT(requestFinished()));
diff --git a/src/declarative/extra/qmlxmllistmodel.h b/src/declarative/extra/qmlxmllistmodel.h
index 052a0c2..bdbba47 100644
--- a/src/declarative/extra/qmlxmllistmodel.h
+++ b/src/declarative/extra/qmlxmllistmodel.h
@@ -93,7 +93,7 @@ class Q_DECLARATIVE_EXPORT QmlXmlListModel : public QListModelInterface, public
Q_PROPERTY(Status status READ status NOTIFY statusChanged)
Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged)
- Q_PROPERTY(QString source READ source WRITE setSource)
+ Q_PROPERTY(QUrl source READ source WRITE setSource)
Q_PROPERTY(QString query READ query WRITE setQuery)
Q_PROPERTY(QString namespaceDeclarations READ namespaceDeclarations WRITE setNamespaceDeclarations)
Q_PROPERTY(QmlList<XmlListModelRole *> *roles READ roleObjects)
@@ -109,8 +109,8 @@ public:
QmlList<XmlListModelRole *> *roleObjects();
- QString source() const;
- void setSource(const QString&);
+ QUrl source() const;
+ void setSource(const QUrl&);
QString query() const;
void setQuery(const QString&);
diff --git a/src/declarative/fx/qfxanimatedimageitem.cpp b/src/declarative/fx/qfxanimatedimageitem.cpp
index 029206b..604481c 100644
--- a/src/declarative/fx/qfxanimatedimageitem.cpp
+++ b/src/declarative/fx/qfxanimatedimageitem.cpp
@@ -155,7 +155,7 @@ int QFxAnimatedImageItem::frameCount() const
void QFxAnimatedImageItem::setSource(const QString &url)
{
Q_D(QFxAnimatedImageItem);
- if (url == d->source)
+ if (url == d->url)
return;
delete d->_movie;
@@ -166,8 +166,7 @@ void QFxAnimatedImageItem::setSource(const QString &url)
d->reply = 0;
}
- d->source = url;
- d->url = qmlContext(this)->resolvedUrl(url);
+ d->url = url;
if (url.isEmpty()) {
delete d->_movie;
diff --git a/src/declarative/fx/qfxblendedimage.cpp b/src/declarative/fx/qfxblendedimage.cpp
index 4c6eb58..e216196 100644
--- a/src/declarative/fx/qfxblendedimage.cpp
+++ b/src/declarative/fx/qfxblendedimage.cpp
@@ -84,9 +84,9 @@ QFxBlendedImage::QFxBlendedImage(QFxItem *parent)
\qmlproperty string BlendedImage::primaryUrl
The URL of the first image to be displayed in this item.
*/
-QString QFxBlendedImage::primaryUrl() const
+QUrl QFxBlendedImage::primaryUrl() const
{
- return primSrc;
+ return primUrl;
}
void QFxBlendedImage::primaryLoaded()
@@ -96,15 +96,15 @@ void QFxBlendedImage::primaryLoaded()
update();
}
-void QFxBlendedImage::setPrimaryUrl(const QString &url)
+void QFxBlendedImage::setPrimaryUrl(const QUrl &url)
{
- if (primSrc == url)
+ if (primUrl == url)
return;
- if (!primSrc.isEmpty())
+ if (!primUrl.isEmpty())
QFxPixmap::cancelGet(primUrl,this);
- primSrc = url;
- primUrl = qmlContext(this)->resolvedUrl(url);
- if (!primSrc.isEmpty())
+ Q_ASSERT(!url.isRelative());
+ primUrl = url;
+ if (!primUrl.isEmpty())
QFxPixmap::get(qmlEngine(this), primUrl,this,SLOT(primaryLoaded()));
}
@@ -112,9 +112,9 @@ void QFxBlendedImage::setPrimaryUrl(const QString &url)
\qmlproperty string BlendedImage::secondaryUrl
The URL of the second image to be displayed in this item.
*/
-QString QFxBlendedImage::secondaryUrl() const
+QUrl QFxBlendedImage::secondaryUrl() const
{
- return secSrc;
+ return secUrl;
}
void QFxBlendedImage::secondaryLoaded()
@@ -124,15 +124,15 @@ void QFxBlendedImage::secondaryLoaded()
update();
}
-void QFxBlendedImage::setSecondaryUrl(const QString &url)
+void QFxBlendedImage::setSecondaryUrl(const QUrl &url)
{
- if (secSrc == url)
+ if (secUrl == url)
return;
- if (!secSrc.isEmpty())
+ if (!secUrl.isEmpty())
QFxPixmap::cancelGet(secUrl,this);
- secSrc = url;
- secUrl = qmlContext(this)->resolvedUrl(url);
- if (!secSrc.isEmpty())
+ Q_ASSERT(!url.isRelative());
+ secUrl = url;
+ if (!secUrl.isEmpty())
QFxPixmap::get(qmlEngine(this), secUrl,this,SLOT(secondaryLoaded()));
}
@@ -183,7 +183,7 @@ void QFxBlendedImage::setSmoothTransform(bool s)
void QFxBlendedImage::paintContents(QPainter &p)
{
- if (primSrc.isNull() && secSrc.isNull())
+ if (primUrl.isEmpty() && secUrl.isEmpty())
return;
if (_smooth) {
diff --git a/src/declarative/fx/qfxblendedimage.h b/src/declarative/fx/qfxblendedimage.h
index baf4b64..7169b92 100644
--- a/src/declarative/fx/qfxblendedimage.h
+++ b/src/declarative/fx/qfxblendedimage.h
@@ -57,18 +57,18 @@ class Q_DECLARATIVE_EXPORT QFxBlendedImage : public QFxItem
{
Q_OBJECT
- Q_PROPERTY(QString primaryUrl READ primaryUrl WRITE setPrimaryUrl)
- Q_PROPERTY(QString secondaryUrl READ secondaryUrl WRITE setSecondaryUrl)
+ Q_PROPERTY(QUrl primaryUrl READ primaryUrl WRITE setPrimaryUrl)
+ Q_PROPERTY(QUrl secondaryUrl READ secondaryUrl WRITE setSecondaryUrl)
Q_PROPERTY(qreal blend READ blend WRITE setBlend)
Q_PROPERTY(bool smooth READ smoothTransform WRITE setSmoothTransform)
public:
QFxBlendedImage(QFxItem *parent=0);
- QString primaryUrl() const;
- void setPrimaryUrl(const QString &);
+ QUrl primaryUrl() const;
+ void setPrimaryUrl(const QUrl &);
- QString secondaryUrl() const;
- void setSecondaryUrl(const QString &);
+ QUrl secondaryUrl() const;
+ void setSecondaryUrl(const QUrl &);
qreal blend() const;
void setBlend(qreal);
@@ -87,8 +87,6 @@ private Q_SLOTS:
void secondaryLoaded();
private:
- QString primSrc;
- QString secSrc;
QUrl primUrl;
QUrl secUrl;
diff --git a/src/declarative/fx/qfxhighlightfilter.cpp b/src/declarative/fx/qfxhighlightfilter.cpp
index 6bf3148..3d5f413 100644
--- a/src/declarative/fx/qfxhighlightfilter.cpp
+++ b/src/declarative/fx/qfxhighlightfilter.cpp
@@ -128,7 +128,7 @@ QFxHighlightFilter::~QFxHighlightFilter()
\property QFxHighlightFilter::source
\brief the URL of the image to be used as the highlight.
*/
-QString QFxHighlightFilter::source() const
+QUrl QFxHighlightFilter::source() const
{
return d->source;
}
@@ -144,14 +144,14 @@ void QFxHighlightFilter::imageLoaded()
update();
}
-void QFxHighlightFilter::setSource(const QString &f)
+void QFxHighlightFilter::setSource(const QUrl &f)
{
- if (d->source == f)
+ if (d->url == f)
return;
- if (!d->source.isEmpty())
+ if (!d->url.isEmpty())
QFxPixmap::cancelGet(d->url, this);
- d->source = f;
- d->url = qmlContext(this)->resolvedUrl(f);
+ Q_ASSERT(!f.isRelative());
+ d->url = f;
#if defined(QFX_RENDER_OPENGL2)
d->tex.clear();
#endif
diff --git a/src/declarative/fx/qfxhighlightfilter.h b/src/declarative/fx/qfxhighlightfilter.h
index 19e95ac..33f0963 100644
--- a/src/declarative/fx/qfxhighlightfilter.h
+++ b/src/declarative/fx/qfxhighlightfilter.h
@@ -56,7 +56,7 @@ class Q_DECLARATIVE_EXPORT QFxHighlightFilter : public QSimpleCanvasFilter
{
Q_OBJECT
- Q_PROPERTY(QString source READ source WRITE setSource NOTIFY sourceChanged)
+ Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
Q_PROPERTY(bool tiled READ tiled WRITE setTiled NOTIFY tiledChanged)
Q_PROPERTY(int xOffset READ xOffset WRITE setXOffset NOTIFY offsetChanged)
Q_PROPERTY(int yOffset READ yOffset WRITE setYOffset NOTIFY offsetChanged)
@@ -64,8 +64,8 @@ public:
QFxHighlightFilter(QObject *parent=0);
virtual ~QFxHighlightFilter();
- QString source() const;
- void setSource(const QString &);
+ QUrl source() const;
+ void setSource(const QUrl &);
bool tiled() const;
void setTiled(bool);
@@ -76,7 +76,7 @@ public:
void setYOffset(int);
Q_SIGNALS:
- void sourceChanged(const QString &);
+ void sourceChanged(const QUrl &);
void offsetChanged(int x, int y);
void tiledChanged(bool);
diff --git a/src/declarative/fx/qfximage.cpp b/src/declarative/fx/qfximage.cpp
index 22e5d97..05738e3 100644
--- a/src/declarative/fx/qfximage.cpp
+++ b/src/declarative/fx/qfximage.cpp
@@ -124,9 +124,15 @@ QFxImage::QFxImage(QFxImagePrivate &dd, QFxItem *parent)
QFxImage::~QFxImage()
{
- Q_D(const QFxImage);
+ Q_D(QFxImage);
if (d->sciReply)
d->sciReply->deleteLater();
+#if defined(QFX_RENDER_OPENGL)
+ if (d->tex) {
+ d->tex->release();
+ d->tex = 0;
+ }
+#endif
}
/*!
@@ -141,22 +147,25 @@ QFxImage::~QFxImage()
QPixmap QFxImage::pixmap() const
{
Q_D(const QFxImage);
- return d->_pix;
+ return d->pix;
}
void QFxImage::setPixmap(const QPixmap &pix)
{
Q_D(QFxImage);
d->url = QUrl();
- d->_pix = pix;
- d->_opaque=false;
+ d->pix = pix;
+ d->opaque=false;
- setImplicitWidth(d->_pix.width());
- setImplicitHeight(d->_pix.height());
+ setImplicitWidth(d->pix.width());
+ setImplicitHeight(d->pix.height());
#if defined(QFX_RENDER_OPENGL)
- d->_texDirty = true;
- d->_tex.clear();
+ d->texDirty = true;
+ if (d->tex) {
+ d->tex->release();
+ d->tex = 0;
+ }
#endif
update();
}
@@ -189,7 +198,7 @@ void QFxImage::setPixmap(const QPixmap &pix)
QFxScaleGrid *QFxImage::scaleGrid()
{
Q_D(QFxImage);
- return d->scaleGrid();
+ return d->getScaleGrid();
}
/*!
@@ -213,13 +222,13 @@ QFxScaleGrid *QFxImage::scaleGrid()
bool QFxImage::isTiled() const
{
Q_D(const QFxImage);
- return d->_tiled;
+ return d->tiled;
}
void QFxImage::setTiled(bool tile)
{
Q_D(QFxImage);
- d->_tiled = tile;
+ d->tiled = tile;
}
/*!
@@ -245,15 +254,18 @@ void QFxImage::setTiled(bool tile)
bool QFxImage::isOpaque() const
{
Q_D(const QFxImage);
- return d->_opaque;
+ return d->opaque;
}
void QFxImage::setOpaque(bool o)
{
Q_D(QFxImage);
- if (o == d->_opaque)
+ if (o == d->opaque)
return;
- d->_opaque = o;
+ d->opaque = o;
+
+ setOptions(IsOpaque, o);
+
update();
}
@@ -293,15 +305,15 @@ void QFxImage::componentComplete()
bool QFxImage::smoothTransform() const
{
Q_D(const QFxImage);
- return d->_smooth;
+ return d->smooth;
}
void QFxImage::setSmoothTransform(bool s)
{
Q_D(QFxImage);
- if (d->_smooth == s)
+ if (d->smooth == s)
return;
- d->_smooth = s;
+ d->smooth = s;
update();
}
@@ -317,16 +329,16 @@ void QFxImage::dump(int depth)
void QFxImage::paintContents(QPainter &p)
{
Q_D(QFxImage);
- if (d->_pix.isNull())
+ if (d->pix.isNull())
return;
QPainter::RenderHints oldHints = p.renderHints();
- if (d->_smooth)
- p.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, d->_smooth);
+ if (d->smooth)
+ p.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, d->smooth);
- QPixmap pix = d->_pix;
+ QPixmap pix = d->pix;
- if (d->_tiled) {
+ if (d->tiled) {
p.save();
p.setClipRect(0, 0, width(), height(), Qt::IntersectClip);
QRect me = QRect(0, 0, width(), height());
@@ -345,7 +357,7 @@ void QFxImage::paintContents(QPainter &p)
}
p.restore();
- } else if (!d->_scaleGrid || d->_scaleGrid->isNull()) {
+ } else if (!d->scaleGrid || d->scaleGrid->isNull()) {
if (width() != pix.width() || height() != pix.height()) {
QTransform scale;
scale.scale(width() / qreal(pix.width()),
@@ -358,10 +370,10 @@ void QFxImage::paintContents(QPainter &p)
p.drawPixmap(0, 0, pix);
}
} else {
- int sgl = d->_scaleGrid->left();
- int sgr = d->_scaleGrid->right();
- int sgt = d->_scaleGrid->top();
- int sgb = d->_scaleGrid->bottom();
+ int sgl = d->scaleGrid->left();
+ int sgr = d->scaleGrid->right();
+ int sgt = d->scaleGrid->top();
+ int sgb = d->scaleGrid->bottom();
int w = width();
int h = height();
@@ -412,7 +424,7 @@ void QFxImage::paintContents(QPainter &p)
QRect(pix.width()-sgr, pix.height() - sgb, sgr, sgb));
}
- if (d->_smooth)
+ if (d->smooth)
p.setRenderHints(oldHints);
}
#elif defined(QFX_RENDER_OPENGL)
@@ -421,7 +433,7 @@ uint QFxImage::glSimpleItemData(float *vertices, float *texVertices,
{
Q_D(QFxImage);
- if (d->_pix.isNull() || (d->_scaleGrid && !d->_scaleGrid->isNull()))
+ if (d->pix.isNull() || (d->scaleGrid && !d->scaleGrid->isNull()))
return 0;
if (count < 8)
@@ -437,20 +449,20 @@ uint QFxImage::glSimpleItemData(float *vertices, float *texVertices,
vertices[4] = 0; vertices[5] = 0;
vertices[6] = widthV; vertices[7] = 0;
- *texture = &d->_tex;
+ *texture = d->tex;
- if (d->_tiled) {
- float tileWidth = widthV / d->_pix.width();
- float tileHeight = heightV / d->_pix.height();
+ if (d->tiled) {
+ float tileWidth = widthV / d->pix.width();
+ float tileHeight = heightV / d->pix.height();
texVertices[0] = 0; texVertices[1] = 0;
texVertices[2] = tileWidth; texVertices[3] = 0;
texVertices[4] = 0; texVertices[5] = tileHeight;
texVertices[6] = tileWidth; texVertices[7] = tileHeight;
} else {
texVertices[0] = 0; texVertices[1] = 0;
- texVertices[2] = 1; texVertices[3] = 0;
- texVertices[4] = 0; texVertices[5] = 1;
- texVertices[6] = 1; texVertices[7] = 1;
+ texVertices[2] = d->tex->glWidth(); texVertices[3] = 0;
+ texVertices[4] = 0; texVertices[5] = d->tex->glHeight();
+ texVertices[6] = d->tex->glWidth(); texVertices[7] = d->tex->glHeight();
}
return 8;
@@ -458,51 +470,87 @@ uint QFxImage::glSimpleItemData(float *vertices, float *texVertices,
void QFxImagePrivate::checkDirty()
{
- if (_texDirty && !_pix.isNull()) {
- _tex.setImage(_pix.toImage());
- _tex.setHorizontalWrap(GLTexture::Repeat);
- _tex.setVerticalWrap(GLTexture::Repeat);
- }
- _texDirty = false;
+ Q_Q(QFxImage);
+ if (texDirty && !pix.isNull())
+ tex = q->cachedTexture(url.toString(), pix);
+ texDirty = false;
}
#if defined(QFX_RENDER_OPENGL2)
void QFxImage::paintGLContents(GLPainter &p)
{
Q_D(QFxImage);
- if (d->_pix.isNull())
+ if (d->pix.isNull())
return;
QGLShaderProgram *shader = p.useTextureShader();
bool restoreBlend = false;
- if (isOpaque() && p.activeOpacity == 1) {
+ if (p.blendEnabled && isOpaque() && p.activeOpacity == 1) {
glDisable(GL_BLEND);
restoreBlend = true;
}
- if (d->_tiled || (!d->_scaleGrid || d->_scaleGrid->isNull())) {
+ d->checkDirty();
+
+ if (d->tiled || (!d->scaleGrid || d->scaleGrid->isNull())) {
+
+ if (!d->tiled) {
- GLfloat vertices[8];
- GLfloat texVertices[8];
- GLTexture *tex = 0;
+ float widthV = width();
+ float heightV = height();
+ float glWidth = d->tex->glWidth();
+ float glHeight = d->tex->glHeight();
- QFxImage::glSimpleItemData(vertices, texVertices, &tex, 8);
+ float deltaX = 0.5 / qreal(d->tex->glSize().width());
+ float deltaY = 0.5 / qreal(d->tex->glSize().height());
+ glWidth -= deltaX;
+ glHeight -= deltaY;
+
- shader->setAttributeArray(SingleTextureShader::Vertices, vertices, 2);
- shader->setAttributeArray(SingleTextureShader::TextureCoords, texVertices, 2);
+ float vert[] = {
+ 0, heightV,
+ widthV, heightV,
+ 0, 0,
- glBindTexture(GL_TEXTURE_2D, tex->texture());
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ widthV, heightV,
+ 0, 0,
+ widthV, 0 };
- shader->disableAttributeArray(SingleTextureShader::Vertices);
- shader->disableAttributeArray(SingleTextureShader::TextureCoords);
+ float tex[] = {
+ deltaX, deltaY,
+ glWidth, deltaY,
+ deltaX, glHeight,
+
+ glWidth, deltaY,
+ deltaX, glHeight,
+ glWidth, glHeight
+ };
+
+ shader->setAttributeArray(SingleTextureShader::Vertices, vert, 2);
+ shader->setAttributeArray(SingleTextureShader::TextureCoords, tex, 2);
+ glBindTexture(GL_TEXTURE_2D, d->tex->texture());
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+
+ } else {
+
+ GLfloat vertices[8];
+ GLfloat texVertices[8];
+ GLTexture *tex = 0;
+
+ QFxImage::glSimpleItemData(vertices, texVertices, &tex, 8);
+
+ shader->setAttributeArray(SingleTextureShader::Vertices, vertices, 2);
+ shader->setAttributeArray(SingleTextureShader::TextureCoords, texVertices, 2);
+
+ glBindTexture(GL_TEXTURE_2D, tex->texture());
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ }
} else {
- d->checkDirty();
- float imgWidth = d->_pix.width();
- float imgHeight = d->_pix.height();
+ float imgWidth = d->pix.width();
+ float imgHeight = d->pix.height();
if (!imgWidth || !imgHeight) {
if (restoreBlend)
glEnable(GL_BLEND);
@@ -511,270 +559,196 @@ void QFxImage::paintGLContents(GLPainter &p)
float widthV = width();
float heightV = height();
-
- float texleft = 0;
- float texright = 1;
- float textop = 1;
- float texbottom = 0;
+ float glWidth = d->tex->glWidth();
+ float glHeight = d->tex->glHeight();
+ float deltaX = 0.5 / qreal(d->tex->glSize().width());
+ float deltaY = 0.5 / qreal(d->tex->glSize().height());
+ glHeight -= deltaY;
+ glWidth -= deltaX;
+
+ float texleft = deltaX;
+ float texright = glWidth;
+ float textop = glHeight;
+ float texbottom = deltaY;
float imgleft = 0;
float imgright = widthV;
float imgtop = 0;
float imgbottom = heightV;
- const int sgl = d->_scaleGrid->left();
- const int sgr = d->_scaleGrid->right();
- const int sgt = d->_scaleGrid->top();
- const int sgb = d->_scaleGrid->bottom();
+ const int sgl = d->scaleGrid->left();
+ const int sgr = d->scaleGrid->right();
+ const int sgt = d->scaleGrid->top();
+ const int sgb = d->scaleGrid->bottom();
if (sgl) {
- texleft = float(sgl) / imgWidth;
+ texleft = deltaX + d->tex->glWidth() * float(sgl) / imgWidth;
imgleft = sgl;
}
if (sgr) {
- texright = 1. - float(sgr) / imgWidth;
+ texright = d->tex->glWidth() - float(sgr) / imgWidth - deltaX;
imgright = widthV - sgr;
}
if (sgt) {
- textop = 1. - float(sgb) / imgHeight;
+ textop = d->tex->glHeight() - float(sgb) / imgHeight - deltaY;
imgtop = sgt;
}
if (sgb) {
- texbottom = float(sgt) / imgHeight;
+ texbottom = deltaY + d->tex->glHeight() * float(sgt) / imgHeight;
imgbottom = heightV - sgb;
}
float vert1[] = { 0, 0,
0, imgtop,
imgleft, 0,
+
+ 0, imgtop,
+ imgleft, 0,
+ imgleft, imgtop,
+
+ imgleft, 0,
imgleft, imgtop,
imgright, 0,
+
+ imgleft, imgtop,
+ imgright, 0,
+ imgright, imgtop,
+
+ imgright, 0,
imgright, imgtop,
widthV, 0,
- widthV, imgtop };
- float tex1[] = { 0, 1,
- 0, textop,
- texleft, 1,
- texleft, textop,
- texright, 1,
- texright, textop,
- 1, 1,
- 1, textop };
- float vert2[] = { 0, imgtop,
+
+ imgright, imgtop,
+ widthV, 0,
+ widthV, imgtop,
+
+ 0, imgtop,
+ 0, imgbottom,
+ imgleft, imgtop,
+
0, imgbottom,
imgleft, imgtop,
imgleft, imgbottom,
+
+ imgleft, imgtop,
+ imgleft, imgbottom,
+ imgright, imgtop,
+
+ imgleft, imgbottom,
+ imgright, imgtop,
+ imgright, imgbottom,
+
imgright, imgtop,
imgright, imgbottom,
widthV, imgtop,
- widthV, imgbottom };
- float tex2[] = { 0, textop,
- 0, texbottom,
- texleft, textop,
- texleft, texbottom,
- texright, textop,
- texright, texbottom,
- 1, textop,
- 1, texbottom };
- float vert3[] = { 0, imgbottom,
+
+ imgright, imgbottom,
+ widthV, imgtop,
+ widthV, imgbottom,
+
+ 0, imgbottom,
0, heightV,
imgleft, imgbottom,
+
+ 0, heightV,
+ imgleft, imgbottom,
+ imgleft, heightV,
+
+ imgleft, imgbottom,
+ imgleft, heightV,
+ imgright, imgbottom,
+
imgleft, heightV,
imgright, imgbottom,
imgright, heightV,
+
+ imgright, imgbottom,
+ imgright, heightV,
widthV, imgbottom,
- widthV, heightV };
- float tex3[] = { 0, texbottom,
- 0, 0,
- texleft, texbottom,
- texleft, 0,
- texright, texbottom,
- texright, 0,
- 1, texbottom,
- 1, 0 };
- glBindTexture(GL_TEXTURE_2D, d->_tex.texture());
+ imgright, heightV,
+ widthV, imgbottom,
+ widthV, heightV };
- shader->setAttributeArray(SingleTextureShader::Vertices, vert1, 2);
- shader->setAttributeArray(SingleTextureShader::TextureCoords, tex1, 2);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);
- shader->setAttributeArray(SingleTextureShader::Vertices, vert2, 2);
- shader->setAttributeArray(SingleTextureShader::TextureCoords, tex2, 2);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);
- shader->setAttributeArray(SingleTextureShader::Vertices, vert3, 2);
- shader->setAttributeArray(SingleTextureShader::TextureCoords, tex3, 2);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);
-
- shader->disableAttributeArray(SingleTextureShader::Vertices);
- shader->disableAttributeArray(SingleTextureShader::TextureCoords);
- }
+ float tex1[] = { deltaX, glHeight,
+ deltaX, textop,
+ texleft, glHeight,
- if (restoreBlend)
- glEnable(GL_BLEND);
-}
-#elif defined(QFX_RENDER_OPENGL1)
-void QFxImage::paintGLContents(GLPainter &p)
-{
- Q_D(QFxImage);
- if (d->_pix.isNull())
- return;
-
- glMatrixMode(GL_MODELVIEW);
- glLoadMatrixf(p.activeTransform.data());
+ deltaX, textop,
+ texleft, glHeight,
+ texleft, textop,
- bool restoreBlend = false;
- if (isOpaque() && p.activeOpacity == 1) {
- glDisable(GL_BLEND);
- restoreBlend = true;
- }
+ texleft, glHeight,
+ texleft, textop,
+ texright, glHeight,
- glEnable(GL_TEXTURE_2D);
- if (p.activeOpacity == 1.) {
- GLint i = GL_REPLACE;
- glTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &i);
- } else {
- GLint i = GL_MODULATE;
- glTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &i);
- glColor4f(1, 1, 1, p.activeOpacity);
- }
+ texleft, textop,
+ texright, glHeight,
+ texright, textop,
- if (d->_tiled || !d->_scaleGrid || d->_scaleGrid->isNull()) {
+ texright, glHeight,
+ texright, textop,
+ glWidth, glHeight,
- GLfloat vertices[8];
- GLfloat texVertices[8];
- GLTexture *tex = 0;
+ texright, textop,
+ glWidth, glHeight,
+ glWidth, textop,
- QFxImage::glSimpleItemData(vertices, texVertices, &tex, 8);
+ deltaX, textop,
+ deltaX, texbottom,
+ texleft, textop,
- glBindTexture(GL_TEXTURE_2D, tex->texture());
+ deltaX, texbottom,
+ texleft, textop,
+ texleft, texbottom,
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ texleft, textop,
+ texleft, texbottom,
+ texright, textop,
- glVertexPointer(2, GL_FLOAT, 0, vertices);
- glTexCoordPointer(2, GL_FLOAT, 0, texVertices);
+ texleft, texbottom,
+ texright, textop,
+ texright, texbottom,
+ texright, textop,
+ texright, texbottom,
+ glWidth, textop,
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ texright, texbottom,
+ glWidth, textop,
+ glWidth, texbottom,
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisable(GL_TEXTURE_2D);
+ deltaX, texbottom,
+ deltaX, deltaY,
+ texleft, texbottom,
- } else {
- d->checkDirty();
+ deltaX, deltaY,
+ texleft, texbottom,
+ texleft, deltaY,
- float imgWidth = d->_pix.width();
- float imgHeight = d->_pix.height();
- if (!imgWidth || !imgHeight) {
- if (restoreBlend)
- glEnable(GL_BLEND);
- return;
- }
+ texleft, texbottom,
+ texleft, deltaY,
+ texright, texbottom,
- float widthV = width();
- float heightV = height();
+ texleft, deltaY,
+ texright, texbottom,
+ texright, deltaY,
- float texleft = 0;
- float texright = 1;
- float textop = 1;
- float texbottom = 0;
- float imgleft = 0;
- float imgright = widthV;
- float imgtop = 0;
- float imgbottom = heightV;
+ texright, texbottom,
+ texright, deltaY,
+ glWidth, texbottom,
- const int sgl = d->_scaleGrid->left();
- const int sgr = d->_scaleGrid->right();
- const int sgt = d->_scaleGrid->top();
- const int sgb = d->_scaleGrid->bottom();
+ texright, deltaY,
+ glWidth, texbottom,
+ glWidth, deltaY };
- if (sgl) {
- texleft = float(sgl) / imgWidth;
- imgleft = sgl;
- }
- if (sgr) {
- texright = 1. - float(sgr) / imgWidth;
- imgright = widthV - sgr;
- }
- if (sgt) {
- textop = 1. - float(sgb) / imgHeight;
- imgtop = sgt;
- }
- if (sgb) {
- texbottom = float(sgt) / imgHeight;
- imgbottom = heightV - sgb;
- }
+ glBindTexture(GL_TEXTURE_2D, d->tex->texture());
- float vert1[] = { 0, 0,
- 0, imgtop,
- imgleft, 0,
- imgleft, imgtop,
- imgright, 0,
- imgright, imgtop,
- widthV, 0,
- widthV, imgtop };
- float tex1[] = { 0, 1,
- 0, textop,
- texleft, 1,
- texleft, textop,
- texright, 1,
- texright, textop,
- 1, 1,
- 1, textop };
- float vert2[] = { 0, imgtop,
- 0, imgbottom,
- imgleft, imgtop,
- imgleft, imgbottom,
- imgright, imgtop,
- imgright, imgbottom,
- widthV, imgtop,
- widthV, imgbottom };
- float tex2[] = { 0, textop,
- 0, texbottom,
- texleft, textop,
- texleft, texbottom,
- texright, textop,
- texright, texbottom,
- 1, textop,
- 1, texbottom };
- float vert3[] = { 0, imgbottom,
- 0, heightV,
- imgleft, imgbottom,
- imgleft, heightV,
- imgright, imgbottom,
- imgright, heightV,
- widthV, imgbottom,
- widthV, heightV };
- float tex3[] = { 0, texbottom,
- 0, 0,
- texleft, texbottom,
- texleft, 0,
- texright, texbottom,
- texright, 0,
- 1, texbottom,
- 1, 0 };
-
- glBindTexture(GL_TEXTURE_2D, d->_tex.texture());
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
- glVertexPointer(2, GL_FLOAT, 0, vert1);
- glTexCoordPointer(2, GL_FLOAT, 0, tex1);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);
- glVertexPointer(2, GL_FLOAT, 0, vert2);
- glTexCoordPointer(2, GL_FLOAT, 0, tex2);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);
- glVertexPointer(2, GL_FLOAT, 0, vert3);
- glTexCoordPointer(2, GL_FLOAT, 0, tex3);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);
-
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisable(GL_TEXTURE_2D);
+ shader->setAttributeArray(SingleTextureShader::Vertices, vert1, 2);
+ shader->setAttributeArray(SingleTextureShader::TextureCoords, tex1, 2);
+ glDrawArrays(GL_TRIANGLES, 0, 54);
}
- if (restoreBlend)
+ if (restoreBlend)
glEnable(GL_BLEND);
}
#endif
@@ -851,19 +825,19 @@ qreal QFxImage::progress() const
The content specified can be of any image type loadable by QImage. Alternatively,
you can specify an sci format file, which specifies both an image and it's scale grid.
*/
-QString QFxImage::source() const
+QUrl QFxImage::source() const
{
Q_D(const QFxImage);
- return d->source;
+ return d->url;
}
-void QFxImage::setSource(const QString &url)
+void QFxImage::setSource(const QUrl &url)
{
#ifdef Q_ENABLE_PERFORMANCE_LOG
QFxPerfTimer<QFxPerf::PixmapLoad> perf;
#endif
Q_D(QFxImage);
- if (url == d->source)
+ if (url == d->url)
return;
if (d->sciReply) {
@@ -876,8 +850,7 @@ void QFxImage::setSource(const QString &url)
if (!d->sciurl.isEmpty())
QFxPixmap::cancelGet(d->sciurl, this);
- d->source = url;
- d->url = qmlContext(this)->resolvedUrl(url);
+ d->url = url;
d->sciurl = QUrl();
if (d->progress != 0.0) {
d->progress = 0.0;
@@ -891,11 +864,14 @@ void QFxImage::setSource(const QString &url)
setImplicitWidth(0);
setImplicitHeight(0);
#if defined(QFX_RENDER_OPENGL)
- d->_texDirty = true;
- d->_tex.clear();
+ d->texDirty = true;
+ if (d->tex) {
+ d->tex->release();
+ d->tex = 0;
+ }
#endif
emit statusChanged(d->status);
- emit sourceChanged(d->source);
+ emit sourceChanged(d->url);
emit progressChanged(1.0);
update();
} else {
@@ -934,7 +910,7 @@ void QFxImage::requestFinished()
{
Q_D(QFxImage);
if (d->url.path().endsWith(QLatin1String(".sci"))) {
- d->_pix = QFxPixmap(d->sciurl);
+ d->pix = QFxPixmap(d->sciurl);
} else {
if (d->reply) {
disconnect(d->reply, SIGNAL(downloadProgress(qint64,qint64)),
@@ -942,21 +918,24 @@ void QFxImage::requestFinished()
if (d->reply->error() != QNetworkReply::NoError)
d->status = Error;
}
- d->_pix = QFxPixmap(d->url);
+ d->pix = QFxPixmap(d->url);
setOptions(QFxImage::SimpleItem, true);
}
- setImplicitWidth(d->_pix.width());
- setImplicitHeight(d->_pix.height());
+ setImplicitWidth(d->pix.width());
+ setImplicitHeight(d->pix.height());
if (d->status == Loading)
d->status = Idle;
d->progress = 1.0;
#if defined(QFX_RENDER_OPENGL)
- d->_texDirty = true;
- d->_tex.clear();
+ d->texDirty = true;
+ if (d->tex) {
+ d->tex->release();
+ d->tex = 0;
+ }
#endif
emit statusChanged(d->status);
- emit sourceChanged(d->source);
+ emit sourceChanged(d->url);
emit progressChanged(1.0);
update();
}
diff --git a/src/declarative/fx/qfximage.h b/src/declarative/fx/qfximage.h
index 4d5f134..35b921a 100644
--- a/src/declarative/fx/qfximage.h
+++ b/src/declarative/fx/qfximage.h
@@ -58,7 +58,7 @@ class Q_DECLARATIVE_EXPORT QFxImage : public QFxItem
Q_ENUMS(Status)
Q_PROPERTY(Status status READ status NOTIFY statusChanged)
- Q_PROPERTY(QString source READ source WRITE setSource NOTIFY sourceChanged)
+ Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged)
Q_PROPERTY(QFxScaleGrid *scaleGrid READ scaleGrid)
@@ -88,8 +88,8 @@ public:
Status status() const;
qreal progress() const;
- QString source() const;
- virtual void setSource(const QString &url);
+ QUrl source() const;
+ virtual void setSource(const QUrl &url);
virtual void dump(int depth);
virtual QString propertyInfo() const;
@@ -102,7 +102,7 @@ public:
#endif
Q_SIGNALS:
- void sourceChanged(const QString &);
+ void sourceChanged(const QUrl &);
void statusChanged(Status);
void progressChanged(qreal progress);
diff --git a/src/declarative/fx/qfximage_p.h b/src/declarative/fx/qfximage_p.h
index b3cccf9..1785abb 100644
--- a/src/declarative/fx/qfximage_p.h
+++ b/src/declarative/fx/qfximage_p.h
@@ -72,9 +72,9 @@ class QFxImagePrivate : public QFxItemPrivate
public:
QFxImagePrivate()
- : _scaleGrid(0), _tiled(false), _smooth(false), _opaque(false),
+ : scaleGrid(0), tiled(false), smooth(false), opaque(false),
#if defined(QFX_RENDER_OPENGL)
- _texDirty(true),
+ texDirty(true), tex(0),
#endif
status(QFxImage::Idle), sciReply(0), progress(0.0)
{
@@ -82,31 +82,30 @@ public:
~QFxImagePrivate()
{
- delete _scaleGrid;
+ delete scaleGrid;
}
void setContent(QIODevice* dev, const QString &url);
- QFxScaleGrid *scaleGrid()
+ QFxScaleGrid *getScaleGrid()
{
- if (!_scaleGrid)
- _scaleGrid = new QFxScaleGrid;
- return _scaleGrid;
+ if (!scaleGrid)
+ scaleGrid = new QFxScaleGrid;
+ return scaleGrid;
}
- QFxScaleGrid *_scaleGrid;
- QPixmap _pix;
- bool _tiled : 1;
- bool _smooth : 1;
- bool _opaque : 1;
+ QFxScaleGrid *scaleGrid;
+ QPixmap pix;
+ bool tiled : 1;
+ bool smooth : 1;
+ bool opaque : 1;
#if defined(QFX_RENDER_OPENGL)
+ bool texDirty : 1;
void checkDirty();
- bool _texDirty;
- GLTexture _tex;
+ QSimpleCanvasItem::CachedTexture *tex;
#endif
QFxImage::Status status;
- QString source;
QUrl url;
QUrl sciurl;
QNetworkReply *sciReply;
diff --git a/src/declarative/fx/qfxitem.cpp b/src/declarative/fx/qfxitem.cpp
index 7129757..648b0fb 100644
--- a/src/declarative/fx/qfxitem.cpp
+++ b/src/declarative/fx/qfxitem.cpp
@@ -792,12 +792,12 @@ QFxItem *QFxItem::qmlItem() const
}
/*!
- \qmlproperty string Item::qml
- This property holds the dynamic QML for the item.
+ \qmlproperty url Item::qml
+ This property holds the dynamic URL of the QML for the item.
This property is used for dynamically loading QML into the
item. Querying for the QML only has meaning if the QML has been
- dynamically set; otherwise an empty string is returned.
+ dynamically set; otherwise an empty URL is returned.
*/
/*! \fn void QFxItem::qmlChanged()
@@ -809,32 +809,31 @@ QFxItem *QFxItem::qmlItem() const
/*!
\property QFxItem::qml
- This property holds the dynamic QML for the item.
+ This property holds the dynamic URL of the QML for the item.
This property is used for dynamically loading QML into the
item. Querying for the QML only has meaning if the QML has been
- dynamically set; otherwise an empty string is returned.
+ dynamically set; otherwise an empty URL is returned.
*/
-QString QFxItem::qml() const
+QUrl QFxItem::qml() const
{
Q_D(const QFxItem);
return d->_qml;
}
-void QFxItem::setQml(const QString &qml)
+void QFxItem::setQml(const QUrl &qml)
{
Q_D(QFxItem);
if (d->_qml == qml)
return;
if (!d->_qml.isEmpty()) {
- QmlChildren::Iterator iter = d->_qmlChildren.find(d->_qml);
+ QmlChildren::Iterator iter = d->_qmlChildren.find(d->_qml.toString());
if (iter != d->_qmlChildren.end())
(*iter)->setOpacity(0.);
}
d->_qml = qml;
- d->_qmlurl = qmlContext(this)->resolvedUri(qml);
d->qmlItem = 0;
if (d->_qml.isEmpty()) {
@@ -842,14 +841,14 @@ void QFxItem::setQml(const QString &qml)
return;
}
- QmlChildren::Iterator iter = d->_qmlChildren.find(d->_qml);
+ QmlChildren::Iterator iter = d->_qmlChildren.find(d->_qml.toString());
if (iter != d->_qmlChildren.end()) {
(*iter)->setOpacity(1.);
d->qmlItem = (*iter);
emit qmlChanged();
} else {
d->_qmlcomp =
- new QmlComponent(qmlEngine(this), d->_qmlurl, this);
+ new QmlComponent(qmlEngine(this), d->_qml, this);
if (!d->_qmlcomp->isLoading())
qmlLoaded();
else
@@ -1491,9 +1490,8 @@ void QFxItem::setRotation(qreal rotation)
trans.rotate(d->_rotation, 0, 0, 1);
trans.translate(-to.x(), -to.y());
#else
- QTransform trans;
- QPointF to = transformOriginPoint();
- trans.translate(to.x(), to.y());
+ QPointF to = d->transformOrigin();
+ QTransform trans = QTransform::fromTranslate(to.x(), to.y());
trans.rotate(d->_rotation);
trans.translate(-to.x(), -to.y());
#endif
diff --git a/src/declarative/fx/qfxitem.h b/src/declarative/fx/qfxitem.h
index 8ca1f9e..3c872e1 100644
--- a/src/declarative/fx/qfxitem.h
+++ b/src/declarative/fx/qfxitem.h
@@ -111,7 +111,7 @@ class Q_DECLARATIVE_EXPORT QFxItem : public QSimpleCanvasItem, public QmlParserS
Q_PROPERTY(QmlList<QmlState *>* states READ states DESIGNABLE false)
Q_PROPERTY(QmlList<QmlTransition *>* transitions READ transitions DESIGNABLE false)
Q_PROPERTY(QString state READ state WRITE setState NOTIFY stateChanged)
- Q_PROPERTY(QString qml READ qml WRITE setQml NOTIFY qmlChanged)
+ Q_PROPERTY(QUrl qml READ qml WRITE setQml NOTIFY qmlChanged)
Q_PROPERTY(QFxItem *qmlItem READ qmlItem NOTIFY qmlChanged)
Q_PROPERTY(qreal x READ x WRITE setX NOTIFY leftChanged)
Q_PROPERTY(qreal y READ y WRITE setY NOTIFY topChanged)
@@ -171,8 +171,8 @@ public:
void setState(const QString &);
QFxItem *qmlItem() const;
- QString qml() const;
- void setQml(const QString &);
+ QUrl qml() const;
+ void setQml(const QUrl &);
bool flipVertically() const;
void setFlipVertically(bool);
diff --git a/src/declarative/fx/qfxitem_p.h b/src/declarative/fx/qfxitem_p.h
index a54f523..b38d877 100644
--- a/src/declarative/fx/qfxitem_p.h
+++ b/src/declarative/fx/qfxitem_p.h
@@ -133,9 +133,8 @@ public:
QFxAnchors *_anchors;
QFxContents *_contents;
QFxItem *qmlItem;
- QUrl _qmlurl;
QmlComponent *_qmlcomp;
- QString _qml;
+ QUrl _qml;
QList<QUrl> _qmlnewloading;
QList<QmlComponent*> _qmlnewcomp;
diff --git a/src/declarative/fx/qfxparticles.cpp b/src/declarative/fx/qfxparticles.cpp
index 41fb5bc..25e359d 100644
--- a/src/declarative/fx/qfxparticles.cpp
+++ b/src/declarative/fx/qfxparticles.cpp
@@ -395,7 +395,6 @@ public:
void createParticle(int time);
void updateOpacity(QFxParticle &p, int age);
- QString source;
QUrl url;
QPixmap image;
int count;
@@ -642,10 +641,10 @@ QFxParticles::~QFxParticles()
\property QFxParticles::source
\brief the URL of the particle image.
*/
-QString QFxParticles::source() const
+QUrl QFxParticles::source() const
{
Q_D(const QFxParticles);
- return d->source;
+ return d->url;
}
void QFxParticles::imageLoaded()
@@ -659,18 +658,17 @@ void QFxParticles::imageLoaded()
update();
}
-void QFxParticles::setSource(const QString &name)
+void QFxParticles::setSource(const QUrl &name)
{
Q_D(QFxParticles);
- if (name == d->source)
+ if (name == d->url)
return;
- if (!d->source.isEmpty())
+ if (!d->url.isEmpty())
QFxPixmap::cancelGet(d->url, this);
if (name.isEmpty()) {
- d->source = name;
- d->url = QUrl();
+ d->url = name;
d->image = QPixmap();
#if defined(QFX_RENDER_OPENGL)
d->texDirty = true;
@@ -678,8 +676,8 @@ void QFxParticles::setSource(const QString &name)
#endif
update();
} else {
- d->source = name;
- d->url = qmlContext(this)->resolvedUrl(name);
+ d->url = name;
+ Q_ASSERT(!name.isRelative());
QFxPixmap::get(qmlEngine(this), d->url, this, SLOT(imageLoaded()));
}
}
diff --git a/src/declarative/fx/qfxparticles.h b/src/declarative/fx/qfxparticles.h
index 6ef2582..b3a569b 100644
--- a/src/declarative/fx/qfxparticles.h
+++ b/src/declarative/fx/qfxparticles.h
@@ -153,7 +153,7 @@ class Q_DECLARATIVE_EXPORT QFxParticles : public QFxItem
{
Q_OBJECT
- Q_PROPERTY(QString source READ source WRITE setSource)
+ Q_PROPERTY(QUrl source READ source WRITE setSource)
Q_PROPERTY(int count READ count WRITE setCount)
Q_PROPERTY(int lifeSpan READ lifeSpan WRITE setLifeSpan)
Q_PROPERTY(int lifeSpanDeviation READ lifeSpanDeviation WRITE setLifeSpanDeviation)
@@ -172,8 +172,8 @@ public:
QFxParticles(QFxItem *parent=0);
~QFxParticles();
- QString source() const;
- void setSource(const QString &);
+ QUrl source() const;
+ void setSource(const QUrl &);
int count() const;
void setCount(int cnt);
diff --git a/src/declarative/fx/qfxrect.cpp b/src/declarative/fx/qfxrect.cpp
index c156753..f55357f 100644
--- a/src/declarative/fx/qfxrect.cpp
+++ b/src/declarative/fx/qfxrect.cpp
@@ -253,13 +253,16 @@ void QFxRect::doUpdate()
{
#if defined(QFX_RENDER_QPAINTER)
Q_D(QFxRect);
- d->_rectImage = QPixmap();
+ d->rectImage = QPixmap();
#endif
#if defined(QFX_RENDER_OPENGL)
Q_D(QFxRect);
- d->_rectTexture.clear();
+ if (d->rectTexture) {
+ d->rectTexture->release();
+ d->rectTexture = 0;
+ }
#endif
- const int pw = d->_pen && d->_pen->isValid() ? d->_pen->width() : 0;
+ const int pw = d->pen && d->pen->isValid() ? d->pen->width() : 0;
setPaintMargin((pw+1)/2);
update();
}
@@ -277,7 +280,7 @@ void QFxRect::doUpdate()
QFxPen *QFxRect::pen()
{
Q_D(QFxRect);
- return d->pen();
+ return d->getPen();
}
/*!
@@ -348,20 +351,23 @@ void QFxRect::setGradient(QFxGradient *gradient)
qreal QFxRect::radius() const
{
Q_D(const QFxRect);
- return d->_radius;
+ return d->radius;
}
void QFxRect::setRadius(qreal radius)
{
Q_D(QFxRect);
- if (d->_radius == radius)
+ if (d->radius == radius)
return;
- d->_radius = radius;
+ d->radius = radius;
#if defined(QFX_RENDER_QPAINTER)
- d->_rectImage = QPixmap();
+ d->rectImage = QPixmap();
#elif defined(QFX_RENDER_OPENGL)
- d->_rectTexture.clear();
+ if (d->rectTexture) {
+ d->rectTexture->release();
+ d->rectTexture = 0;
+ }
#endif
update();
}
@@ -370,7 +376,7 @@ void QFxRect::dump(int depth)
{
Q_D(QFxRect);
QByteArray ba(depth * 4, ' ');
- qWarning() << ba.constData() << "QFxRect:" << d->_color;
+ qWarning() << ba.constData() << "QFxRect:" << d->color;
QFxItem::dump(depth);
}
@@ -394,21 +400,24 @@ void QFxRect::dump(int depth)
QColor QFxRect::color() const
{
Q_D(const QFxRect);
- return d->_color;
+ return d->color;
}
void QFxRect::setColor(const QColor &c)
{
Q_D(QFxRect);
- if (d->_color == c)
+ if (d->color == c)
return;
- d->_color = c;
+ d->color = c;
#if defined(QFX_RENDER_QPAINTER)
- d->_rectImage = QPixmap();
+ d->rectImage = QPixmap();
#endif
#if defined(QFX_RENDER_OPENGL)
- d->_rectTexture.clear();
+ if (d->rectTexture) {
+ d->rectTexture->release();
+ d->rectTexture = 0;
+ }
#endif
update();
}
@@ -437,30 +446,30 @@ void QFxRect::setColor(const QColor &c)
QColor QFxRect::tintColor() const
{
Q_D(const QFxRect);
- return d->_tintColor;
+ return d->tintColor;
}
void QFxRect::setTintColor(const QColor &c)
{
Q_D(QFxRect);
- if (d->_tintColor == c)
+ if (d->tintColor == c)
return;
- d->_tintColor = c;
+ d->tintColor = c;
update();
}
QColor QFxRectPrivate::getColor()
{
- if (_tintColor.isValid()) {
- int a = _tintColor.alpha();
+ if (tintColor.isValid()) {
+ int a = tintColor.alpha();
if (a == 0xFF)
- return _tintColor;
+ return tintColor;
else if (a == 0x00)
- return _color;
+ return color;
else {
- uint src = _tintColor.rgba();
- uint dest = _color.rgba();
+ uint src = tintColor.rgba();
+ uint dest = color.rgba();
uint res = (((a * (src & 0xFF00FF)) +
((0xFF - a) * (dest & 0xFF00FF))) >> 8) & 0xFF00FF;
@@ -472,7 +481,7 @@ QColor QFxRectPrivate::getColor()
return QColor::fromRgba(res);
}
} else {
- return _color;
+ return color;
}
}
@@ -481,82 +490,95 @@ QColor QFxRectPrivate::getColor()
void QFxRect::generateRoundedRect()
{
Q_D(QFxRect);
- if (d->_rectImage.isNull()) {
- const int pw = d->_pen && d->_pen->isValid() ? d->_pen->width() : 0;
- d->_rectImage = QPixmap(d->_radius*2 + 3 + pw*2, d->_radius*2 + 3 + pw*2);
- d->_rectImage.fill(Qt::transparent);
- QPainter p(&(d->_rectImage));
+ if (d->rectImage.isNull()) {
+ const int pw = d->pen && d->pen->isValid() ? d->pen->width() : 0;
+ d->rectImage = QPixmap(d->radius*2 + 3 + pw*2, d->radius*2 + 3 + pw*2);
+ d->rectImage.fill(Qt::transparent);
+ QPainter p(&(d->rectImage));
p.setRenderHint(QPainter::Antialiasing);
- if (d->_pen && d->_pen->isValid()) {
- QPen pn(QColor(pen()->color()), pen()->width());
+ if (d->pen && d->pen->isValid()) {
+ QPen pn(QColor(d->pen->color()), d->pen->width());
p.setPen(pn);
} else {
p.setPen(Qt::NoPen);
}
- p.setBrush(d->_color);
- p.drawRoundedRect((pw+1)/2, (pw+1)/2, d->_rectImage.width()-(pw+1)/2*2, d->_rectImage.height()-(pw+1)/2*2, d->_radius, d->_radius);
+ p.setBrush(d->color);
+ p.drawRoundedRect((pw+1)/2, (pw+1)/2, d->rectImage.width()-(pw+1)/2*2, d->rectImage.height()-(pw+1)/2*2, d->radius, d->radius);
}
}
void QFxRect::generateBorderedRect()
{
Q_D(QFxRect);
- if (d->_rectImage.isNull()) {
- const int pw = d->_pen && d->_pen->isValid() ? d->_pen->width() : 0;
- d->_rectImage = QPixmap(d->pen()->width()*2 + 3 + pw*2, d->pen()->width()*2 + 3 + pw*2);
- d->_rectImage.fill(Qt::transparent);
- QPainter p(&(d->_rectImage));
+ if (d->rectImage.isNull()) {
+ const int pw = d->pen && d->pen->isValid() ? d->pen->width() : 0;
+ d->rectImage = QPixmap(d->getPen()->width()*2 + 3 + pw*2, d->getPen()->width()*2 + 3 + pw*2);
+ d->rectImage.fill(Qt::transparent);
+ QPainter p(&(d->rectImage));
p.setRenderHint(QPainter::Antialiasing);
- if (d->_pen && d->_pen->isValid()) {
- QPen pn(QColor(pen()->color()), pen()->width());
+ if (d->pen && d->pen->isValid()) {
+ QPen pn(QColor(d->pen->color()), d->pen->width());
p.setPen(pn);
} else {
p.setPen(Qt::NoPen);
}
- p.setBrush(d->_color);
- p.drawRect(qreal(pw+1)/2, qreal(pw+1)/2, d->_rectImage.width()-(pw+1)/2*2, d->_rectImage.height()-(pw+1)/2*2);
+ p.setBrush(d->color);
+ p.drawRect(qreal(pw+1)/2, qreal(pw+1)/2, d->rectImage.width()-(pw+1)/2*2, d->rectImage.height()-(pw+1)/2*2);
}
}
#elif defined(QFX_RENDER_OPENGL)
void QFxRect::generateRoundedRect()
{
Q_D(QFxRect);
- if (d->_rectTexture.isNull()) {
- const int pw = d->_pen && d->_pen->isValid() ? d->_pen->width() : 0;
- QImage roundRect(d->_radius*2 + 4 + pw*2, d->_radius*2 + 4 + pw*2, QImage::Format_ARGB32_Premultiplied);
- roundRect.fill(0);
- QPainter p(&roundRect);
- p.setRenderHint(QPainter::Antialiasing);
- if (d->_pen && d->_pen->isValid()) {
- QPen pn(QColor(pen()->color()), pen()->width());
- p.setPen(pn);
- } else {
- p.setPen(Qt::NoPen);
+ if (!d->rectTexture) {
+ const int pw = d->pen && d->pen->isValid() ? d->pen->width() : 0;
+ QString key = QString("QFxRect://r_%1_%2_%3_%4").arg(pw).arg(d->radius).arg((d->pen && d->pen->isValid())?d->pen->color().name():QString()).arg(d->color.name());
+
+ d->rectTexture = cachedTexture(key);
+
+ if (!d->rectTexture) {
+ QPixmap roundRect(d->radius*2 + 4 + pw*2, d->radius*2 + 4 + pw*2);
+ roundRect.fill(Qt::transparent);
+ QPainter p(&roundRect);
+ p.setRenderHint(QPainter::Antialiasing);
+ if (d->pen && d->pen->isValid()) {
+ QPen pn(QColor(pen()->color()), pen()->width());
+ p.setPen(pn);
+ } else {
+ p.setPen(Qt::NoPen);
+ }
+ p.setBrush(d->color);
+ p.drawRoundedRect((pw+1)/2, (pw+1)/2, roundRect.width()-(pw+1)/2*2, roundRect.height()-(pw+1)/2*2, d->radius, d->radius);
+
+ d->rectTexture = cachedTexture(key, roundRect);
}
- p.setBrush(d->_color);
- p.drawRoundedRect((pw+1)/2, (pw+1)/2, roundRect.width()-(pw+1)/2*2, roundRect.height()-(pw+1)/2*2, d->_radius, d->_radius);
- d->_rectTexture.setImage(roundRect);
}
}
void QFxRect::generateBorderedRect()
{
Q_D(QFxRect);
- if (d->_rectTexture.isNull()) {
- const int pw = d->_pen && d->_pen->isValid() ? d->_pen->width() : 0;
- QImage borderedRect(pw*2 + 4, pw*2 + 4, QImage::Format_ARGB32_Premultiplied);
- borderedRect.fill(0);
- QPainter p(&(borderedRect));
- p.setRenderHint(QPainter::Antialiasing);
- if (d->_pen && d->_pen->isValid()) {
- QPen pn(QColor(pen()->color()), pen()->width());
- p.setPen(pn);
- } else {
- p.setPen(Qt::NoPen);
+ if (!d->rectTexture) {
+ const int pw = d->pen && d->pen->isValid() ? d->pen->width() : 0;
+ QString key = QString("QFxRect://b_%1_%2_%3_%4").arg(pw).arg(d->radius).arg((d->pen && d->pen->isValid())?d->pen->color().name():QString()).arg(d->color.name());
+
+ d->rectTexture = cachedTexture(key);
+
+ if (!d->rectTexture) {
+ QPixmap borderedRect(pw*2 + 4, pw*2 + 4);
+ borderedRect.fill(Qt::transparent);
+ QPainter p(&(borderedRect));
+ p.setRenderHint(QPainter::Antialiasing);
+ if (d->pen && d->pen->isValid()) {
+ QPen pn(QColor(pen()->color()), pen()->width());
+ p.setPen(pn);
+ } else {
+ p.setPen(Qt::NoPen);
+ }
+ p.setBrush(d->color);
+ p.drawRect(qreal(pw+1)/2, qreal(pw+1)/2, borderedRect.width()-(pw+1)/2*2, borderedRect.height()-(pw+1)/2*2);
+ d->rectTexture = cachedTexture(key, borderedRect);
}
- p.setBrush(d->_color);
- p.drawRect(qreal(pw+1)/2, qreal(pw+1)/2, borderedRect.width()-(pw+1)/2*2, borderedRect.height()-(pw+1)/2*2);
- d->_rectTexture.setImage(borderedRect);
}
}
#endif
@@ -566,7 +588,7 @@ void QFxRect::generateBorderedRect()
void QFxRect::paintContents(QPainter &p)
{
Q_D(QFxRect);
- if (d->_radius > 0 || (d->_pen && d->_pen->isValid())
+ if (d->radius > 0 || (d->pen && d->pen->isValid())
|| (d->gradient && d->gradient->gradient()) )
drawRect(p);
else
@@ -581,26 +603,26 @@ void QFxRect::drawRect(QPainter &p)
// Image path won't work for gradients though
QPainter::RenderHints oldHints = p.renderHints();
p.setRenderHint(QPainter::Antialiasing);
- if (d->_pen && d->_pen->isValid()) {
- QPen pn(QColor(pen()->color()), pen()->width());
+ if (d->pen && d->pen->isValid()) {
+ QPen pn(QColor(d->pen->color()), d->pen->width());
p.setPen(pn);
} else {
p.setPen(Qt::NoPen);
}
p.setBrush(*d->gradient->gradient());
- if (d->_radius > 0.)
- p.drawRoundedRect(0, 0, width(), height(), d->_radius, d->_radius);
+ if (d->radius > 0.)
+ p.drawRoundedRect(0, 0, width(), height(), d->radius, d->radius);
else
p.drawRect(0, 0, width(), height());
p.setRenderHints(oldHints);
} else {
int offset = 0;
- const int pw = d->_pen && d->_pen->isValid() ? (d->_pen->width()+1)/2*2 : 0;
+ const int pw = d->pen && d->pen->isValid() ? (d->pen->width()+1)/2*2 : 0;
- if (d->_radius > 0) {
+ if (d->radius > 0) {
generateRoundedRect();
//### implicit conversion to int
- offset = int(d->_radius+1.5+pw);
+ offset = int(d->radius+1.5+pw);
} else {
generateBorderedRect();
offset = pw+1;
@@ -627,40 +649,40 @@ void QFxRect::drawRect(QPainter &p)
}
// Upper left
- p.drawPixmap(QRect(-pw/2, -pw/2, xOffset, yOffset), d->_rectImage, QRect(0, 0, xOffset, yOffset));
+ p.drawPixmap(QRect(-pw/2, -pw/2, xOffset, yOffset), d->rectImage, QRect(0, 0, xOffset, yOffset));
// Upper middle
if (xMiddles)
- p.drawPixmap(QRect(xOffset-pw/2, -pw/2, width() - xSide + pw, yOffset), d->_rectImage,
- QRect(d->_rectImage.width()/2, 0, 1, yOffset));
+ p.drawPixmap(QRect(xOffset-pw/2, -pw/2, width() - xSide + pw, yOffset), d->rectImage,
+ QRect(d->rectImage.width()/2, 0, 1, yOffset));
// Upper right
- p.drawPixmap(QPoint(width()-xOffset+pw/2, -pw/2), d->_rectImage,
- QRect(d->_rectImage.width()-xOffset, 0, xOffset, yOffset));
+ p.drawPixmap(QPoint(width()-xOffset+pw/2, -pw/2), d->rectImage,
+ QRect(d->rectImage.width()-xOffset, 0, xOffset, yOffset));
// Middle left
if (yMiddles)
- p.drawPixmap(QRect(-pw/2, yOffset-pw/2, xOffset, height() - ySide + pw), d->_rectImage,
- QRect(0, d->_rectImage.height()/2, xOffset, 1));
+ p.drawPixmap(QRect(-pw/2, yOffset-pw/2, xOffset, height() - ySide + pw), d->rectImage,
+ QRect(0, d->rectImage.height()/2, xOffset, 1));
// Middle
if (xMiddles && yMiddles)
// XXX paint errors in animation example
//p.fillRect(xOffset-pw/2, yOffset-pw/2, width() - xSide + pw, height() - ySide + pw, d->getColor());
- p.drawPixmap(QRect(xOffset-pw/2, yOffset-pw/2, width() - xSide + pw, height() - ySide + pw), d->_rectImage,
- QRect(d->_rectImage.width()/2, d->_rectImage.height()/2, 1, 1));
+ p.drawPixmap(QRect(xOffset-pw/2, yOffset-pw/2, width() - xSide + pw, height() - ySide + pw), d->rectImage,
+ QRect(d->rectImage.width()/2, d->rectImage.height()/2, 1, 1));
// Middle right
if (yMiddles)
- p.drawPixmap(QRect(width()-xOffset+pw/2, yOffset-pw/2, xOffset, height() - ySide + pw), d->_rectImage,
- QRect(d->_rectImage.width()-xOffset, d->_rectImage.height()/2, xOffset, 1));
+ p.drawPixmap(QRect(width()-xOffset+pw/2, yOffset-pw/2, xOffset, height() - ySide + pw), d->rectImage,
+ QRect(d->rectImage.width()-xOffset, d->rectImage.height()/2, xOffset, 1));
// Lower left
- p.drawPixmap(QPoint(-pw/2, height() - yOffset + pw/2), d->_rectImage, QRect(0, d->_rectImage.height() - yOffset, xOffset, yOffset));
+ p.drawPixmap(QPoint(-pw/2, height() - yOffset + pw/2), d->rectImage, QRect(0, d->rectImage.height() - yOffset, xOffset, yOffset));
// Lower Middle
if (xMiddles)
- p.drawPixmap(QRect(xOffset-pw/2, height() - yOffset +pw/2, width() - xSide + pw, yOffset), d->_rectImage,
- QRect(d->_rectImage.width()/2, d->_rectImage.height() - yOffset, 1, yOffset));
+ p.drawPixmap(QRect(xOffset-pw/2, height() - yOffset +pw/2, width() - xSide + pw, yOffset), d->rectImage,
+ QRect(d->rectImage.width()/2, d->rectImage.height() - yOffset, 1, yOffset));
// Lower Right
- p.drawPixmap(QPoint(width()-xOffset+pw/2, height() - yOffset+pw/2), d->_rectImage,
- QRect(d->_rectImage.width()-xOffset, d->_rectImage.height() - yOffset, xOffset, yOffset));
+ p.drawPixmap(QPoint(width()-xOffset+pw/2, height() - yOffset+pw/2), d->rectImage,
+ QRect(d->rectImage.width()-xOffset, d->rectImage.height() - yOffset, xOffset, yOffset));
}
}
#endif
@@ -671,7 +693,7 @@ void QFxRect::drawRect(QPainter &p)
void QFxRect::paintGLContents(GLPainter &p)
{
Q_D(QFxRect);
- if (d->_radius == 0 && (!d->_pen || !d->_pen->isValid())) {
+ if (d->radius == 0 && (!d->pen || !d->pen->isValid())) {
if (d->gradient) {
float widthV = width();
float heightV = height();
@@ -692,6 +714,7 @@ void QFxRect::paintGLContents(GLPainter &p)
colors[i+3] = c.alphaF() * p.activeOpacity; colors[i+7] = colors[i+3];
}
+ p.invalidate();
ColorShader *shader = basicShaders()->color();
shader->enable();
shader->setTransform(p.activeTransform);
@@ -702,27 +725,17 @@ void QFxRect::paintGLContents(GLPainter &p)
shader->disableAttributeArray(ColorShader::Vertices);
shader->disableAttributeArray(ColorShader::Colors);
} else {
- QGLShaderProgram *shader = p.useColorShader(d->getColor());
- float widthV = width();
- float heightV = height();
+ p.fillRect(QRectF(0, 0, width(), height()), d->getColor());
- GLfloat vertices[] = { 0, heightV,
- widthV, heightV,
- 0, 0,
- widthV, 0 };
-
- shader->setAttributeArray(ConstantColorShader::Vertices, vertices, 2);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- shader->disableAttributeArray(ConstantColorShader::Vertices);
}
} else {
qreal offset = 0;
- qreal pw = d->_pen && d->_pen->isValid() ? d->_pen->width() : 0.0;
+ qreal pw = d->pen && d->pen->isValid() ? d->pen->width() : 0.0;
- if (d->_radius > 0) {
+ if (d->radius > 0) {
generateRoundedRect();
- offset = d->_radius + pw+1.5;
+ offset = d->radius + pw+1.5;
} else {
generateBorderedRect();
offset = pw+1.5;
@@ -730,8 +743,8 @@ void QFxRect::paintGLContents(GLPainter &p)
QGLShaderProgram *shader = p.useTextureShader();
- float texWidth = d->_rectTexture.width();
- float texHeight = d->_rectTexture.height();
+ float texWidth = d->rectTexture->width();
+ float texHeight = d->rectTexture->height();
if (!texWidth || !texHeight)
return;
@@ -765,239 +778,163 @@ void QFxRect::paintGLContents(GLPainter &p)
if (offset==1)
texleft=texright=textop=texbottom=0.5;
+ texleft *= d->rectTexture->glWidth();
+ texright *= d->rectTexture->glWidth();
+ textop *= d->rectTexture->glHeight();
+ texbottom *= d->rectTexture->glHeight();
+
float vert1[] = { -pw/2, -pw/2,
-pw/2, imgtop,
imgleft, -pw/2,
+
+ -pw/2, imgtop,
+ imgleft, -pw/2,
+ imgleft, imgtop,
+
+ imgleft, -pw/2,
+ imgleft, imgtop,
+ imgright, -pw/2,
+
imgleft, imgtop,
imgright, -pw/2,
imgright, imgtop,
+
+ imgright, -pw/2,
+ imgright, imgtop,
widthV, -pw/2,
- widthV, imgtop };
- float tex1[] = { 0, 0,
- 0, textop,
- texleft, 0,
- texleft, textop,
- texright, 0,
- texright, textop,
- 1, 0,
- 1, textop };
- float vert2[] = { -pw/2, imgtop,
- -pw/2, imgbottom,
- imgleft, imgtop,
- imgleft, imgbottom,
+
imgright, imgtop,
- imgright, imgbottom,
+ widthV, -pw/2,
widthV, imgtop,
- widthV, imgbottom };
- float tex2[] = { 0, textop,
- 0, texbottom,
- texleft, textop,
- texleft, texbottom,
- texright, textop,
- texright, texbottom,
- 1, textop,
- 1, texbottom };
- float vert3[] = { -pw/2, heightV,
+
+ -pw/2, heightV,
-pw/2, imgbottom,
imgleft, heightV,
+
+ -pw/2, imgbottom,
+ imgleft, heightV,
+ imgleft, imgbottom,
+
+ imgleft, heightV,
imgleft, imgbottom,
imgright, heightV,
+
+ imgleft, imgbottom,
+ imgright, heightV,
+ imgright, imgbottom,
+
+ imgright, heightV,
+ imgright, imgbottom,
+ widthV, heightV,
+
imgright, imgbottom,
widthV, heightV,
+ widthV, imgbottom,
+
+ -pw/2, imgtop,
+ -pw/2, imgbottom,
+ imgleft, imgtop,
+
+ -pw/2, imgbottom,
+ imgleft, imgtop,
+ imgleft, imgbottom,
+
+ imgleft, imgtop,
+ imgleft, imgbottom,
+ imgright, imgtop,
+
+ imgleft, imgbottom,
+ imgright, imgtop,
+ imgright, imgbottom,
+
+ imgright, imgtop,
+ imgright, imgbottom,
+ widthV, imgtop,
+
+ imgright, imgbottom,
+ widthV, imgtop,
widthV, imgbottom };
- float tex3[] = { 0, 1,
- 0, texbottom,
- texleft, 1,
- texleft, texbottom,
- texright, 1,
- texright, texbottom,
- 1, 1,
- 1, texbottom };
- glBindTexture(GL_TEXTURE_2D, d->_rectTexture.texture());
- shader->setAttributeArray(SingleTextureShader::Vertices, vert1, 2);
- shader->setAttributeArray(SingleTextureShader::TextureCoords, tex1, 2);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);
- if (yMiddles) {
- shader->setAttributeArray(SingleTextureShader::Vertices, vert2, 2);
- shader->setAttributeArray(SingleTextureShader::TextureCoords, tex2, 2);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);
- }
- shader->setAttributeArray(SingleTextureShader::Vertices, vert3, 2);
- shader->setAttributeArray(SingleTextureShader::TextureCoords, tex3, 2);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);
+ float tex1[] = { 0, 0,
+ 0, textop,
+ texleft, 0,
- shader->disableAttributeArray(SingleTextureShader::Vertices);
- shader->disableAttributeArray(SingleTextureShader::TextureCoords);
- }
-}
-#elif defined(QFX_RENDER_OPENGL1)
-void QFxRect::paintGLContents(GLPainter &p)
-{
- Q_D(QFxRect);
+ 0, textop,
+ texleft, 0,
+ texleft, textop,
- float widthV = width();
- float heightV = height();
-
- glMatrixMode(GL_MODELVIEW);
- glLoadMatrixf(p.activeTransform.data());
-
- if (d->_radius == 0 && (!d->_pen || !d->_pen->isValid())) {
- GLfloat vertices[] = { 0, heightV,
- widthV, heightV,
- 0, 0,
- widthV, 0 };
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2,GL_FLOAT,0,vertices);
-
- QColor c;
- if (d->_gradcolor.isValid())
- c = d->_color;
- else
- c = d->getColor();
- float r = c.redF();
- float g = c.greenF();
- float b = c.blueF();
- float a = c.alphaF() * p.activeOpacity;
-
- float r2 = r; float g2 = g; float b2 = b; float a2 = a;
-
- if (d->_gradcolor.isValid()) {
- r2 = d->_gradcolor.redF();
- g2 = d->_gradcolor.greenF();
- b2 = d->_gradcolor.blueF();
- a2 = d->_gradcolor.alphaF() * p.activeOpacity;
- }
+ texleft, 0,
+ texleft, textop,
+ texright, 0,
- GLfloat colors[] = { r2, g2, b2, a2,
- r2, g2, b2, a2,
- r, g, b, a,
- r, g, b, a };
+ texleft, textop,
+ texright, 0,
+ texright, textop,
- glEnableClientState(GL_COLOR_ARRAY);
- glColorPointer(4,GL_FLOAT,0,colors);
+ texright, 0,
+ texright, textop,
+ d->rectTexture->glWidth(), 0,
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ texright, textop,
+ d->rectTexture->glWidth(), 0,
+ d->rectTexture->glWidth(), textop,
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
- } else {
- qreal offset = 0;
- if (d->_radius > 0) {
- generateRoundedRect();
- offset = d->_radius;
- } else {
- generateBorderedRect();
- offset = d->pen()->width();
- }
+ 0, d->rectTexture->glHeight(),
+ 0, texbottom,
+ texleft, d->rectTexture->glHeight(),
- if (p.activeOpacity == 1.) {
- GLint i = GL_REPLACE;
- glTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &i);
- } else {
- GLint i = GL_MODULATE;
- glTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &i);
- glColor4f(1, 1, 1, p.activeOpacity);
- }
+ 0, texbottom,
+ texleft, d->rectTexture->glHeight(),
+ texleft, texbottom,
- float texWidth = d->_rectTexture.width();
- float texHeight = d->_rectTexture.height();
- if (!texWidth || !texHeight)
- return;
+ texleft, d->rectTexture->glHeight(),
+ texleft, texbottom,
+ texright, d->rectTexture->glHeight(),
+
+ texleft, texbottom,
+ texright, d->rectTexture->glHeight(),
+ texright, texbottom,
+
+ texright, d->rectTexture->glHeight(),
+ texright, texbottom,
+ d->rectTexture->glWidth(), d->rectTexture->glHeight(),
+
+ texright, texbottom,
+ d->rectTexture->glWidth(), d->rectTexture->glHeight(),
+ d->rectTexture->glWidth(), texbottom,
- float widthV = width();
- float heightV = height();
-
- float texleft = 0;
- float texright = 1;
- float textop = 1;
- float texbottom = 0;
- float imgleft = 0;
- float imgright = widthV;
- float imgtop = 0;
- float imgbottom = heightV;
-
- texleft = float(offset) / texWidth;
- imgleft = offset;
- texright = 1. - float(offset) / texWidth;
- imgright = widthV - offset;
- textop = 1. - float(offset) / texHeight;
- imgtop = offset;
- texbottom = float(offset) / texHeight;
- imgbottom = heightV - offset;
-
- float vert1[] = { 0, 0,
- 0, imgtop,
- imgleft, 0,
- imgleft, imgtop,
- imgright, 0,
- imgright, imgtop,
- widthV, 0,
- widthV, imgtop };
- float tex1[] = { 0, 1,
0, textop,
- texleft, 1,
+ 0, texbottom,
texleft, textop,
- texright, 1,
- texright, textop,
- 1, 1,
- 1, textop };
- float vert2[] = { 0, imgtop,
- 0, imgbottom,
- imgleft, imgtop,
- imgleft, imgbottom,
- imgright, imgtop,
- imgright, imgbottom,
- widthV, imgtop,
- widthV, imgbottom };
- float tex2[] = { 0, textop,
+
0, texbottom,
texleft, textop,
texleft, texbottom,
+
+ texleft, textop,
+ texleft, texbottom,
texright, textop,
- texright, texbottom,
- 1, textop,
- 1, texbottom };
- float vert3[] = { 0, imgbottom,
- 0, heightV,
- imgleft, imgbottom,
- imgleft, heightV,
- imgright, imgbottom,
- imgright, heightV,
- widthV, imgbottom,
- widthV, heightV };
- float tex3[] = { 0, texbottom,
- 0, 0,
+
texleft, texbottom,
- texleft, 0,
+ texright, textop,
texright, texbottom,
- texright, 0,
- 1, texbottom,
- 1, 0 };
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, d->_rectTexture.texture());
+ texright, textop,
+ texright, texbottom,
+ d->rectTexture->glWidth(), textop,
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ texright, texbottom,
+ d->rectTexture->glWidth(), textop,
+ d->rectTexture->glWidth(), texbottom };
- glVertexPointer(2, GL_FLOAT, 0, vert1);
- glTexCoordPointer(2, GL_FLOAT, 0, tex1);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);
- glVertexPointer(2, GL_FLOAT, 0, vert2);
- glTexCoordPointer(2, GL_FLOAT, 0, tex2);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);
- glVertexPointer(2, GL_FLOAT, 0, vert3);
- glTexCoordPointer(2, GL_FLOAT, 0, tex3);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);
+ glBindTexture(GL_TEXTURE_2D, d->rectTexture->texture());
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisable(GL_TEXTURE_2D);
+ shader->setAttributeArray(SingleTextureShader::Vertices, vert1, 2);
+ shader->setAttributeArray(SingleTextureShader::TextureCoords, tex1, 2);
+ glDrawArrays(GL_TRIANGLES, 0, 36 + (yMiddles?18:0));
}
}
#endif
diff --git a/src/declarative/fx/qfxrect_p.h b/src/declarative/fx/qfxrect_p.h
index 8cafcbb..f662fac 100644
--- a/src/declarative/fx/qfxrect_p.h
+++ b/src/declarative/fx/qfxrect_p.h
@@ -68,14 +68,17 @@ class QFxRectPrivate : public QFxItemPrivate
Q_DECLARE_PUBLIC(QFxRect)
public:
- QFxRectPrivate()
- : gradient(0), _pen(0), _radius(0)
+ QFxRectPrivate() :
+#if defined(QFX_RENDER_OPENGL)
+ rectTexture(0),
+#endif //QFX_RENDER_OPENGL
+ gradient(0), pen(0), radius(0)
{
}
~QFxRectPrivate()
{
- delete _pen;
+ delete pen;
}
void init()
@@ -83,24 +86,24 @@ public:
}
#if defined(QFX_RENDER_OPENGL)
- GLTexture _rectTexture;
+ QSimpleCanvasItem::CachedTexture *rectTexture;
#endif
QColor getColor();
- QColor _color;
+ QColor color;
QFxGradient *gradient;
- QColor _tintColor;
- QFxPen *pen() {
- if (!_pen) {
+ QColor tintColor;
+ QFxPen *getPen() {
+ if (!pen) {
Q_Q(QFxRect);
- _pen = new QFxPen;
- QObject::connect(_pen, SIGNAL(updated()), q, SLOT(doUpdate()));
+ pen = new QFxPen;
+ QObject::connect(pen, SIGNAL(updated()), q, SLOT(doUpdate()));
}
- return _pen;
+ return pen;
}
- QFxPen *_pen;
- qreal _radius;
+ QFxPen *pen;
+ qreal radius;
#if defined(QFX_RENDER_QPAINTER)
- QPixmap _rectImage;
+ QPixmap rectImage;
#endif
};
diff --git a/src/declarative/fx/qfxtext.cpp b/src/declarative/fx/qfxtext.cpp
index 702ec81..031c0f8 100644
--- a/src/declarative/fx/qfxtext.cpp
+++ b/src/declarative/fx/qfxtext.cpp
@@ -696,7 +696,7 @@ void QFxTextPrivate::checkImgCache()
}
#if defined(QFX_RENDER_OPENGL)
- tex.setImage(imgCache.toImage());
+ tex.setImage(imgCache.toImage(), GLTexture::PowerOfTwo);
#endif
imgDirty = false;
@@ -755,6 +755,7 @@ void QFxText::paintContents(QPainter &p)
#elif defined(QFX_RENDER_OPENGL2)
void QFxText::paintGLContents(GLPainter &p)
{
+ //return;
Q_D(QFxText);
d->checkImgCache();
if (d->imgCache.isNull())
@@ -792,107 +793,42 @@ void QFxText::paintGLContents(GLPainter &p)
float widthV = d->imgCache.width();
float heightV = d->imgCache.height();
+ float glWidth = d->tex.glWidth();
+ float glHeight = d->tex.glHeight();
QGLShaderProgram *shader = p.useTextureShader();
+ float deltaX = 0.5 / qreal(d->tex.glSize().width());
+ float deltaY = 0.5 / qreal(d->tex.glSize().height());
+ glWidth -= deltaX;
+ glHeight -= deltaY;
+
GLfloat vertices[] = { x, y + heightV,
- x + widthV, y + heightV,
- x, y,
- x + widthV, y };
+ x + widthV, y + heightV,
+ x, y,
+
+ x + widthV, y + heightV,
+ x, y,
+ x + widthV, y };
- GLfloat texVertices[] = { 0, 0,
- 1, 0,
- 0, 1,
- 1, 1 };
+ GLfloat texVertices[] = { deltaX, deltaY,
+ glWidth, deltaY,
+ deltaX, glHeight,
+
+ glWidth, deltaY,
+ deltaX, glHeight,
+ glWidth, glHeight };
shader->setAttributeArray(SingleTextureShader::Vertices, vertices, 2);
shader->setAttributeArray(SingleTextureShader::TextureCoords, texVertices, 2);
glBindTexture(GL_TEXTURE_2D, d->tex.texture());
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ glDrawArrays(GL_TRIANGLES, 0, 6);
shader->disableAttributeArray(SingleTextureShader::Vertices);
shader->disableAttributeArray(SingleTextureShader::TextureCoords);
}
-#elif defined(QFX_RENDER_OPENGL)
-void QFxText::paintGLContents(GLPainter &p)
-{
- Q_D(QFxText);
- d->checkImgCache();
- if (d->imgCache.isNull())
- return;
-
- int w = width();
- int h = height();
-
- float x = 0;
- float y = 0;
-
- switch (d->hAlign) {
- case AlignLeft:
- x = 0;
- break;
- case AlignRight:
- x = w - d->imgCache.width();
- break;
- case AlignHCenter:
- x = (w - d->imgCache.width()) / 2;
- break;
- }
-
- switch (d->vAlign) {
- case AlignTop:
- y = 0;
- break;
- case AlignBottom:
- y = h - d->imgCache.height();
- break;
- case AlignVCenter:
- y = (h - d->imgCache.height()) / 2;
- break;
- }
-
- float widthV = d->imgCache.width();
- float heightV = d->imgCache.height();
-
- GLfloat vertices[] = { x, y + heightV,
- x + widthV, y + heightV,
- x, y,
- x + widthV, y };
-
- GLfloat texVertices[] = { 0, 0,
- 1, 0,
- 0, 1,
- 1, 1 };
-
- glMatrixMode(GL_MODELVIEW);
- glLoadMatrixf(p.activeTransform.data());
- glEnable(GL_TEXTURE_2D);
- if (p.activeOpacity == 1.) {
- GLint i = GL_REPLACE;
- glTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &i);
- } else {
- GLint i = GL_MODULATE;
- glTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &i);
- glColor4f(1, 1, 1, p.activeOpacity);
- }
-
- glBindTexture(GL_TEXTURE_2D, d->tex.texture());
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
- glVertexPointer(2, GL_FLOAT, 0, vertices);
- glTexCoordPointer(2, GL_FLOAT, 0, texVertices);
-
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisable(GL_TEXTURE_2D);
-}
-
#endif
void QFxText::componentComplete()
diff --git a/src/declarative/fx/qfxwebview.cpp b/src/declarative/fx/qfxwebview.cpp
index bfccd34..d15502b 100644
--- a/src/declarative/fx/qfxwebview.cpp
+++ b/src/declarative/fx/qfxwebview.cpp
@@ -287,7 +287,7 @@ void QFxWebView::componentComplete()
Q_D(QFxWebView);
switch (d->pending) {
case QFxWebViewPrivate::PendingUrl:
- setUrl(d->pending_url.toString());
+ setUrl(d->pending_url);
break;
case QFxWebViewPrivate::PendingHtml:
setHtml(d->pending_string, d->pending_url);
@@ -339,7 +339,7 @@ void QFxWebView::doLoadFinished(bool ok)
}
/*!
- \qmlproperty string WebView::url
+ \qmlproperty url WebView::url
This property holds the URL to the page displayed in this item.
Note that after this property is set, it may take some time
@@ -358,24 +358,22 @@ void QFxWebView::doLoadFinished(bool ok)
Emitted when loading of the URL successfully starts after
setUrl() is called.
*/
-QString QFxWebView::url() const
+QUrl QFxWebView::url() const
{
- return page()->mainFrame()->url().toString();
+ return page()->mainFrame()->url();
}
-void QFxWebView::setUrl(const QString &n)
+void QFxWebView::setUrl(const QUrl &url)
{
Q_D(QFxWebView);
- if (n == page()->mainFrame()->url().toString())
+ if (url == page()->mainFrame()->url())
return;
page()->setViewportSize(QSize(
d->idealwidth>0 ? d->idealwidth : width(),
d->idealheight>0 ? d->idealheight : height()));
- QUrl url(n);
- if (url.isRelative())
- url = qmlContext(this)->resolvedUrl(n);
+ Q_ASSERT(!url.isRelative());
if (isComponentComplete())
page()->mainFrame()->load(url);
@@ -942,7 +940,7 @@ void QFxWebView::setHtml(const QString &html, const QUrl &baseUrl)
d->idealwidth>0 ? d->idealwidth : width(),
d->idealheight>0 ? d->idealheight : height()));
if (isComponentComplete())
- page()->mainFrame()->setHtml(html, qmlContext(this)->resolvedUrl(baseUrl));
+ page()->mainFrame()->setHtml(html, baseUrl);
else {
d->pending = d->PendingHtml;
d->pending_url = baseUrl;
diff --git a/src/declarative/fx/qfxwebview.h b/src/declarative/fx/qfxwebview.h
index 28ef6c3..f30fd0d 100644
--- a/src/declarative/fx/qfxwebview.h
+++ b/src/declarative/fx/qfxwebview.h
@@ -90,7 +90,7 @@ class Q_DECLARATIVE_EXPORT QFxWebView : public QFxPaintedItem
Q_PROPERTY(int idealWidth READ idealWidth WRITE setIdealWidth NOTIFY idealWidthChanged)
Q_PROPERTY(int idealHeight READ idealHeight WRITE setIdealHeight NOTIFY idealHeightChanged)
- Q_PROPERTY(QString url READ url WRITE setUrl NOTIFY urlChanged)
+ Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged)
Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged)
Q_PROPERTY(bool interactive READ interactive WRITE setInteractive NOTIFY interactiveChanged)
@@ -108,8 +108,8 @@ public:
QFxWebView(QFxItem *parent=0);
~QFxWebView();
- QString url() const;
- void setUrl(const QString &);
+ QUrl url() const;
+ void setUrl(const QUrl &);
QString title() const;
diff --git a/src/declarative/opengl/gltexture.cpp b/src/declarative/opengl/gltexture.cpp
index 199b362..c2a02df 100644
--- a/src/declarative/opengl/gltexture.cpp
+++ b/src/declarative/opengl/gltexture.cpp
@@ -79,7 +79,8 @@ public:
GLTexturePrivate(GLTexture *_q)
: q(_q), texture(0), width(0), height(0),
horizWrap(GLTexture::Repeat), vertWrap(GLTexture::Repeat),
- minFilter(GLTexture::Linear), magFilter(GLTexture::Linear)
+ minFilter(GLTexture::Linear), magFilter(GLTexture::Linear),
+ glWidth(1.), glHeight(1.)
{
}
@@ -92,6 +93,10 @@ public:
GLTexture::FilterMode minFilter;
GLTexture::FilterMode magFilter;
+ qreal glWidth;
+ qreal glHeight;
+ QSize glSize;
+
void genTexture();
};
@@ -167,32 +172,74 @@ static inline int npot(int size)
by explicitly setting the size, or by previously setting an image), it will
be destroyed and a new texture created with \a img's contents and size.
*/
-void GLTexture::setImage(const QImage &img)
+void GLTexture::setImage(const QImage &img, ImageMode mode)
{
if (img.isNull())
return;
d->genTexture();
- //QImage dataImage = img.scaled(npot(img.width()), npot(img.height()), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
- QImage dataImage = QGLWidget_convertToGLFormat(img);
-
glBindTexture(GL_TEXTURE_2D, d->texture);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dataImage.width(),
- dataImage.height(), 0,
- (dataImage.format() == QImage::Format_ARGB32)?GL_RGBA:GL_RGB,
- GL_UNSIGNED_BYTE, dataImage.bits());
- d->width = dataImage.width();
- d->height = dataImage.height();
-
-#if 0
- glGenerateMipmap(GL_TEXTURE_2D);
- int e = glGetError();
- if (d->magFilter == Linear)
- setMagFilter(MipmapLinear);
- if (d->minFilter == Linear)
- setMinFilter((GLTexture::FilterMode)GL_LINEAR_MIPMAP_LINEAR);
-#endif
+
+ if (mode == NonPowerOfTwo) {
+
+ if (img.format() == QImage::Format_RGB16) {
+ QImage dataImage = img.mirrored();
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, dataImage.width(),
+ dataImage.height(), 0,
+ GL_RGB,
+ GL_UNSIGNED_SHORT_5_6_5, dataImage.bits());
+ } else {
+ QImage dataImage = QGLWidget_convertToGLFormat(img);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dataImage.width(),
+ dataImage.height(), 0,
+ (dataImage.format() == QImage::Format_ARGB32)?GL_RGBA:GL_RGB,
+ GL_UNSIGNED_BYTE, dataImage.bits());
+ }
+ d->glWidth = 1.;
+ d->glHeight = 1.;
+ d->glSize = img.size();
+
+ } else {
+ // mode == PowerOfTwo
+ int max = (img.width() > img.height())?img.width():img.height();
+ max = npot(max);
+
+ if (img.format() == QImage::Format_RGB16) {
+ QImage dataImage = img.mirrored();
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, max,
+ max, 0,
+ GL_RGB,
+ GL_UNSIGNED_SHORT_5_6_5, 0);
+
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, dataImage.width(),
+ dataImage.height(), GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
+ dataImage.bits());
+
+ } else {
+ QImage dataImage = QGLWidget_convertToGLFormat(img);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, max,
+ max, 0,
+ (dataImage.format() == QImage::Format_ARGB32)?GL_RGBA:GL_RGB,
+ GL_UNSIGNED_BYTE, 0);
+
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, dataImage.width(),
+ dataImage.height(),
+ (dataImage.format() == QImage::Format_ARGB32)?GL_RGBA:GL_RGB,
+ GL_UNSIGNED_BYTE, dataImage.bits());
+ }
+
+ d->glWidth = qreal(img.width()) / qreal(max);
+ d->glHeight = qreal(img.height()) / qreal(max);
+ d->glSize = QSize(max, max);
+ }
+
+ d->width = img.width();
+ d->height = img.height();
}
void GLTexture::copyImage(const QImage &img, const QPoint &point,
@@ -219,6 +266,21 @@ int GLTexture::height() const
return d->height;
}
+qreal GLTexture::glWidth() const
+{
+ return d->glWidth;
+}
+
+qreal GLTexture::glHeight() const
+{
+ return d->glHeight;
+}
+
+QSize GLTexture::glSize() const
+{
+ return d->glSize;
+}
+
/*!
Sets the \a size of the texture. This will destroy the current contents of
the texture. If an image has been assigned, it will need to be reassigned
diff --git a/src/declarative/opengl/gltexture.h b/src/declarative/opengl/gltexture.h
index 787c9a5..c08d68f 100644
--- a/src/declarative/opengl/gltexture.h
+++ b/src/declarative/opengl/gltexture.h
@@ -69,11 +69,15 @@ public:
bool isNull() const;
void clear();
- void setImage(const QImage &);
+ enum ImageMode { NonPowerOfTwo, PowerOfTwo };
+ void setImage(const QImage &, ImageMode = NonPowerOfTwo);
void copyImage(const QImage &, const QPoint & = QPoint(0, 0), const QRect & = QRect());
int width() const;
int height() const;
+ qreal glWidth() const;
+ qreal glHeight() const;
+ QSize glSize() const;
QSize size() const;
void setSize(const QSize &);
diff --git a/src/declarative/qml/parser/parser.pri b/src/declarative/qml/parser/parser.pri
index 72bd46c..610b2aa 100644
--- a/src/declarative/qml/parser/parser.pri
+++ b/src/declarative/qml/parser/parser.pri
@@ -1,22 +1,22 @@
INCLUDEPATH += $$PWD
-HEADERS += $$PWD/javascriptast_p.h \
- $$PWD/javascriptastfwd_p.h \
- $$PWD/javascriptastvisitor_p.h \
- $$PWD/javascriptengine_p.h \
- $$PWD/javascriptgrammar_p.h \
- $$PWD/javascriptlexer_p.h \
- $$PWD/javascriptmemorypool_p.h \
- $$PWD/javascriptnodepool_p.h \
- $$PWD/javascriptparser_p.h \
- $$PWD/javascriptprettypretty_p.h
+HEADERS += $$PWD/qmljsast_p.h \
+ $$PWD/qmljsastfwd_p.h \
+ $$PWD/qmljsastvisitor_p.h \
+ $$PWD/qmljsengine_p.h \
+ $$PWD/qmljsgrammar_p.h \
+ $$PWD/qmljslexer_p.h \
+ $$PWD/qmljsmemorypool_p.h \
+ $$PWD/qmljsnodepool_p.h \
+ $$PWD/qmljsparser_p.h \
+ $$PWD/qmljsprettypretty_p.h
-SOURCES += $$PWD/javascriptast.cpp \
- $$PWD/javascriptastvisitor.cpp \
- $$PWD/javascriptengine_p.cpp \
- $$PWD/javascriptgrammar.cpp \
- $$PWD/javascriptlexer.cpp \
- $$PWD/javascriptprettypretty.cpp \
- $$PWD/javascriptparser.cpp
+SOURCES += $$PWD/qmljsast.cpp \
+ $$PWD/qmljsastvisitor.cpp \
+ $$PWD/qmljsengine_p.cpp \
+ $$PWD/qmljsgrammar.cpp \
+ $$PWD/qmljslexer.cpp \
+ $$PWD/qmljsprettypretty.cpp \
+ $$PWD/qmljsparser.cpp
diff --git a/src/declarative/qml/parser/javascript.g b/src/declarative/qml/parser/qmljs.g
index 8cabeea..907ca52 100644
--- a/src/declarative/qml/parser/javascript.g
+++ b/src/declarative/qml/parser/qmljs.g
@@ -42,11 +42,11 @@
--
----------------------------------------------------------------------------
-%parser JavaScriptGrammar
-%decl javascriptparser_p.h
-%impl javascriptparser.cpp
+%parser QmlJSGrammar
+%decl qmljsparser_p.h
+%impl qmljsparser.cpp
%expect 2
-%expect-rr 2
+%expect-rr 3
%token T_AND "&" T_AND_AND "&&" T_AND_EQ "&="
%token T_BREAK "break" T_CASE "case" T_CATCH "catch"
@@ -137,10 +137,10 @@
#include <string.h>
-#include "javascriptengine_p.h"
-#include "javascriptlexer_p.h"
-#include "javascriptast_p.h"
-#include "javascriptnodepool_p.h"
+#include "qmljsengine_p.h"
+#include "qmljslexer_p.h"
+#include "qmljsast_p.h"
+#include "qmljsnodepool_p.h"
./
@@ -198,16 +198,16 @@
//
//
-// This file is automatically generated from javascript.g.
+// This file is automatically generated from qmljs.g.
// Changes will be lost.
//
-#ifndef JAVASCRIPTPARSER_P_H
-#define JAVASCRIPTPARSER_P_H
+#ifndef QMLJSPARSER_P_H
+#define QMLJSPARSER_P_H
-#include "javascriptgrammar_p.h"
-#include "javascriptast_p.h"
-#include "javascriptengine_p.h"
+#include "qmljsgrammar_p.h"
+#include "qmljsast_p.h"
+#include "qmljsengine_p.h"
#include <QtCore/QList>
@@ -215,7 +215,7 @@ QT_BEGIN_NAMESPACE
class QString;
-namespace JavaScript {
+namespace QmlJS {
class Engine;
class NameId;
@@ -262,6 +262,7 @@ public:
AST::UiArrayBinding *UiArrayBinding;
AST::UiObjectMember *UiObjectMember;
AST::UiObjectMemberList *UiObjectMemberList;
+ AST::UiArrayMemberList *UiArrayMemberList;
AST::UiQualifiedId *UiQualifiedId;
};
@@ -337,7 +338,7 @@ protected:
QList<DiagnosticMessage> diagnostic_messages;
};
-} // end of namespace JavaScript
+} // end of namespace QmlJS
:/
@@ -345,15 +346,15 @@ protected:
/.
-#include "javascriptparser_p.h"
+#include "qmljsparser_p.h"
#include <QVarLengthArray>
//
-// This file is automatically generated from javascript.g.
+// This file is automatically generated from qmljs.g.
// Changes will be lost.
//
-using namespace JavaScript;
+using namespace QmlJS;
QT_BEGIN_NAMESPACE
@@ -568,15 +569,16 @@ case $rule_number: {
UiArrayMemberList: UiObjectDefinition ;
/.
case $rule_number: {
- sym(1).Node = makeAstNode<AST::UiObjectMemberList> (driver->nodePool(), sym(1).UiObjectMember);
+ sym(1).Node = makeAstNode<AST::UiArrayMemberList> (driver->nodePool(), sym(1).UiObjectMember);
} break;
./
UiArrayMemberList: UiArrayMemberList T_COMMA UiObjectDefinition ;
/.
case $rule_number: {
- AST::UiObjectMemberList *node = makeAstNode<AST:: UiObjectMemberList> (driver->nodePool(),
- sym(1).UiObjectMemberList, sym(3).UiObjectMember);
+ AST::UiArrayMemberList *node = makeAstNode<AST::UiArrayMemberList> (driver->nodePool(),
+ sym(1).UiArrayMemberList, sym(3).UiObjectMember);
+ node->commaToken = loc(2);
sym(1).Node = node;
} break;
./
@@ -616,7 +618,7 @@ UiObjectMember: UiQualifiedId T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET ;
/.
case $rule_number: {
AST::UiArrayBinding *node = makeAstNode<AST::UiArrayBinding> (driver->nodePool(), sym(1).UiQualifiedId->finish(),
- sym(4).UiObjectMemberList->finish());
+ sym(4).UiArrayMemberList->finish());
node->colonToken = loc(2);
node->lbracketToken = loc(3);
node->rbracketToken = loc(5);
@@ -808,7 +810,7 @@ JsIdentifier: T_IDENTIFIER;
JsIdentifier: T_PROPERTY ;
/.
case $rule_number: {
- QString s = QLatin1String(JavaScriptGrammar::spell[T_PROPERTY]);
+ QString s = QLatin1String(QmlJSGrammar::spell[T_PROPERTY]);
sym(1).sval = driver->intern(s.constData(), s.length());
break;
}
@@ -817,7 +819,7 @@ case $rule_number: {
JsIdentifier: T_SIGNAL ;
/.
case $rule_number: {
- QString s = QLatin1String(JavaScriptGrammar::spell[T_SIGNAL]);
+ QString s = QLatin1String(QmlJSGrammar::spell[T_SIGNAL]);
sym(1).sval = driver->intern(s.constData(), s.length());
break;
}
@@ -2696,7 +2698,7 @@ case $rule_number: {
} break;
./
---JavaScriptProgram: SourceElements ;
+--QmlJSProgram: SourceElements ;
--/.
--case $rule_number: {
-- sym(1).Node = makeAstNode<AST::Program> (driver->nodePool(), sym(1).SourceElements->finish ());
@@ -2875,5 +2877,5 @@ QT_END_NAMESPACE
-#endif // JAVASCRIPTPARSER_P_H
+#endif // QMLJSPARSER_P_H
:/
diff --git a/src/declarative/qml/parser/javascriptast.cpp b/src/declarative/qml/parser/qmljsast.cpp
index 130229b..d10c071 100644
--- a/src/declarative/qml/parser/javascriptast.cpp
+++ b/src/declarative/qml/parser/qmljsast.cpp
@@ -39,15 +39,15 @@
**
****************************************************************************/
-#include "javascriptast_p.h"
+#include "qmljsast_p.h"
-#include "javascriptastvisitor_p.h"
+#include "qmljsastvisitor_p.h"
QT_BEGIN_NAMESPACE
-namespace JavaScript { namespace AST {
+namespace QmlJS { namespace AST {
int NumericLiteral::suffixLength[] = {
0, // noSuffix
@@ -893,7 +893,7 @@ void UiArrayBinding::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
acceptChild(qualifiedId, visitor);
- for (UiObjectMemberList *it = members; it; it = it->next)
+ for (UiArrayMemberList *it = members; it; it = it->next)
acceptChild(it->member, visitor);
}
@@ -910,6 +910,16 @@ void UiObjectMemberList::accept0(Visitor *visitor)
visitor->endVisit(this);
}
+void UiArrayMemberList::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ for (UiArrayMemberList *it = this; it; it = it->next)
+ acceptChild(it->member, visitor);
+ }
+
+ visitor->endVisit(this);
+}
+
void UiQualifiedId::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
@@ -945,7 +955,7 @@ void UiSourceElement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-} } // namespace JavaScript::AST
+} } // namespace QmlJS::AST
QT_END_NAMESPACE
diff --git a/src/declarative/qml/parser/javascriptast_p.h b/src/declarative/qml/parser/qmljsast_p.h
index 23d59e5..8dc32ed 100644
--- a/src/declarative/qml/parser/javascriptast_p.h
+++ b/src/declarative/qml/parser/qmljsast_p.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef JAVASCRIPTAST_P_H
-#define JAVASCRIPTAST_P_H
+#ifndef QMLJSAST_P_H
+#define QMLJSAST_P_H
//
// W A R N I N G
@@ -53,12 +53,12 @@
// We mean it.
//
-#include "javascriptastvisitor_p.h"
+#include "qmljsastvisitor_p.h"
#include <QtCore/QString>
QT_BEGIN_NAMESPACE
-#define JAVASCRIPT_DECLARE_AST_NODE(name) \
+#define QMLJS_DECLARE_AST_NODE(name) \
enum { K = Kind_##name };
namespace QSOperator // ### rename
@@ -104,7 +104,7 @@ enum Op {
} // namespace QSOperator
-namespace JavaScript {
+namespace QmlJS {
class NameId;
namespace AST {
@@ -207,6 +207,7 @@ public:
Kind_UiObjectDefinition,
Kind_UiObjectInitializer,
Kind_UiObjectMemberList,
+ Kind_UiArrayMemberList,
Kind_UiProgram,
Kind_UiPublicMember,
Kind_UiQualifiedId,
@@ -270,7 +271,7 @@ public:
class NestedExpression: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(NestedExpression)
+ QMLJS_DECLARE_AST_NODE(NestedExpression)
NestedExpression(ExpressionNode *expression)
: expression(expression)
@@ -293,7 +294,7 @@ public:
class ThisExpression: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(ThisExpression)
+ QMLJS_DECLARE_AST_NODE(ThisExpression)
ThisExpression() { kind = K; }
virtual ~ThisExpression() {}
@@ -313,7 +314,7 @@ public:
class IdentifierExpression: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(IdentifierExpression)
+ QMLJS_DECLARE_AST_NODE(IdentifierExpression)
IdentifierExpression(NameId *n):
name (n) { kind = K; }
@@ -336,7 +337,7 @@ public:
class NullExpression: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(NullExpression)
+ QMLJS_DECLARE_AST_NODE(NullExpression)
NullExpression() { kind = K; }
virtual ~NullExpression() {}
@@ -356,7 +357,7 @@ public:
class TrueLiteral: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(TrueLiteral)
+ QMLJS_DECLARE_AST_NODE(TrueLiteral)
TrueLiteral() { kind = K; }
virtual ~TrueLiteral() {}
@@ -376,7 +377,7 @@ public:
class FalseLiteral: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(FalseLiteral)
+ QMLJS_DECLARE_AST_NODE(FalseLiteral)
FalseLiteral() { kind = K; }
virtual ~FalseLiteral() {}
@@ -396,9 +397,9 @@ public:
class NumericLiteral: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(NumericLiteral)
+ QMLJS_DECLARE_AST_NODE(NumericLiteral)
- enum Suffix { // ### keep it in sync with the Suffix enum in javascriptlexer_p.h
+ enum Suffix { // ### keep it in sync with the Suffix enum in qmljslexer_p.h
noSuffix,
emSuffix,
exSuffix,
@@ -441,7 +442,7 @@ public:
class StringLiteral: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(StringLiteral)
+ QMLJS_DECLARE_AST_NODE(StringLiteral)
StringLiteral(NameId *v):
value (v) { kind = K; }
@@ -464,7 +465,7 @@ public:
class RegExpLiteral: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(RegExpLiteral)
+ QMLJS_DECLARE_AST_NODE(RegExpLiteral)
RegExpLiteral(NameId *p, int f):
pattern (p), flags (f) { kind = K; }
@@ -488,7 +489,7 @@ public:
class ArrayLiteral: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(ArrayLiteral)
+ QMLJS_DECLARE_AST_NODE(ArrayLiteral)
ArrayLiteral(Elision *e):
elements (0), elision (e)
@@ -523,7 +524,7 @@ public:
class ObjectLiteral: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(ObjectLiteral)
+ QMLJS_DECLARE_AST_NODE(ObjectLiteral)
ObjectLiteral():
properties (0) { kind = K; }
@@ -550,7 +551,7 @@ public:
class ElementList: public Node
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(ElementList)
+ QMLJS_DECLARE_AST_NODE(ElementList)
ElementList(Elision *e, ExpressionNode *expr):
elision (e), expression (expr), next (this)
@@ -585,7 +586,7 @@ public:
class Elision: public Node
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(Elision)
+ QMLJS_DECLARE_AST_NODE(Elision)
Elision():
next (this) { kind = K; }
@@ -616,7 +617,7 @@ public:
class PropertyNameAndValueList: public Node
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(PropertyNameAndValueList)
+ QMLJS_DECLARE_AST_NODE(PropertyNameAndValueList)
PropertyNameAndValueList(PropertyName *n, ExpressionNode *v):
name (n), value (v), next (this)
@@ -652,7 +653,7 @@ public:
class PropertyName: public Node
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(PropertyName)
+ QMLJS_DECLARE_AST_NODE(PropertyName)
PropertyName() { kind = K; }
virtual ~PropertyName() {}
@@ -664,7 +665,7 @@ public:
class IdentifierPropertyName: public PropertyName
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(IdentifierPropertyName)
+ QMLJS_DECLARE_AST_NODE(IdentifierPropertyName)
IdentifierPropertyName(NameId *n):
id (n) { kind = K; }
@@ -680,7 +681,7 @@ public:
class StringLiteralPropertyName: public PropertyName
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(StringLiteralPropertyName)
+ QMLJS_DECLARE_AST_NODE(StringLiteralPropertyName)
StringLiteralPropertyName(NameId *n):
id (n) { kind = K; }
@@ -695,7 +696,7 @@ public:
class NumericLiteralPropertyName: public PropertyName
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(NumericLiteralPropertyName)
+ QMLJS_DECLARE_AST_NODE(NumericLiteralPropertyName)
NumericLiteralPropertyName(double n):
id (n) { kind = K; }
@@ -710,7 +711,7 @@ public:
class ArrayMemberExpression: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(ArrayMemberExpression)
+ QMLJS_DECLARE_AST_NODE(ArrayMemberExpression)
ArrayMemberExpression(ExpressionNode *b, ExpressionNode *e):
base (b), expression (e)
@@ -736,7 +737,7 @@ public:
class FieldMemberExpression: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(FieldMemberExpression)
+ QMLJS_DECLARE_AST_NODE(FieldMemberExpression)
FieldMemberExpression(ExpressionNode *b, NameId *n):
base (b), name (n)
@@ -762,7 +763,7 @@ public:
class NewMemberExpression: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(NewMemberExpression)
+ QMLJS_DECLARE_AST_NODE(NewMemberExpression)
NewMemberExpression(ExpressionNode *b, ArgumentList *a):
base (b), arguments (a)
@@ -789,7 +790,7 @@ public:
class NewExpression: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(NewExpression)
+ QMLJS_DECLARE_AST_NODE(NewExpression)
NewExpression(ExpressionNode *e):
expression (e) { kind = K; }
@@ -812,7 +813,7 @@ public:
class CallExpression: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(CallExpression)
+ QMLJS_DECLARE_AST_NODE(CallExpression)
CallExpression(ExpressionNode *b, ArgumentList *a):
base (b), arguments (a)
@@ -838,7 +839,7 @@ public:
class ArgumentList: public Node
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(ArgumentList)
+ QMLJS_DECLARE_AST_NODE(ArgumentList)
ArgumentList(ExpressionNode *e):
expression (e), next (this)
@@ -872,7 +873,7 @@ public:
class PostIncrementExpression: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(PostIncrementExpression)
+ QMLJS_DECLARE_AST_NODE(PostIncrementExpression)
PostIncrementExpression(ExpressionNode *b):
base (b) { kind = K; }
@@ -895,7 +896,7 @@ public:
class PostDecrementExpression: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(PostDecrementExpression)
+ QMLJS_DECLARE_AST_NODE(PostDecrementExpression)
PostDecrementExpression(ExpressionNode *b):
base (b) { kind = K; }
@@ -918,7 +919,7 @@ public:
class DeleteExpression: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(DeleteExpression)
+ QMLJS_DECLARE_AST_NODE(DeleteExpression)
DeleteExpression(ExpressionNode *e):
expression (e) { kind = K; }
@@ -940,7 +941,7 @@ public:
class VoidExpression: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(VoidExpression)
+ QMLJS_DECLARE_AST_NODE(VoidExpression)
VoidExpression(ExpressionNode *e):
expression (e) { kind = K; }
@@ -963,7 +964,7 @@ public:
class TypeOfExpression: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(TypeOfExpression)
+ QMLJS_DECLARE_AST_NODE(TypeOfExpression)
TypeOfExpression(ExpressionNode *e):
expression (e) { kind = K; }
@@ -986,7 +987,7 @@ public:
class PreIncrementExpression: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(PreIncrementExpression)
+ QMLJS_DECLARE_AST_NODE(PreIncrementExpression)
PreIncrementExpression(ExpressionNode *e):
expression (e) { kind = K; }
@@ -1009,7 +1010,7 @@ public:
class PreDecrementExpression: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(PreDecrementExpression)
+ QMLJS_DECLARE_AST_NODE(PreDecrementExpression)
PreDecrementExpression(ExpressionNode *e):
expression (e) { kind = K; }
@@ -1032,7 +1033,7 @@ public:
class UnaryPlusExpression: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(UnaryPlusExpression)
+ QMLJS_DECLARE_AST_NODE(UnaryPlusExpression)
UnaryPlusExpression(ExpressionNode *e):
expression (e) { kind = K; }
@@ -1055,7 +1056,7 @@ public:
class UnaryMinusExpression: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(UnaryMinusExpression)
+ QMLJS_DECLARE_AST_NODE(UnaryMinusExpression)
UnaryMinusExpression(ExpressionNode *e):
expression (e) { kind = K; }
@@ -1078,7 +1079,7 @@ public:
class TildeExpression: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(TildeExpression)
+ QMLJS_DECLARE_AST_NODE(TildeExpression)
TildeExpression(ExpressionNode *e):
expression (e) { kind = K; }
@@ -1101,7 +1102,7 @@ public:
class NotExpression: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(NotExpression)
+ QMLJS_DECLARE_AST_NODE(NotExpression)
NotExpression(ExpressionNode *e):
expression (e) { kind = K; }
@@ -1124,7 +1125,7 @@ public:
class BinaryExpression: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(BinaryExpression)
+ QMLJS_DECLARE_AST_NODE(BinaryExpression)
BinaryExpression(ExpressionNode *l, int o, ExpressionNode *r):
left (l), op (o), right (r)
@@ -1152,7 +1153,7 @@ public:
class ConditionalExpression: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(ConditionalExpression)
+ QMLJS_DECLARE_AST_NODE(ConditionalExpression)
ConditionalExpression(ExpressionNode *e, ExpressionNode *t, ExpressionNode *f):
expression (e), ok (t), ko (f)
@@ -1179,7 +1180,7 @@ public:
class Expression: public ExpressionNode // ### rename
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(Expression)
+ QMLJS_DECLARE_AST_NODE(Expression)
Expression(ExpressionNode *l, ExpressionNode *r):
left (l), right (r) { kind = K; }
@@ -1203,7 +1204,7 @@ public:
class Block: public Statement
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(Block)
+ QMLJS_DECLARE_AST_NODE(Block)
Block(StatementList *slist):
statements (slist) { kind = K; }
@@ -1227,7 +1228,7 @@ public:
class StatementList: public Node
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(StatementList)
+ QMLJS_DECLARE_AST_NODE(StatementList)
StatementList(Statement *stmt):
statement (stmt), next (this)
@@ -1260,7 +1261,7 @@ public:
class VariableStatement: public Statement
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(VariableStatement)
+ QMLJS_DECLARE_AST_NODE(VariableStatement)
VariableStatement(VariableDeclarationList *vlist):
declarations (vlist)
@@ -1285,7 +1286,7 @@ public:
class VariableDeclaration: public Node
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(VariableDeclaration)
+ QMLJS_DECLARE_AST_NODE(VariableDeclaration)
VariableDeclaration(NameId *n, ExpressionNode *e):
name (n), expression (e), readOnly(false)
@@ -1305,7 +1306,7 @@ public:
class VariableDeclarationList: public Node
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(VariableDeclarationList)
+ QMLJS_DECLARE_AST_NODE(VariableDeclarationList)
VariableDeclarationList(VariableDeclaration *decl):
declaration (decl), next (this)
@@ -1344,7 +1345,7 @@ public:
class EmptyStatement: public Statement
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(EmptyStatement)
+ QMLJS_DECLARE_AST_NODE(EmptyStatement)
EmptyStatement() { kind = K; }
virtual ~EmptyStatement() {}
@@ -1364,7 +1365,7 @@ public:
class ExpressionStatement: public Statement
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(ExpressionStatement)
+ QMLJS_DECLARE_AST_NODE(ExpressionStatement)
ExpressionStatement(ExpressionNode *e):
expression (e) { kind = K; }
@@ -1387,7 +1388,7 @@ public:
class IfStatement: public Statement
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(IfStatement)
+ QMLJS_DECLARE_AST_NODE(IfStatement)
IfStatement(ExpressionNode *e, Statement *t, Statement *f = 0):
expression (e), ok (t), ko (f)
@@ -1421,7 +1422,7 @@ public:
class DoWhileStatement: public Statement
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(DoWhileStatement)
+ QMLJS_DECLARE_AST_NODE(DoWhileStatement)
DoWhileStatement(Statement *stmt, ExpressionNode *e):
statement (stmt), expression (e)
@@ -1450,7 +1451,7 @@ public:
class WhileStatement: public Statement
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(WhileStatement)
+ QMLJS_DECLARE_AST_NODE(WhileStatement)
WhileStatement(ExpressionNode *e, Statement *stmt):
expression (e), statement (stmt)
@@ -1477,7 +1478,7 @@ public:
class ForStatement: public Statement
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(ForStatement)
+ QMLJS_DECLARE_AST_NODE(ForStatement)
ForStatement(ExpressionNode *i, ExpressionNode *c, ExpressionNode *e, Statement *stmt):
initialiser (i), condition (c), expression (e), statement (stmt)
@@ -1508,7 +1509,7 @@ public:
class LocalForStatement: public Statement
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(LocalForStatement)
+ QMLJS_DECLARE_AST_NODE(LocalForStatement)
LocalForStatement(VariableDeclarationList *vlist, ExpressionNode *c, ExpressionNode *e, Statement *stmt):
declarations (vlist), condition (c), expression (e), statement (stmt)
@@ -1540,7 +1541,7 @@ public:
class ForEachStatement: public Statement
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(ForEachStatement)
+ QMLJS_DECLARE_AST_NODE(ForEachStatement)
ForEachStatement(ExpressionNode *i, ExpressionNode *e, Statement *stmt):
initialiser (i), expression (e), statement (stmt)
@@ -1569,7 +1570,7 @@ public:
class LocalForEachStatement: public Statement
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(LocalForEachStatement)
+ QMLJS_DECLARE_AST_NODE(LocalForEachStatement)
LocalForEachStatement(VariableDeclaration *v, ExpressionNode *e, Statement *stmt):
declaration (v), expression (e), statement (stmt)
@@ -1599,7 +1600,7 @@ public:
class ContinueStatement: public Statement
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(ContinueStatement)
+ QMLJS_DECLARE_AST_NODE(ContinueStatement)
ContinueStatement(NameId *l = 0):
label (l) { kind = K; }
@@ -1624,7 +1625,7 @@ public:
class BreakStatement: public Statement
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(BreakStatement)
+ QMLJS_DECLARE_AST_NODE(BreakStatement)
BreakStatement(NameId *l = 0):
label (l) { kind = K; }
@@ -1649,7 +1650,7 @@ public:
class ReturnStatement: public Statement
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(ReturnStatement)
+ QMLJS_DECLARE_AST_NODE(ReturnStatement)
ReturnStatement(ExpressionNode *e):
expression (e) { kind = K; }
@@ -1673,7 +1674,7 @@ public:
class WithStatement: public Statement
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(WithStatement)
+ QMLJS_DECLARE_AST_NODE(WithStatement)
WithStatement(ExpressionNode *e, Statement *stmt):
expression (e), statement (stmt)
@@ -1700,7 +1701,7 @@ public:
class CaseBlock: public Node
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(CaseBlock)
+ QMLJS_DECLARE_AST_NODE(CaseBlock)
CaseBlock(CaseClauses *c, DefaultClause *d = 0, CaseClauses *r = 0):
clauses (c), defaultClause (d), moreClauses (r)
@@ -1721,7 +1722,7 @@ public:
class SwitchStatement: public Statement
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(SwitchStatement)
+ QMLJS_DECLARE_AST_NODE(SwitchStatement)
SwitchStatement(ExpressionNode *e, CaseBlock *b):
expression (e), block (b)
@@ -1748,7 +1749,7 @@ public:
class CaseClauses: public Node
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(CaseClauses)
+ QMLJS_DECLARE_AST_NODE(CaseClauses)
CaseClauses(CaseClause *c):
clause (c), next (this)
@@ -1781,7 +1782,7 @@ public:
class CaseClause: public Node
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(CaseClause)
+ QMLJS_DECLARE_AST_NODE(CaseClause)
CaseClause(ExpressionNode *e, StatementList *slist):
expression (e), statements (slist)
@@ -1801,7 +1802,7 @@ public:
class DefaultClause: public Node
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(DefaultClause)
+ QMLJS_DECLARE_AST_NODE(DefaultClause)
DefaultClause(StatementList *slist):
statements (slist)
@@ -1820,7 +1821,7 @@ public:
class LabelledStatement: public Statement
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(LabelledStatement)
+ QMLJS_DECLARE_AST_NODE(LabelledStatement)
LabelledStatement(NameId *l, Statement *stmt):
label (l), statement (stmt)
@@ -1846,7 +1847,7 @@ public:
class ThrowStatement: public Statement
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(ThrowStatement)
+ QMLJS_DECLARE_AST_NODE(ThrowStatement)
ThrowStatement(ExpressionNode *e):
expression (e) { kind = K; }
@@ -1870,7 +1871,7 @@ public:
class Catch: public Node
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(Catch)
+ QMLJS_DECLARE_AST_NODE(Catch)
Catch(NameId *n, Block *stmt):
name (n), statement (stmt)
@@ -1892,7 +1893,7 @@ public:
class Finally: public Node
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(Finally)
+ QMLJS_DECLARE_AST_NODE(Finally)
Finally(Block *stmt):
statement (stmt)
@@ -1910,7 +1911,7 @@ public:
class TryStatement: public Statement
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(TryStatement)
+ QMLJS_DECLARE_AST_NODE(TryStatement)
TryStatement(Statement *stmt, Catch *c, Finally *f):
statement (stmt), catchExpression (c), finallyExpression (f)
@@ -1951,7 +1952,7 @@ public:
class FunctionExpression: public ExpressionNode
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(FunctionExpression)
+ QMLJS_DECLARE_AST_NODE(FunctionExpression)
FunctionExpression(NameId *n, FormalParameterList *f, FunctionBody *b):
name (n), formals (f), body (b)
@@ -1982,7 +1983,7 @@ public:
class FunctionDeclaration: public FunctionExpression
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(FunctionDeclaration)
+ QMLJS_DECLARE_AST_NODE(FunctionDeclaration)
FunctionDeclaration(NameId *n, FormalParameterList *f, FunctionBody *b):
FunctionExpression(n, f, b)
@@ -1996,7 +1997,7 @@ public:
class FormalParameterList: public Node
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(FormalParameterList)
+ QMLJS_DECLARE_AST_NODE(FormalParameterList)
FormalParameterList(NameId *n):
name (n), next (this)
@@ -2031,7 +2032,7 @@ public:
class FunctionBody: public Node
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(FunctionBody)
+ QMLJS_DECLARE_AST_NODE(FunctionBody)
FunctionBody(SourceElements *elts):
elements (elts)
@@ -2048,7 +2049,7 @@ public:
class Program: public Node
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(Program)
+ QMLJS_DECLARE_AST_NODE(Program)
Program(SourceElements *elts):
elements (elts)
@@ -2065,7 +2066,7 @@ public:
class SourceElements: public Node
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(SourceElements)
+ QMLJS_DECLARE_AST_NODE(SourceElements)
SourceElements(SourceElement *elt):
element (elt), next (this)
@@ -2098,7 +2099,7 @@ public:
class SourceElement: public Node
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(SourceElement)
+ QMLJS_DECLARE_AST_NODE(SourceElement)
inline SourceElement()
{ kind = K; }
@@ -2109,7 +2110,7 @@ public:
class FunctionSourceElement: public SourceElement
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(FunctionSourceElement)
+ QMLJS_DECLARE_AST_NODE(FunctionSourceElement)
FunctionSourceElement(FunctionDeclaration *f):
declaration (f)
@@ -2126,7 +2127,7 @@ public:
class StatementSourceElement: public SourceElement
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(StatementSourceElement)
+ QMLJS_DECLARE_AST_NODE(StatementSourceElement)
StatementSourceElement(Statement *stmt):
statement (stmt)
@@ -2143,7 +2144,7 @@ public:
class DebuggerStatement: public Statement
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(DebuggerStatement)
+ QMLJS_DECLARE_AST_NODE(DebuggerStatement)
DebuggerStatement()
{ kind = K; }
@@ -2166,7 +2167,7 @@ public:
class UiProgram: public Node
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(UiProgram)
+ QMLJS_DECLARE_AST_NODE(UiProgram)
UiProgram(UiImportList *imports, UiObjectMemberList *members)
: imports(imports), members(members)
@@ -2182,7 +2183,7 @@ public:
class UiQualifiedId: public Node
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(UiQualifiedId)
+ QMLJS_DECLARE_AST_NODE(UiQualifiedId)
UiQualifiedId(NameId *name)
: next(this), name(name)
@@ -2216,7 +2217,7 @@ public:
class UiImport: public Node
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(UiImport)
+ QMLJS_DECLARE_AST_NODE(UiImport)
UiImport(NameId *fileName)
: fileName(fileName)
@@ -2234,7 +2235,7 @@ public:
class UiImportList: public Node
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(UiImportList)
+ QMLJS_DECLARE_AST_NODE(UiImportList)
UiImportList(UiImport *import)
: import(import),
@@ -2273,7 +2274,7 @@ public:
class UiObjectMemberList: public Node
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(UiObjectMemberList)
+ QMLJS_DECLARE_AST_NODE(UiObjectMemberList)
UiObjectMemberList(UiObjectMember *member)
: next(this), member(member)
@@ -2301,10 +2302,42 @@ public:
UiObjectMember *member;
};
+class UiArrayMemberList: public Node
+{
+public:
+ QMLJS_DECLARE_AST_NODE(UiArrayMemberList)
+
+ UiArrayMemberList(UiObjectMember *member)
+ : next(this), member(member)
+ { kind = K; }
+
+ UiArrayMemberList(UiArrayMemberList *previous, UiObjectMember *member)
+ : member(member)
+ {
+ kind = K;
+ next = previous->next;
+ previous->next = this;
+ }
+
+ virtual void accept0(Visitor *visitor);
+
+ UiArrayMemberList *finish()
+ {
+ UiArrayMemberList *head = next;
+ next = 0;
+ return head;
+ }
+
+// attributes
+ UiArrayMemberList *next;
+ UiObjectMember *member;
+ SourceLocation commaToken;
+};
+
class UiObjectInitializer: public Node
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(UiObjectInitializer)
+ QMLJS_DECLARE_AST_NODE(UiObjectInitializer)
UiObjectInitializer(UiObjectMemberList *members)
: members(members)
@@ -2321,7 +2354,7 @@ public:
class UiPublicMember: public UiObjectMember
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(UiPublicMember)
+ QMLJS_DECLARE_AST_NODE(UiPublicMember)
UiPublicMember(NameId *memberType,
NameId *name)
@@ -2366,7 +2399,7 @@ public:
class UiObjectDefinition: public UiObjectMember
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(UiObjectDefinition)
+ QMLJS_DECLARE_AST_NODE(UiObjectDefinition)
UiObjectDefinition(UiQualifiedId *qualifiedTypeNameId,
UiObjectInitializer *initializer)
@@ -2389,7 +2422,7 @@ public:
class UiSourceElement: public UiObjectMember
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(UiSourceElement)
+ QMLJS_DECLARE_AST_NODE(UiSourceElement)
UiSourceElement(Node *sourceElement)
: sourceElement(sourceElement)
@@ -2425,7 +2458,7 @@ public:
class UiObjectBinding: public UiObjectMember
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(UiObjectBinding)
+ QMLJS_DECLARE_AST_NODE(UiObjectBinding)
UiObjectBinding(UiQualifiedId *qualifiedId,
UiQualifiedId *qualifiedTypeNameId,
@@ -2453,7 +2486,7 @@ public:
class UiScriptBinding: public UiObjectMember
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(UiScriptBinding)
+ QMLJS_DECLARE_AST_NODE(UiScriptBinding)
UiScriptBinding(UiQualifiedId *qualifiedId,
Statement *statement)
@@ -2478,10 +2511,10 @@ public:
class UiArrayBinding: public UiObjectMember
{
public:
- JAVASCRIPT_DECLARE_AST_NODE(UiArrayBinding)
+ QMLJS_DECLARE_AST_NODE(UiArrayBinding)
UiArrayBinding(UiQualifiedId *qualifiedId,
- UiObjectMemberList *members)
+ UiArrayMemberList *members)
: qualifiedId(qualifiedId),
members(members)
{ kind = K; }
@@ -2496,7 +2529,7 @@ public:
// attributes
UiQualifiedId *qualifiedId;
- UiObjectMemberList *members;
+ UiArrayMemberList *members;
SourceLocation colonToken;
SourceLocation lbracketToken;
SourceLocation rbracketToken;
diff --git a/src/declarative/qml/parser/javascriptastfwd_p.h b/src/declarative/qml/parser/qmljsastfwd_p.h
index 822a2d7..339bea4 100644
--- a/src/declarative/qml/parser/javascriptastfwd_p.h
+++ b/src/declarative/qml/parser/qmljsastfwd_p.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef JAVASCRIPTAST_FWD_P_H
-#define JAVASCRIPTAST_FWD_P_H
+#ifndef QMLJSAST_FWD_P_H
+#define QMLJSAST_FWD_P_H
#include <QtCore/qglobal.h>
@@ -57,7 +57,7 @@
QT_BEGIN_NAMESPACE
-namespace JavaScript { namespace AST {
+namespace QmlJS { namespace AST {
class SourceLocation
{
@@ -174,6 +174,7 @@ class UiSourceElement;
class UiArrayBinding;
class UiObjectMember;
class UiObjectMemberList;
+class UiArrayMemberList;
class UiQualifiedId;
} } // namespace AST
diff --git a/src/declarative/qml/parser/javascriptastvisitor.cpp b/src/declarative/qml/parser/qmljsastvisitor.cpp
index eac291d..642bcee 100644
--- a/src/declarative/qml/parser/javascriptastvisitor.cpp
+++ b/src/declarative/qml/parser/qmljsastvisitor.cpp
@@ -39,11 +39,11 @@
**
****************************************************************************/
-#include "javascriptastvisitor_p.h"
+#include "qmljsastvisitor_p.h"
QT_BEGIN_NAMESPACE
-namespace JavaScript { namespace AST {
+namespace QmlJS { namespace AST {
Visitor::Visitor()
{
@@ -53,6 +53,6 @@ Visitor::~Visitor()
{
}
-} } // namespace JavaScript::AST
+} } // namespace QmlJS::AST
QT_END_NAMESPACE
diff --git a/src/declarative/qml/parser/javascriptastvisitor_p.h b/src/declarative/qml/parser/qmljsastvisitor_p.h
index 81df364..3677b1a 100644
--- a/src/declarative/qml/parser/javascriptastvisitor_p.h
+++ b/src/declarative/qml/parser/qmljsastvisitor_p.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef JAVASCRIPTASTVISITOR_P_H
-#define JAVASCRIPTASTVISITOR_P_H
+#ifndef QMLJSASTVISITOR_P_H
+#define QMLJSASTVISITOR_P_H
//
// W A R N I N G
@@ -53,11 +53,11 @@
// We mean it.
//
-#include "javascriptastfwd_p.h"
+#include "qmljsastfwd_p.h"
QT_BEGIN_NAMESPACE
-namespace JavaScript { namespace AST {
+namespace QmlJS { namespace AST {
class Visitor
{
@@ -80,6 +80,7 @@ public:
virtual bool visit(UiScriptBinding *) { return true; }
virtual bool visit(UiArrayBinding *) { return true; }
virtual bool visit(UiObjectMemberList *) { return true; }
+ virtual bool visit(UiArrayMemberList *) { return true; }
virtual bool visit(UiQualifiedId *) { return true; }
virtual void endVisit(UiProgram *) {}
@@ -93,9 +94,10 @@ public:
virtual void endVisit(UiScriptBinding *) {}
virtual void endVisit(UiArrayBinding *) {}
virtual void endVisit(UiObjectMemberList *) {}
+ virtual void endVisit(UiArrayMemberList *) {}
virtual void endVisit(UiQualifiedId *) {}
- // JavaScript
+ // QmlJS
virtual bool visit(ThisExpression *) { return true; }
virtual void endVisit(ThisExpression *) {}
@@ -323,4 +325,4 @@ public:
QT_END_NAMESPACE
-#endif // JAVASCRIPTASTVISITOR_P_H
+#endif // QMLJSASTVISITOR_P_H
diff --git a/src/declarative/qml/parser/javascriptengine_p.cpp b/src/declarative/qml/parser/qmljsengine_p.cpp
index d893a90..42885d8 100644
--- a/src/declarative/qml/parser/javascriptengine_p.cpp
+++ b/src/declarative/qml/parser/qmljsengine_p.cpp
@@ -27,16 +27,16 @@
**
**************************************************************************/
-#include "javascriptengine_p.h"
-#include "javascriptnodepool_p.h"
+#include "qmljsengine_p.h"
+#include "qmljsnodepool_p.h"
#include <qnumeric.h>
#include <QHash>
QT_BEGIN_NAMESPACE
-namespace JavaScript {
+namespace QmlJS {
-uint qHash(const JavaScript::NameId &id)
+uint qHash(const QmlJS::NameId &id)
{ return qHash(id.asString()); }
QString numberToString(double value)
@@ -186,6 +186,6 @@ void Engine::setNodePool(NodePool *nodePool)
-} // end of namespace JavaScript
+} // end of namespace QmlJS
QT_END_NAMESPACE
diff --git a/src/declarative/qml/parser/javascriptengine_p.h b/src/declarative/qml/parser/qmljsengine_p.h
index 3bd924a..b9ff042 100644
--- a/src/declarative/qml/parser/javascriptengine_p.h
+++ b/src/declarative/qml/parser/qmljsengine_p.h
@@ -27,17 +27,17 @@
**
**************************************************************************/
-#ifndef JAVASCRIPTENGINE_P_H
-#define JAVASCRIPTENGINE_P_H
+#ifndef QMLJSENGINE_P_H
+#define QMLJSENGINE_P_H
#include <QString>
#include <QSet>
-#include "javascriptastfwd_p.h"
+#include "qmljsastfwd_p.h"
QT_BEGIN_NAMESPACE
-namespace JavaScript {
+namespace QmlJS {
class NameId
{
QString _text;
@@ -60,17 +60,17 @@ public:
{ return _text < other._text; }
};
-uint qHash(const JavaScript::NameId &id);
+uint qHash(const QmlJS::NameId &id);
-} // end of namespace JavaScript
+} // end of namespace QmlJS
#if defined(Q_CC_MSVC) && _MSC_VER <= 1300
-//this ensures that code outside JavaScript can use the hash function
+//this ensures that code outside QmlJS can use the hash function
//it also a workaround for some compilers
-inline uint qHash(const JavaScript::NameId &nameId) { return JavaScript::qHash(nameId); }
+inline uint qHash(const QmlJS::NameId &nameId) { return QmlJS::qHash(nameId); }
#endif
-namespace JavaScript {
+namespace QmlJS {
class Lexer;
class NodePool;
@@ -138,8 +138,8 @@ public:
void setNodePool(NodePool *nodePool);
};
-} // end of namespace JavaScript
+} // end of namespace QmlJS
QT_END_NAMESPACE
-#endif // JAVASCRIPTENGINE_P_H
+#endif // QMLJSENGINE_P_H
diff --git a/src/declarative/qml/parser/javascriptgrammar.cpp b/src/declarative/qml/parser/qmljsgrammar.cpp
index a879bfe..835ee44 100644
--- a/src/declarative/qml/parser/javascriptgrammar.cpp
+++ b/src/declarative/qml/parser/qmljsgrammar.cpp
@@ -40,9 +40,9 @@
**
****************************************************************************/
-#include "javascriptgrammar_p.h"
+#include "qmljsgrammar_p.h"
-const char *const JavaScriptGrammar::spell [] = {
+const char *const QmlJSGrammar::spell [] = {
"end of file", "&", "&&", "&=", "break", "case", "catch", ":", ";", "continue",
"default", "delete", "/", "/=", "do", ".", "else", "=", "==", "===",
"finally", "for", "function", ">=", ">", ">>", ">>=", ">>>", ">>>=", "identifier",
@@ -54,7 +54,7 @@ const char *const JavaScriptGrammar::spell [] = {
"null", "true", "false", "const", "debugger", "reserved word", "multiline string literal", "public", "import", 0,
0};
-const int JavaScriptGrammar::lhs [] = {
+const int QmlJSGrammar::lhs [] = {
91, 92, 92, 95, 95, 96, 96, 94, 93, 98,
98, 100, 100, 101, 101, 97, 99, 99, 103, 104,
104, 99, 99, 99, 99, 99, 99, 99, 111, 111,
@@ -89,7 +89,7 @@ const int JavaScriptGrammar::lhs [] = {
185, 186, 186, 189, 190, 190, 191, 191, 187, 187,
118, 118, 192};
-const int JavaScriptGrammar:: rhs[] = {
+const int QmlJSGrammar:: rhs[] = {
2, 1, 1, 1, 2, 3, 3, 0, 1, 1,
2, 1, 3, 2, 3, 2, 1, 5, 1, 2,
2, 4, 3, 3, 3, 3, 3, 3, 1, 1,
@@ -124,7 +124,7 @@ const int JavaScriptGrammar:: rhs[] = {
1, 0, 1, 1, 1, 2, 1, 1, 0, 1,
0, 1, 2};
-const int JavaScriptGrammar::action_default [] = {
+const int QmlJSGrammar::action_default [] = {
8, 2, 0, 4, 3, 0, 0, 0, 6, 7,
5, 65, 45, 46, 43, 44, 47, 9, 0, 1,
0, 0, 16, 66, 41, 248, 0, 0, 46, 14,
@@ -185,7 +185,7 @@ const int JavaScriptGrammar::action_default [] = {
0, 12, 0, 18, 13, 20, 21, 257, 250, 0,
258, 254, 0, 256, 246, 0, 247, 251, 323};
-const int JavaScriptGrammar::goto_default [] = {
+const int QmlJSGrammar::goto_default [] = {
6, 5, 19, 1, 4, 3, 32, 34, 33, 570,
22, 18, 538, 539, 231, 226, 230, 232, 229, 236,
517, 235, 264, 57, 65, 495, 494, 388, 387, 48,
@@ -198,7 +198,7 @@ const int JavaScriptGrammar::goto_default [] = {
454, 453, 473, 474, 220, 234, 216, 219, 233, 241,
240, 0};
-const int JavaScriptGrammar::action_index [] = {
+const int QmlJSGrammar::action_index [] = {
8, -91, 14, -91, -15, 296, 67, 94, -91, -91,
-91, -91, -91, -91, -91, -91, -91, -91, 109, -91,
184, 408, -91, -91, -91, -91, 45, 125, 170, -91,
@@ -319,7 +319,7 @@ const int JavaScriptGrammar::action_index [] = {
-102, -102, 128, -102, -102, -102, -102, -102, -102, -102,
-102, -102, -6, -102, -102, 58, -102, -102, -102};
-const int JavaScriptGrammar::action_info [] = {
+const int QmlJSGrammar::action_info [] = {
338, 174, 289, 485, 472, 472, -89, 480, -105, 380,
43, 472, -79, -78, -100, 448, -97, 435, -102, 134,
304, 326, 132, 104, 478, 375, 489, 372, 374, 456,
@@ -573,7 +573,7 @@ const int JavaScriptGrammar::action_info [] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0};
-const int JavaScriptGrammar::action_check [] = {
+const int QmlJSGrammar::action_check [] = {
60, 8, 36, 36, 33, 33, 7, 60, 7, 36,
29, 33, 7, 7, 7, 36, 7, 55, 7, 78,
1, 78, 48, 1, 36, 33, 36, 36, 60, 5,
diff --git a/src/declarative/qml/parser/javascriptgrammar_p.h b/src/declarative/qml/parser/qmljsgrammar_p.h
index 830f533..c514485 100644
--- a/src/declarative/qml/parser/javascriptgrammar_p.h
+++ b/src/declarative/qml/parser/qmljsgrammar_p.h
@@ -51,10 +51,10 @@
// We mean it.
//
-#ifndef JAVASCRIPTGRAMMAR_P_H
-#define JAVASCRIPTGRAMMAR_P_H
+#ifndef QMLJSGRAMMAR_P_H
+#define QMLJSGRAMMAR_P_H
-class JavaScriptGrammar
+class QmlJSGrammar
{
public:
enum {
@@ -196,5 +196,5 @@ public:
};
-#endif // JAVASCRIPTGRAMMAR_P_H
+#endif // QMLJSGRAMMAR_P_H
diff --git a/src/declarative/qml/parser/javascriptlexer.cpp b/src/declarative/qml/parser/qmljslexer.cpp
index ea36a7a..843f6ae 100644
--- a/src/declarative/qml/parser/javascriptlexer.cpp
+++ b/src/declarative/qml/parser/qmljslexer.cpp
@@ -43,9 +43,9 @@
#include "config.h"
#endif
-#include "javascriptengine_p.h"
-#include "javascriptlexer_p.h"
-#include "javascriptgrammar_p.h"
+#include "qmljsengine_p.h"
+#include "qmljslexer_p.h"
+#include "qmljsgrammar_p.h"
#include <ctype.h>
#include <stdlib.h>
@@ -65,11 +65,11 @@ extern double qstrtod(const char *s00, char const **se, bool *ok);
} \
while (0)
-namespace JavaScript {
+namespace QmlJS {
extern double integerFromString(const char *buf, int size, int radix);
}
-using namespace JavaScript;
+using namespace QmlJS;
Lexer::Lexer(Engine *eng)
: driver(eng),
@@ -154,66 +154,66 @@ int Lexer::findReservedWord(const QChar *c, int size) const
switch (size) {
case 2: {
if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('o'))
- return JavaScriptGrammar::T_DO;
+ return QmlJSGrammar::T_DO;
else if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('f'))
- return JavaScriptGrammar::T_IF;
+ return QmlJSGrammar::T_IF;
else if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n'))
- return JavaScriptGrammar::T_IN;
+ return QmlJSGrammar::T_IN;
} break;
case 3: {
if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('o') && c[2] == QLatin1Char('r'))
- return JavaScriptGrammar::T_FOR;
+ return QmlJSGrammar::T_FOR;
else if (c[0] == QLatin1Char('n') && c[1] == QLatin1Char('e') && c[2] == QLatin1Char('w'))
- return JavaScriptGrammar::T_NEW;
+ return QmlJSGrammar::T_NEW;
else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('r') && c[2] == QLatin1Char('y'))
- return JavaScriptGrammar::T_TRY;
+ return QmlJSGrammar::T_TRY;
else if (c[0] == QLatin1Char('v') && c[1] == QLatin1Char('a') && c[2] == QLatin1Char('r'))
- return JavaScriptGrammar::T_VAR;
+ return QmlJSGrammar::T_VAR;
else if (check_reserved) {
if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n') && c[2] == QLatin1Char('t'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
}
} break;
case 4: {
if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('a')
&& c[2] == QLatin1Char('s') && c[3] == QLatin1Char('e'))
- return JavaScriptGrammar::T_CASE;
+ return QmlJSGrammar::T_CASE;
else if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('l')
&& c[2] == QLatin1Char('s') && c[3] == QLatin1Char('e'))
- return JavaScriptGrammar::T_ELSE;
+ return QmlJSGrammar::T_ELSE;
else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('h')
&& c[2] == QLatin1Char('i') && c[3] == QLatin1Char('s'))
- return JavaScriptGrammar::T_THIS;
+ return QmlJSGrammar::T_THIS;
else if (c[0] == QLatin1Char('v') && c[1] == QLatin1Char('o')
&& c[2] == QLatin1Char('i') && c[3] == QLatin1Char('d'))
- return JavaScriptGrammar::T_VOID;
+ return QmlJSGrammar::T_VOID;
else if (c[0] == QLatin1Char('w') && c[1] == QLatin1Char('i')
&& c[2] == QLatin1Char('t') && c[3] == QLatin1Char('h'))
- return JavaScriptGrammar::T_WITH;
+ return QmlJSGrammar::T_WITH;
else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('r')
&& c[2] == QLatin1Char('u') && c[3] == QLatin1Char('e'))
- return JavaScriptGrammar::T_TRUE;
+ return QmlJSGrammar::T_TRUE;
else if (c[0] == QLatin1Char('n') && c[1] == QLatin1Char('u')
&& c[2] == QLatin1Char('l') && c[3] == QLatin1Char('l'))
- return JavaScriptGrammar::T_NULL;
+ return QmlJSGrammar::T_NULL;
else if (check_reserved) {
if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('n')
&& c[2] == QLatin1Char('u') && c[3] == QLatin1Char('m'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
else if (c[0] == QLatin1Char('b') && c[1] == QLatin1Char('y')
&& c[2] == QLatin1Char('t') && c[3] == QLatin1Char('e'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
else if (c[0] == QLatin1Char('l') && c[1] == QLatin1Char('o')
&& c[2] == QLatin1Char('n') && c[3] == QLatin1Char('g'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('h')
&& c[2] == QLatin1Char('a') && c[3] == QLatin1Char('r'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
else if (c[0] == QLatin1Char('g') && c[1] == QLatin1Char('o')
&& c[2] == QLatin1Char('t') && c[3] == QLatin1Char('o'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
}
} break;
@@ -221,48 +221,48 @@ int Lexer::findReservedWord(const QChar *c, int size) const
if (c[0] == QLatin1Char('b') && c[1] == QLatin1Char('r')
&& c[2] == QLatin1Char('e') && c[3] == QLatin1Char('a')
&& c[4] == QLatin1Char('k'))
- return JavaScriptGrammar::T_BREAK;
+ return QmlJSGrammar::T_BREAK;
else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('a')
&& c[2] == QLatin1Char('t') && c[3] == QLatin1Char('c')
&& c[4] == QLatin1Char('h'))
- return JavaScriptGrammar::T_CATCH;
+ return QmlJSGrammar::T_CATCH;
else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('h')
&& c[2] == QLatin1Char('r') && c[3] == QLatin1Char('o')
&& c[4] == QLatin1Char('w'))
- return JavaScriptGrammar::T_THROW;
+ return QmlJSGrammar::T_THROW;
else if (c[0] == QLatin1Char('w') && c[1] == QLatin1Char('h')
&& c[2] == QLatin1Char('i') && c[3] == QLatin1Char('l')
&& c[4] == QLatin1Char('e'))
- return JavaScriptGrammar::T_WHILE;
+ return QmlJSGrammar::T_WHILE;
else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('o')
&& c[2] == QLatin1Char('n') && c[3] == QLatin1Char('s')
&& c[4] == QLatin1Char('t'))
- return JavaScriptGrammar::T_CONST;
+ return QmlJSGrammar::T_CONST;
else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('a')
&& c[2] == QLatin1Char('l') && c[3] == QLatin1Char('s')
&& c[4] == QLatin1Char('e'))
- return JavaScriptGrammar::T_FALSE;
+ return QmlJSGrammar::T_FALSE;
else if (check_reserved) {
if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('h')
&& c[2] == QLatin1Char('o') && c[3] == QLatin1Char('r')
&& c[4] == QLatin1Char('t'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
else if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('u')
&& c[2] == QLatin1Char('p') && c[3] == QLatin1Char('e')
&& c[4] == QLatin1Char('r'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('i')
&& c[2] == QLatin1Char('n') && c[3] == QLatin1Char('a')
&& c[4] == QLatin1Char('l'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('l')
&& c[2] == QLatin1Char('a') && c[3] == QLatin1Char('s')
&& c[4] == QLatin1Char('s'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('l')
&& c[2] == QLatin1Char('o') && c[3] == QLatin1Char('a')
&& c[4] == QLatin1Char('t'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
}
} break;
@@ -270,56 +270,56 @@ int Lexer::findReservedWord(const QChar *c, int size) const
if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('e')
&& c[2] == QLatin1Char('l') && c[3] == QLatin1Char('e')
&& c[4] == QLatin1Char('t') && c[5] == QLatin1Char('e'))
- return JavaScriptGrammar::T_DELETE;
+ return QmlJSGrammar::T_DELETE;
else if (c[0] == QLatin1Char('r') && c[1] == QLatin1Char('e')
&& c[2] == QLatin1Char('t') && c[3] == QLatin1Char('u')
&& c[4] == QLatin1Char('r') && c[5] == QLatin1Char('n'))
- return JavaScriptGrammar::T_RETURN;
+ return QmlJSGrammar::T_RETURN;
else if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('w')
&& c[2] == QLatin1Char('i') && c[3] == QLatin1Char('t')
&& c[4] == QLatin1Char('c') && c[5] == QLatin1Char('h'))
- return JavaScriptGrammar::T_SWITCH;
+ return QmlJSGrammar::T_SWITCH;
else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('y')
&& c[2] == QLatin1Char('p') && c[3] == QLatin1Char('e')
&& c[4] == QLatin1Char('o') && c[5] == QLatin1Char('f'))
- return JavaScriptGrammar::T_TYPEOF;
+ return QmlJSGrammar::T_TYPEOF;
else if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('m')
&& c[2] == QLatin1Char('p') && c[3] == QLatin1Char('o')
&& c[4] == QLatin1Char('r') && c[5] == QLatin1Char('t'))
- return JavaScriptGrammar::T_IMPORT;
+ return QmlJSGrammar::T_IMPORT;
else if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('i')
&& c[2] == QLatin1Char('g') && c[3] == QLatin1Char('n')
&& c[4] == QLatin1Char('a') && c[5] == QLatin1Char('l'))
- return JavaScriptGrammar::T_SIGNAL;
+ return QmlJSGrammar::T_SIGNAL;
else if (check_reserved) {
if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('x')
&& c[2] == QLatin1Char('p') && c[3] == QLatin1Char('o')
&& c[4] == QLatin1Char('r') && c[5] == QLatin1Char('t'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
else if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('t')
&& c[2] == QLatin1Char('a') && c[3] == QLatin1Char('t')
&& c[4] == QLatin1Char('i') && c[5] == QLatin1Char('c'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
else if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('o')
&& c[2] == QLatin1Char('u') && c[3] == QLatin1Char('b')
&& c[4] == QLatin1Char('l') && c[5] == QLatin1Char('e'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
else if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('m')
&& c[2] == QLatin1Char('p') && c[3] == QLatin1Char('o')
&& c[4] == QLatin1Char('r') && c[5] == QLatin1Char('t'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('u')
&& c[2] == QLatin1Char('b') && c[3] == QLatin1Char('l')
&& c[4] == QLatin1Char('i') && c[5] == QLatin1Char('c'))
- return JavaScriptGrammar::T_PUBLIC;
+ return QmlJSGrammar::T_PUBLIC;
else if (c[0] == QLatin1Char('n') && c[1] == QLatin1Char('a')
&& c[2] == QLatin1Char('t') && c[3] == QLatin1Char('i')
&& c[4] == QLatin1Char('v') && c[5] == QLatin1Char('e'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('h')
&& c[2] == QLatin1Char('r') && c[3] == QLatin1Char('o')
&& c[4] == QLatin1Char('w') && c[5] == QLatin1Char('s'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
}
} break;
@@ -328,33 +328,33 @@ int Lexer::findReservedWord(const QChar *c, int size) const
&& c[2] == QLatin1Char('f') && c[3] == QLatin1Char('a')
&& c[4] == QLatin1Char('u') && c[5] == QLatin1Char('l')
&& c[6] == QLatin1Char('t'))
- return JavaScriptGrammar::T_DEFAULT;
+ return QmlJSGrammar::T_DEFAULT;
else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('i')
&& c[2] == QLatin1Char('n') && c[3] == QLatin1Char('a')
&& c[4] == QLatin1Char('l') && c[5] == QLatin1Char('l')
&& c[6] == QLatin1Char('y'))
- return JavaScriptGrammar::T_FINALLY;
+ return QmlJSGrammar::T_FINALLY;
else if (check_reserved) {
if (c[0] == QLatin1Char('b') && c[1] == QLatin1Char('o')
&& c[2] == QLatin1Char('o') && c[3] == QLatin1Char('l')
&& c[4] == QLatin1Char('e') && c[5] == QLatin1Char('a')
&& c[6] == QLatin1Char('n'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
else if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('x')
&& c[2] == QLatin1Char('t') && c[3] == QLatin1Char('e')
&& c[4] == QLatin1Char('n') && c[5] == QLatin1Char('d')
&& c[6] == QLatin1Char('s'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('a')
&& c[2] == QLatin1Char('c') && c[3] == QLatin1Char('k')
&& c[4] == QLatin1Char('a') && c[5] == QLatin1Char('g')
&& c[6] == QLatin1Char('e'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('r')
&& c[2] == QLatin1Char('i') && c[3] == QLatin1Char('v')
&& c[4] == QLatin1Char('a') && c[5] == QLatin1Char('t')
&& c[6] == QLatin1Char('e'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
}
} break;
@@ -363,33 +363,33 @@ int Lexer::findReservedWord(const QChar *c, int size) const
&& c[2] == QLatin1Char('n') && c[3] == QLatin1Char('t')
&& c[4] == QLatin1Char('i') && c[5] == QLatin1Char('n')
&& c[6] == QLatin1Char('u') && c[7] == QLatin1Char('e'))
- return JavaScriptGrammar::T_CONTINUE;
+ return QmlJSGrammar::T_CONTINUE;
else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('u')
&& c[2] == QLatin1Char('n') && c[3] == QLatin1Char('c')
&& c[4] == QLatin1Char('t') && c[5] == QLatin1Char('i')
&& c[6] == QLatin1Char('o') && c[7] == QLatin1Char('n'))
- return JavaScriptGrammar::T_FUNCTION;
+ return QmlJSGrammar::T_FUNCTION;
else if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('e')
&& c[2] == QLatin1Char('b') && c[3] == QLatin1Char('u')
&& c[4] == QLatin1Char('g') && c[5] == QLatin1Char('g')
&& c[6] == QLatin1Char('e') && c[7] == QLatin1Char('r'))
- return JavaScriptGrammar::T_DEBUGGER;
+ return QmlJSGrammar::T_DEBUGGER;
else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('r')
&& c[2] == QLatin1Char('o') && c[3] == QLatin1Char('p')
&& c[4] == QLatin1Char('e') && c[5] == QLatin1Char('r')
&& c[6] == QLatin1Char('t') && c[7] == QLatin1Char('y'))
- return JavaScriptGrammar::T_PROPERTY;
+ return QmlJSGrammar::T_PROPERTY;
else if (check_reserved) {
if (c[0] == QLatin1Char('a') && c[1] == QLatin1Char('b')
&& c[2] == QLatin1Char('s') && c[3] == QLatin1Char('t')
&& c[4] == QLatin1Char('r') && c[5] == QLatin1Char('a')
&& c[6] == QLatin1Char('c') && c[7] == QLatin1Char('t'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
else if (c[0] == QLatin1Char('v') && c[1] == QLatin1Char('o')
&& c[2] == QLatin1Char('l') && c[3] == QLatin1Char('a')
&& c[4] == QLatin1Char('t') && c[5] == QLatin1Char('i')
&& c[6] == QLatin1Char('l') && c[7] == QLatin1Char('e'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
}
} break;
@@ -400,19 +400,19 @@ int Lexer::findReservedWord(const QChar *c, int size) const
&& c[4] == QLatin1Char('r') && c[5] == QLatin1Char('f')
&& c[6] == QLatin1Char('a') && c[7] == QLatin1Char('c')
&& c[8] == QLatin1Char('e'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('r')
&& c[2] == QLatin1Char('a') && c[3] == QLatin1Char('n')
&& c[4] == QLatin1Char('s') && c[5] == QLatin1Char('i')
&& c[6] == QLatin1Char('e') && c[7] == QLatin1Char('n')
&& c[8] == QLatin1Char('t'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('r')
&& c[2] == QLatin1Char('o') && c[3] == QLatin1Char('t')
&& c[4] == QLatin1Char('e') && c[5] == QLatin1Char('c')
&& c[6] == QLatin1Char('t') && c[7] == QLatin1Char('e')
&& c[8] == QLatin1Char('d'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
}
} break;
@@ -422,14 +422,14 @@ int Lexer::findReservedWord(const QChar *c, int size) const
&& c[4] == QLatin1Char('a') && c[5] == QLatin1Char('n')
&& c[6] == QLatin1Char('c') && c[7] == QLatin1Char('e')
&& c[8] == QLatin1Char('o') && c[9] == QLatin1Char('f'))
- return JavaScriptGrammar::T_INSTANCEOF;
+ return QmlJSGrammar::T_INSTANCEOF;
else if (check_reserved) {
if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('m')
&& c[2] == QLatin1Char('p') && c[3] == QLatin1Char('l')
&& c[4] == QLatin1Char('e') && c[5] == QLatin1Char('m')
&& c[6] == QLatin1Char('e') && c[7] == QLatin1Char('n')
&& c[8] == QLatin1Char('t') && c[9] == QLatin1Char('s'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
}
} break;
@@ -441,7 +441,7 @@ int Lexer::findReservedWord(const QChar *c, int size) const
&& c[6] == QLatin1Char('o') && c[7] == QLatin1Char('n')
&& c[8] == QLatin1Char('i') && c[9] == QLatin1Char('z')
&& c[10] == QLatin1Char('e') && c[11] == QLatin1Char('d'))
- return JavaScriptGrammar::T_RESERVED_WORD;
+ return QmlJSGrammar::T_RESERVED_WORD;
}
} break;
@@ -485,7 +485,7 @@ int Lexer::lex()
syncProhibitAutomaticSemicolon();
if (!terminator && !delimited && !prohibitAutomaticSemicolon) {
// automatic semicolon insertion if program incomplete
- token = JavaScriptGrammar::T_SEMICOLON;
+ token = QmlJSGrammar::T_SEMICOLON;
stackToken = 0;
setDone(Other);
} else {
@@ -499,7 +499,7 @@ int Lexer::lex()
terminator = true;
syncProhibitAutomaticSemicolon();
if (restrKeyword) {
- token = JavaScriptGrammar::T_SEMICOLON;
+ token = QmlJSGrammar::T_SEMICOLON;
setDone(Other);
}
} else if (current == '"' || current == '\'') {
@@ -528,11 +528,11 @@ int Lexer::lex()
token = matchPunctuator(current, next1, next2, next3);
if (token != -1) {
if (terminator && !delimited && !prohibitAutomaticSemicolon
- && (token == JavaScriptGrammar::T_PLUS_PLUS
- || token == JavaScriptGrammar::T_MINUS_MINUS)) {
+ && (token == QmlJSGrammar::T_PLUS_PLUS
+ || token == QmlJSGrammar::T_MINUS_MINUS)) {
// automatic semicolon insertion
stackToken = token;
- token = JavaScriptGrammar::T_SEMICOLON;
+ token = QmlJSGrammar::T_SEMICOLON;
}
setDone(Other);
}
@@ -636,7 +636,7 @@ int Lexer::lex()
terminator = true;
bol = true;
if (restrKeyword) {
- token = JavaScriptGrammar::T_SEMICOLON;
+ token = QmlJSGrammar::T_SEMICOLON;
setDone(Other);
} else
state = Start;
@@ -840,11 +840,11 @@ int Lexer::lex()
case IgnoreParentheses:
break;
case CountParentheses:
- if (token == JavaScriptGrammar::T_RPAREN) {
+ if (token == QmlJSGrammar::T_RPAREN) {
--parenthesesCount;
if (parenthesesCount == 0)
parenthesesState = BalancedParentheses;
- } else if (token == JavaScriptGrammar::T_LPAREN) {
+ } else if (token == QmlJSGrammar::T_LPAREN) {
++parenthesesCount;
}
break;
@@ -857,7 +857,7 @@ int Lexer::lex()
case Eof:
return 0;
case Other:
- if (token == JavaScriptGrammar::T_RBRACE || token == JavaScriptGrammar::T_SEMICOLON)
+ if (token == QmlJSGrammar::T_RBRACE || token == QmlJSGrammar::T_SEMICOLON)
delimited = true;
return token;
case Identifier:
@@ -867,16 +867,16 @@ int Lexer::lex()
qsyylval.ustr = driver->intern(buffer16, pos16);
else
qsyylval.ustr = 0;
- return JavaScriptGrammar::T_IDENTIFIER;
+ return QmlJSGrammar::T_IDENTIFIER;
}
- if (token == JavaScriptGrammar::T_CONTINUE || token == JavaScriptGrammar::T_BREAK
- || token == JavaScriptGrammar::T_RETURN || token == JavaScriptGrammar::T_THROW) {
+ if (token == QmlJSGrammar::T_CONTINUE || token == QmlJSGrammar::T_BREAK
+ || token == QmlJSGrammar::T_RETURN || token == QmlJSGrammar::T_THROW) {
restrKeyword = true;
- } else if (token == JavaScriptGrammar::T_IF || token == JavaScriptGrammar::T_FOR
- || token == JavaScriptGrammar::T_WHILE || token == JavaScriptGrammar::T_WITH) {
+ } else if (token == QmlJSGrammar::T_IF || token == QmlJSGrammar::T_FOR
+ || token == QmlJSGrammar::T_WHILE || token == QmlJSGrammar::T_WITH) {
parenthesesState = CountParentheses;
parenthesesCount = 0;
- } else if (token == JavaScriptGrammar::T_DO) {
+ } else if (token == QmlJSGrammar::T_DO) {
parenthesesState = BalancedParentheses;
}
return token;
@@ -885,10 +885,10 @@ int Lexer::lex()
qsyylval.ustr = driver->intern(buffer16, pos16);
else
qsyylval.ustr = 0;
- return multiLineString?JavaScriptGrammar::T_MULTILINE_STRING_LITERAL:JavaScriptGrammar::T_STRING_LITERAL;
+ return multiLineString?QmlJSGrammar::T_MULTILINE_STRING_LITERAL:QmlJSGrammar::T_STRING_LITERAL;
case Number:
qsyylval.dval = dval;
- return JavaScriptGrammar::T_NUMERIC_LITERAL;
+ return QmlJSGrammar::T_NUMERIC_LITERAL;
case Bad:
return -1;
default:
@@ -939,103 +939,103 @@ int Lexer::matchPunctuator(ushort c1, ushort c2,
{
if (c1 == '>' && c2 == '>' && c3 == '>' && c4 == '=') {
shift(4);
- return JavaScriptGrammar::T_GT_GT_GT_EQ;
+ return QmlJSGrammar::T_GT_GT_GT_EQ;
} else if (c1 == '=' && c2 == '=' && c3 == '=') {
shift(3);
- return JavaScriptGrammar::T_EQ_EQ_EQ;
+ return QmlJSGrammar::T_EQ_EQ_EQ;
} else if (c1 == '!' && c2 == '=' && c3 == '=') {
shift(3);
- return JavaScriptGrammar::T_NOT_EQ_EQ;
+ return QmlJSGrammar::T_NOT_EQ_EQ;
} else if (c1 == '>' && c2 == '>' && c3 == '>') {
shift(3);
- return JavaScriptGrammar::T_GT_GT_GT;
+ return QmlJSGrammar::T_GT_GT_GT;
} else if (c1 == '<' && c2 == '<' && c3 == '=') {
shift(3);
- return JavaScriptGrammar::T_LT_LT_EQ;
+ return QmlJSGrammar::T_LT_LT_EQ;
} else if (c1 == '>' && c2 == '>' && c3 == '=') {
shift(3);
- return JavaScriptGrammar::T_GT_GT_EQ;
+ return QmlJSGrammar::T_GT_GT_EQ;
} else if (c1 == '<' && c2 == '=') {
shift(2);
- return JavaScriptGrammar::T_LE;
+ return QmlJSGrammar::T_LE;
} else if (c1 == '>' && c2 == '=') {
shift(2);
- return JavaScriptGrammar::T_GE;
+ return QmlJSGrammar::T_GE;
} else if (c1 == '!' && c2 == '=') {
shift(2);
- return JavaScriptGrammar::T_NOT_EQ;
+ return QmlJSGrammar::T_NOT_EQ;
} else if (c1 == '+' && c2 == '+') {
shift(2);
- return JavaScriptGrammar::T_PLUS_PLUS;
+ return QmlJSGrammar::T_PLUS_PLUS;
} else if (c1 == '-' && c2 == '-') {
shift(2);
- return JavaScriptGrammar::T_MINUS_MINUS;
+ return QmlJSGrammar::T_MINUS_MINUS;
} else if (c1 == '=' && c2 == '=') {
shift(2);
- return JavaScriptGrammar::T_EQ_EQ;
+ return QmlJSGrammar::T_EQ_EQ;
} else if (c1 == '+' && c2 == '=') {
shift(2);
- return JavaScriptGrammar::T_PLUS_EQ;
+ return QmlJSGrammar::T_PLUS_EQ;
} else if (c1 == '-' && c2 == '=') {
shift(2);
- return JavaScriptGrammar::T_MINUS_EQ;
+ return QmlJSGrammar::T_MINUS_EQ;
} else if (c1 == '*' && c2 == '=') {
shift(2);
- return JavaScriptGrammar::T_STAR_EQ;
+ return QmlJSGrammar::T_STAR_EQ;
} else if (c1 == '/' && c2 == '=') {
shift(2);
- return JavaScriptGrammar::T_DIVIDE_EQ;
+ return QmlJSGrammar::T_DIVIDE_EQ;
} else if (c1 == '&' && c2 == '=') {
shift(2);
- return JavaScriptGrammar::T_AND_EQ;
+ return QmlJSGrammar::T_AND_EQ;
} else if (c1 == '^' && c2 == '=') {
shift(2);
- return JavaScriptGrammar::T_XOR_EQ;
+ return QmlJSGrammar::T_XOR_EQ;
} else if (c1 == '%' && c2 == '=') {
shift(2);
- return JavaScriptGrammar::T_REMAINDER_EQ;
+ return QmlJSGrammar::T_REMAINDER_EQ;
} else if (c1 == '|' && c2 == '=') {
shift(2);
- return JavaScriptGrammar::T_OR_EQ;
+ return QmlJSGrammar::T_OR_EQ;
} else if (c1 == '<' && c2 == '<') {
shift(2);
- return JavaScriptGrammar::T_LT_LT;
+ return QmlJSGrammar::T_LT_LT;
} else if (c1 == '>' && c2 == '>') {
shift(2);
- return JavaScriptGrammar::T_GT_GT;
+ return QmlJSGrammar::T_GT_GT;
} else if (c1 == '&' && c2 == '&') {
shift(2);
- return JavaScriptGrammar::T_AND_AND;
+ return QmlJSGrammar::T_AND_AND;
} else if (c1 == '|' && c2 == '|') {
shift(2);
- return JavaScriptGrammar::T_OR_OR;
+ return QmlJSGrammar::T_OR_OR;
}
switch(c1) {
- case '=': shift(1); return JavaScriptGrammar::T_EQ;
- case '>': shift(1); return JavaScriptGrammar::T_GT;
- case '<': shift(1); return JavaScriptGrammar::T_LT;
- case ',': shift(1); return JavaScriptGrammar::T_COMMA;
- case '!': shift(1); return JavaScriptGrammar::T_NOT;
- case '~': shift(1); return JavaScriptGrammar::T_TILDE;
- case '?': shift(1); return JavaScriptGrammar::T_QUESTION;
- case ':': shift(1); return JavaScriptGrammar::T_COLON;
- case '.': shift(1); return JavaScriptGrammar::T_DOT;
- case '+': shift(1); return JavaScriptGrammar::T_PLUS;
- case '-': shift(1); return JavaScriptGrammar::T_MINUS;
- case '*': shift(1); return JavaScriptGrammar::T_STAR;
- case '/': shift(1); return JavaScriptGrammar::T_DIVIDE_;
- case '&': shift(1); return JavaScriptGrammar::T_AND;
- case '|': shift(1); return JavaScriptGrammar::T_OR;
- case '^': shift(1); return JavaScriptGrammar::T_XOR;
- case '%': shift(1); return JavaScriptGrammar::T_REMAINDER;
- case '(': shift(1); return JavaScriptGrammar::T_LPAREN;
- case ')': shift(1); return JavaScriptGrammar::T_RPAREN;
- case '{': shift(1); return JavaScriptGrammar::T_LBRACE;
- case '}': shift(1); return JavaScriptGrammar::T_RBRACE;
- case '[': shift(1); return JavaScriptGrammar::T_LBRACKET;
- case ']': shift(1); return JavaScriptGrammar::T_RBRACKET;
- case ';': shift(1); return JavaScriptGrammar::T_SEMICOLON;
+ case '=': shift(1); return QmlJSGrammar::T_EQ;
+ case '>': shift(1); return QmlJSGrammar::T_GT;
+ case '<': shift(1); return QmlJSGrammar::T_LT;
+ case ',': shift(1); return QmlJSGrammar::T_COMMA;
+ case '!': shift(1); return QmlJSGrammar::T_NOT;
+ case '~': shift(1); return QmlJSGrammar::T_TILDE;
+ case '?': shift(1); return QmlJSGrammar::T_QUESTION;
+ case ':': shift(1); return QmlJSGrammar::T_COLON;
+ case '.': shift(1); return QmlJSGrammar::T_DOT;
+ case '+': shift(1); return QmlJSGrammar::T_PLUS;
+ case '-': shift(1); return QmlJSGrammar::T_MINUS;
+ case '*': shift(1); return QmlJSGrammar::T_STAR;
+ case '/': shift(1); return QmlJSGrammar::T_DIVIDE_;
+ case '&': shift(1); return QmlJSGrammar::T_AND;
+ case '|': shift(1); return QmlJSGrammar::T_OR;
+ case '^': shift(1); return QmlJSGrammar::T_XOR;
+ case '%': shift(1); return QmlJSGrammar::T_REMAINDER;
+ case '(': shift(1); return QmlJSGrammar::T_LPAREN;
+ case ')': shift(1); return QmlJSGrammar::T_RPAREN;
+ case '{': shift(1); return QmlJSGrammar::T_LBRACE;
+ case '}': shift(1); return QmlJSGrammar::T_RBRACE;
+ case '[': shift(1); return QmlJSGrammar::T_LBRACKET;
+ case ']': shift(1); return QmlJSGrammar::T_RBRACKET;
+ case ';': shift(1); return QmlJSGrammar::T_SEMICOLON;
default: return -1;
}
diff --git a/src/declarative/qml/parser/javascriptlexer_p.h b/src/declarative/qml/parser/qmljslexer_p.h
index a47c1ae..e1ff23e 100644
--- a/src/declarative/qml/parser/javascriptlexer_p.h
+++ b/src/declarative/qml/parser/qmljslexer_p.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef JAVASCRIPTLEXER_P_H
-#define JAVASCRIPTLEXER_P_H
+#ifndef QMLJSLEXER_P_H
+#define QMLJSLEXER_P_H
//
// W A R N I N G
@@ -59,7 +59,7 @@
QT_BEGIN_NAMESPACE
-namespace JavaScript {
+namespace QmlJS {
class Engine;
class NameId;
@@ -260,7 +260,7 @@ private:
bool prohibitAutomaticSemicolon;
};
-} // namespace JavaScript
+} // namespace QmlJS
QT_END_NAMESPACE
diff --git a/src/declarative/qml/parser/javascriptmemorypool_p.h b/src/declarative/qml/parser/qmljsmemorypool_p.h
index cff7677..d7506be 100644
--- a/src/declarative/qml/parser/javascriptmemorypool_p.h
+++ b/src/declarative/qml/parser/qmljsmemorypool_p.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef JAVASCRIPTMEMORYPOOL_P_H
-#define JAVASCRIPTMEMORYPOOL_P_H
+#ifndef QMLJSMEMORYPOOL_P_H
+#define QMLJSMEMORYPOOL_P_H
//
// W A R N I N G
@@ -59,7 +59,7 @@
QT_BEGIN_NAMESPACE
-namespace JavaScript {
+namespace QmlJS {
class MemoryPool : public QSharedData
{
@@ -123,7 +123,7 @@ private:
Q_DISABLE_COPY(MemoryPool)
};
-} // namespace JavaScript
+} // namespace QmlJS
QT_END_NAMESPACE
diff --git a/src/declarative/qml/parser/javascriptnodepool_p.h b/src/declarative/qml/parser/qmljsnodepool_p.h
index cb56fbb..1a5b7f6 100644
--- a/src/declarative/qml/parser/javascriptnodepool_p.h
+++ b/src/declarative/qml/parser/qmljsnodepool_p.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef JAVASCRIPTNODEPOOL_P_H
-#define JAVASCRIPTNODEPOOL_P_H
+#ifndef QMLJSNODEPOOL_P_H
+#define QMLJSNODEPOOL_P_H
//
// W A R N I N G
@@ -56,11 +56,11 @@
#include <QtCore/QHash>
#include <QtCore/QString>
-#include "javascriptmemorypool_p.h"
+#include "qmljsmemorypool_p.h"
QT_BEGIN_NAMESPACE
-namespace JavaScript {
+namespace QmlJS {
namespace AST {
class Node;
@@ -131,7 +131,7 @@ private:
Q_DISABLE_COPY(NodePool)
};
-} // namespace JavaScript
+} // namespace QmlJS
QT_END_NAMESPACE
diff --git a/src/declarative/qml/parser/javascriptparser.cpp b/src/declarative/qml/parser/qmljsparser.cpp
index 34ecd0e..6ecff3d 100644
--- a/src/declarative/qml/parser/javascriptparser.cpp
+++ b/src/declarative/qml/parser/qmljsparser.cpp
@@ -45,22 +45,22 @@
#include <string.h>
-#include "javascriptengine_p.h"
-#include "javascriptlexer_p.h"
-#include "javascriptast_p.h"
-#include "javascriptnodepool_p.h"
+#include "qmljsengine_p.h"
+#include "qmljslexer_p.h"
+#include "qmljsast_p.h"
+#include "qmljsnodepool_p.h"
-#include "javascriptparser_p.h"
+#include "qmljsparser_p.h"
#include <QVarLengthArray>
//
-// This file is automatically generated from javascript.g.
+// This file is automatically generated from qmljs.g.
// Changes will be lost.
//
-using namespace JavaScript;
+using namespace QmlJS;
QT_BEGIN_NAMESPACE
@@ -78,7 +78,7 @@ void Parser::reallocateStack()
inline static bool automatic(Engine *driver, int token)
{
- return token == JavaScriptGrammar::T_RBRACE
+ return token == QmlJSGrammar::T_RBRACE
|| token == 0
|| driver->lexer()->prevTerminator();
}
@@ -239,12 +239,13 @@ case 10: {
} break;
case 11: {
- sym(1).Node = makeAstNode<AST::UiObjectMemberList> (driver->nodePool(), sym(1).UiObjectMember);
+ sym(1).Node = makeAstNode<AST::UiArrayMemberList> (driver->nodePool(), sym(1).UiObjectMember);
} break;
case 12: {
- AST::UiObjectMemberList *node = makeAstNode<AST:: UiObjectMemberList> (driver->nodePool(),
- sym(1).UiObjectMemberList, sym(3).UiObjectMember);
+ AST::UiArrayMemberList *node = makeAstNode<AST::UiArrayMemberList> (driver->nodePool(),
+ sym(1).UiArrayMemberList, sym(3).UiObjectMember);
+ node->commaToken = loc(2);
sym(1).Node = node;
} break;
@@ -270,7 +271,7 @@ case 15: {
case 17: {
AST::UiArrayBinding *node = makeAstNode<AST::UiArrayBinding> (driver->nodePool(), sym(1).UiQualifiedId->finish(),
- sym(4).UiObjectMemberList->finish());
+ sym(4).UiArrayMemberList->finish());
node->colonToken = loc(2);
node->lbracketToken = loc(3);
node->rbracketToken = loc(5);
@@ -388,13 +389,13 @@ case 43:
} break;
case 45: {
- QString s = QLatin1String(JavaScriptGrammar::spell[T_PROPERTY]);
+ QString s = QLatin1String(QmlJSGrammar::spell[T_PROPERTY]);
sym(1).sval = driver->intern(s.constData(), s.length());
break;
}
case 46: {
- QString s = QLatin1String(JavaScriptGrammar::spell[T_SIGNAL]);
+ QString s = QLatin1String(QmlJSGrammar::spell[T_SIGNAL]);
sym(1).sval = driver->intern(s.constData(), s.length());
break;
}
diff --git a/src/declarative/qml/parser/javascriptparser_p.h b/src/declarative/qml/parser/qmljsparser_p.h
index 2ae4c34..cd2c7f5 100644
--- a/src/declarative/qml/parser/javascriptparser_p.h
+++ b/src/declarative/qml/parser/qmljsparser_p.h
@@ -53,16 +53,16 @@
//
//
-// This file is automatically generated from javascript.g.
+// This file is automatically generated from qmljs.g.
// Changes will be lost.
//
-#ifndef JAVASCRIPTPARSER_P_H
-#define JAVASCRIPTPARSER_P_H
+#ifndef QMLJSPARSER_P_H
+#define QMLJSPARSER_P_H
-#include "javascriptgrammar_p.h"
-#include "javascriptast_p.h"
-#include "javascriptengine_p.h"
+#include "qmljsgrammar_p.h"
+#include "qmljsast_p.h"
+#include "qmljsengine_p.h"
#include <QtCore/QList>
@@ -70,12 +70,12 @@ QT_BEGIN_NAMESPACE
class QString;
-namespace JavaScript {
+namespace QmlJS {
class Engine;
class NameId;
-class Parser: protected JavaScriptGrammar
+class Parser: protected QmlJSGrammar
{
public:
union Value {
@@ -117,6 +117,7 @@ public:
AST::UiArrayBinding *UiArrayBinding;
AST::UiObjectMember *UiObjectMember;
AST::UiObjectMemberList *UiObjectMemberList;
+ AST::UiArrayMemberList *UiArrayMemberList;
AST::UiQualifiedId *UiQualifiedId;
};
@@ -192,7 +193,7 @@ protected:
QList<DiagnosticMessage> diagnostic_messages;
};
-} // end of namespace JavaScript
+} // end of namespace QmlJS
@@ -204,4 +205,4 @@ QT_END_NAMESPACE
-#endif // JAVASCRIPTPARSER_P_H
+#endif // QMLJSPARSER_P_H
diff --git a/src/declarative/qml/parser/javascriptprettypretty.cpp b/src/declarative/qml/parser/qmljsprettypretty.cpp
index 0342b39..1045792 100644
--- a/src/declarative/qml/parser/javascriptprettypretty.cpp
+++ b/src/declarative/qml/parser/qmljsprettypretty.cpp
@@ -39,16 +39,16 @@
**
****************************************************************************/
-#include "javascriptprettypretty_p.h"
+#include "qmljsprettypretty_p.h"
-#include "javascriptengine_p.h"
+#include "qmljsengine_p.h"
-#include "javascriptast_p.h"
+#include "qmljsast_p.h"
#include <QtCore/QString>
#include <QtCore/QTextStream>
@@ -56,11 +56,11 @@
QT_BEGIN_NAMESPACE
-namespace JavaScript {
+namespace QmlJS {
QString numberToString(double value);
}
-using namespace JavaScript;
+using namespace QmlJS;
PrettyPretty::PrettyPretty(QTextStream &o):
out(o), m_indentLevel(0)
@@ -242,7 +242,7 @@ void PrettyPretty::endVisit(AST::StringLiteral *node)
bool PrettyPretty::visit(AST::NumericLiteral *node)
{
- out << JavaScript::numberToString(node->value);
+ out << QmlJS::numberToString(node->value);
return true;
}
@@ -255,7 +255,7 @@ bool PrettyPretty::visit(AST::RegExpLiteral *node)
{
out << "/" << Engine::toString(node->pattern) << "/";
if (node->flags)
- out << JavaScript::Ecma::RegExp::flagsToString(node->flags);
+ out << QmlJS::Ecma::RegExp::flagsToString(node->flags);
return true;
}
diff --git a/src/declarative/qml/parser/javascriptprettypretty_p.h b/src/declarative/qml/parser/qmljsprettypretty_p.h
index c692da5..fe82ca2 100644
--- a/src/declarative/qml/parser/javascriptprettypretty_p.h
+++ b/src/declarative/qml/parser/qmljsprettypretty_p.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef JAVASCRIPTPRETTYPRETTY_P_H
-#define JAVASCRIPTPRETTYPRETTY_P_H
+#ifndef QMLJSPRETTYPRETTY_P_H
+#define QMLJSPRETTYPRETTY_P_H
//
// W A R N I N G
@@ -55,13 +55,13 @@
#include <QtCore/qglobal.h>
-#include "javascriptastvisitor_p.h"
+#include "qmljsastvisitor_p.h"
QT_BEGIN_NAMESPACE
class QTextStream;
-namespace JavaScript {
+namespace QmlJS {
class PrettyPretty: protected AST::Visitor
{
@@ -322,7 +322,7 @@ private:
Q_DISABLE_COPY(PrettyPretty)
};
-} // namespace JavaScript
+} // namespace QmlJS
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index c61200e..efe4d3f 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -63,7 +63,8 @@ HEADERS += qml/qmlparser_p.h \
qml/qmldeclarativedata_p.h \
qml/qmlerror.h \
qml/qmlscriptparser_p.h \
- qml/qmlbasicscript_p.h
+ qml/qmlbasicscript_p.h \
+ qml/qpodvector_p.h
# for qtscript debugger
QT += scripttools
diff --git a/src/declarative/qml/qmlbasicscript.cpp b/src/declarative/qml/qmlbasicscript.cpp
index 7bd898c..dd6766e 100644
--- a/src/declarative/qml/qmlbasicscript.cpp
+++ b/src/declarative/qml/qmlbasicscript.cpp
@@ -17,16 +17,24 @@
#include <QStack>
#include <qfxperf.h>
#include <private/qmlrefcount_p.h>
-#include <private/javascriptast_p.h>
-#include <private/javascriptengine_p.h>
+#include <private/qmljsast_p.h>
+#include <private/qmljsengine_p.h>
QT_BEGIN_NAMESPACE
+using namespace QmlJS;
+
struct ScriptInstruction {
enum {
Load, // fetch
Fetch, // fetch
+ LoadIdObject, // fetch
+ FetchConstant, // constant
+ FetchD0Constant, // constant
+ FetchD1Constant, // constant
+
+
Add, // NA
Subtract, // NA
Multiply, // NA
@@ -47,6 +55,11 @@ struct ScriptInstruction {
struct {
bool value;
} boolean;
+ struct {
+ short idx;
+ short notify;
+ int type;
+ } constant;
};
};
@@ -249,19 +262,24 @@ struct QmlBasicScriptCompiler
{
QmlBasicScriptCompiler()
: script(0), stateSize(0) {}
+
QmlBasicScript *script;
int stateSize;
- bool compile(JavaScript::AST::Node *);
+ QmlParser::Object *context;
+ QmlParser::Object *component;
+ QHash<QString, QPair<QmlParser::Object *, int> > ids;
+
+ bool compile(QmlJS::AST::Node *);
- bool compileExpression(JavaScript::AST::Node *);
+ bool compileExpression(QmlJS::AST::Node *);
- bool tryConstant(JavaScript::AST::Node *);
- bool parseConstant(JavaScript::AST::Node *);
- bool tryName(JavaScript::AST::Node *);
- bool parseName(JavaScript::AST::Node *);
- bool tryBinaryExpression(JavaScript::AST::Node *);
- bool compileBinaryExpression(JavaScript::AST::Node *);
+ bool tryConstant(QmlJS::AST::Node *);
+ bool parseConstant(QmlJS::AST::Node *);
+ bool tryName(QmlJS::AST::Node *);
+ bool parseName(QmlJS::AST::Node *, QmlParser::Object ** = 0);
+ bool tryBinaryExpression(QmlJS::AST::Node *);
+ bool compileBinaryExpression(QmlJS::AST::Node *);
QByteArray data;
QList<ScriptInstruction> bytecode;
@@ -270,10 +288,10 @@ struct QmlBasicScriptCompiler
/*!
\internal
\class QmlBasicScript
- \brief The QmlBasicScript class provides a fast implementation of a limited subset of JavaScript bindings.
+ \brief The QmlBasicScript class provides a fast implementation of a limited subset of QmlJS bindings.
QmlBasicScript instances are used to accelerate binding. Instead of using
- the slower, fully fledged JavaScript engine, many simple bindings can be
+ the slower, fully fledged QmlJS engine, many simple bindings can be
evaluated using the QmlBasicScript engine.
To see if the QmlBasicScript engine can handle a binding, call compile()
@@ -437,19 +455,18 @@ bool QmlBasicScript::isValid() const
return d != 0;
}
-/*!
- Compile \a v and return true if the compilation is successful, otherwise
- returns false.
- */
-bool QmlBasicScript::compile(const QmlParser::Variant &v)
+bool QmlBasicScript::compile(const Expression &expression)
{
- if (!v.asAST()) return false;
+ if (!expression.expression.asAST()) return false;
- QByteArray expr = v.asScript().toLatin1();
+ QByteArray expr = expression.expression.asScript().toLatin1();
const char *src = expr.constData();
QmlBasicScriptCompiler bsc;
bsc.script = this;
+ bsc.context = expression.context;
+ bsc.component = expression.component;
+ bsc.ids = expression.ids;
if (d) {
if (flags & QmlBasicScriptPrivate::OwnData)
@@ -458,7 +475,7 @@ bool QmlBasicScript::compile(const QmlParser::Variant &v)
flags = 0;
}
- if (bsc.compile(v.asAST())) {
+ if (bsc.compile(expression.expression.asAST())) {
int len = ::strlen(src);
flags = QmlBasicScriptPrivate::OwnData;
int size = sizeof(QmlBasicScriptPrivate) +
@@ -478,13 +495,12 @@ bool QmlBasicScript::compile(const QmlParser::Variant &v)
return d != 0;
}
-bool QmlBasicScriptCompiler::compile(JavaScript::AST::Node *node)
+bool QmlBasicScriptCompiler::compile(QmlJS::AST::Node *node)
{
return compileExpression(node);
}
-using namespace JavaScript;
-bool QmlBasicScriptCompiler::tryConstant(JavaScript::AST::Node *node)
+bool QmlBasicScriptCompiler::tryConstant(QmlJS::AST::Node *node)
{
if (node->kind == AST::Node::Kind_TrueLiteral ||
node->kind == AST::Node::Kind_FalseLiteral)
@@ -500,7 +516,7 @@ bool QmlBasicScriptCompiler::tryConstant(JavaScript::AST::Node *node)
return false;
}
-bool QmlBasicScriptCompiler::parseConstant(JavaScript::AST::Node *node)
+bool QmlBasicScriptCompiler::parseConstant(QmlJS::AST::Node *node)
{
ScriptInstruction instr;
@@ -518,16 +534,17 @@ bool QmlBasicScriptCompiler::parseConstant(JavaScript::AST::Node *node)
return true;
}
-bool QmlBasicScriptCompiler::tryName(JavaScript::AST::Node *node)
+bool QmlBasicScriptCompiler::tryName(QmlJS::AST::Node *node)
{
return node->kind == AST::Node::Kind_IdentifierExpression ||
node->kind == AST::Node::Kind_FieldMemberExpression;
}
-bool QmlBasicScriptCompiler::parseName(AST::Node *node)
+bool QmlBasicScriptCompiler::parseName(AST::Node *node,
+ QmlParser::Object **type)
{
bool load = false;
-
+ QmlParser::Object *loadedType = 0;
QString name;
if (node->kind == AST::Node::Kind_IdentifierExpression) {
name = static_cast<AST::IdentifierExpression *>(node)->name->asString();
@@ -535,7 +552,7 @@ bool QmlBasicScriptCompiler::parseName(AST::Node *node)
} else if (node->kind == AST::Node::Kind_FieldMemberExpression) {
AST::FieldMemberExpression *expr = static_cast<AST::FieldMemberExpression *>(node);
- if (!parseName(expr->base))
+ if (!parseName(expr->base, &loadedType))
return false;
name = expr->name->asString();
@@ -543,22 +560,76 @@ bool QmlBasicScriptCompiler::parseName(AST::Node *node)
return false;
}
- int nref = data.count();
- data.append(name.toUtf8());
- data.append('\0');
ScriptInstruction instr;
- if (load)
- instr.type = ScriptInstruction::Load;
- else
- instr.type = ScriptInstruction::Fetch;
- instr.fetch.idx = nref;
- bytecode.append(instr);
- ++stateSize;
+ if (load) {
+
+ if (ids.contains(name)) {
+ instr.type = ScriptInstruction::LoadIdObject;
+ instr.fetch.idx = ids.value(name).second;
+
+ if (type)
+ *type = ids.value(name).first;
+
+ } else {
+ int d0Idx = context->metaObject()->indexOfProperty(name.toUtf8().constData());
+ int d1Idx = -1;
+ if (d0Idx == -1)
+ d1Idx = component->metaObject()->indexOfProperty(name.toUtf8().constData());
+ if (d0Idx != -1) {
+
+ instr.type = ScriptInstruction::FetchD0Constant;
+ instr.constant.idx = d0Idx;
+ QMetaProperty prop = context->metaObject()->property(d0Idx);
+ instr.constant.notify = prop.notifySignalIndex();
+ instr.constant.type = prop.userType();
+
+ } else if (d1Idx != -1) {
+
+ instr.type = ScriptInstruction::FetchD1Constant;
+ instr.constant.idx = d1Idx;
+ QMetaProperty prop = component->metaObject()->property(d1Idx);
+ instr.constant.notify = prop.notifySignalIndex();
+ instr.constant.type = prop.userType();
+
+ } else {
+
+ int nref = data.count();
+ data.append(name.toUtf8());
+ data.append('\0');
+ instr.type = ScriptInstruction::Load;
+ instr.fetch.idx = nref;
+ ++stateSize;
+
+ }
+ }
+
+ } else {
+
+ int idx = -1;
+ if (loadedType)
+ idx = loadedType->metaObject()->indexOfProperty(name.toUtf8().constData());
+ if (idx != -1) {
+ instr.type = ScriptInstruction::FetchConstant;
+ instr.constant.idx = idx;
+ QMetaProperty prop = loadedType->metaObject()->property(idx);
+ instr.constant.notify = prop.notifySignalIndex();
+ instr.constant.type = prop.userType();
+ } else {
+ int nref = data.count();
+ data.append(name.toUtf8());
+ data.append('\0');
+ instr.type = ScriptInstruction::Fetch;
+ instr.fetch.idx = nref;
+ ++stateSize;
+ }
+
+ }
+ bytecode.append(instr);
return true;
}
-bool QmlBasicScriptCompiler::compileExpression(JavaScript::AST::Node *node)
+bool QmlBasicScriptCompiler::compileExpression(QmlJS::AST::Node *node)
{
if (tryBinaryExpression(node))
return compileBinaryExpression(node);
@@ -679,12 +750,16 @@ QVariant QmlBasicScript::run(QmlContext *context, void *voidCache, CacheState *c
{
if (!isValid())
return QVariant();
+
+ QmlContextPrivate *contextPrivate = context->d_func();
+ QmlEnginePrivate *enginePrivate = context->engine()->d_func();
QmlBasicScriptNodeCache *dataCache =
reinterpret_cast<QmlBasicScriptNodeCache *>(voidCache);
int dataCacheItem;
- QStack<QVariant> stack;
+ QStack<QVariant> stack;
+
bool resetting = false;
bool hasReset = false;
@@ -702,6 +777,49 @@ QVariant QmlBasicScript::run(QmlContext *context, void *voidCache, CacheState *c
const ScriptInstruction &instr = d->instructions()[idx];
switch(instr.type) {
+ case ScriptInstruction::LoadIdObject:
+ {
+ stack.push(contextPrivate->propertyValues.at(instr.fetch.idx));
+ enginePrivate->capturedProperties <<
+ QmlEnginePrivate::CapturedProperty(context, contextPrivate->notifyIndex + instr.fetch.idx);
+ state = Reset;
+ }
+ break;
+
+ case ScriptInstruction::FetchD0Constant:
+ {
+ QObject *obj = contextPrivate->defaultObjects.at(0);
+
+ stack.push(fetch_value(obj, instr.constant.idx, instr.constant.type));
+ enginePrivate->capturedProperties <<
+ QmlEnginePrivate::CapturedProperty(obj, instr.constant.notify);
+ state = Reset;
+ }
+ break;
+
+ case ScriptInstruction::FetchD1Constant:
+ {
+ QObject *obj = contextPrivate->defaultObjects.at(1);
+
+ stack.push(fetch_value(obj, instr.constant.idx, instr.constant.type));
+ enginePrivate->capturedProperties <<
+ QmlEnginePrivate::CapturedProperty(obj, instr.constant.notify);
+ state = Reset;
+ }
+ break;
+
+ case ScriptInstruction::FetchConstant:
+ {
+ QVariant o = stack.pop();
+ QObject *obj = qvariant_cast<QObject *>(o);
+
+ stack.push(fetch_value(obj, instr.constant.idx, instr.constant.type));
+ enginePrivate->capturedProperties <<
+ QmlEnginePrivate::CapturedProperty(obj, instr.constant.notify);
+ state = Reset;
+ }
+ break;
+
case ScriptInstruction::Load: // either an object or a property
case ScriptInstruction::Fetch: // can only be a property
{
diff --git a/src/declarative/qml/qmlbasicscript_p.h b/src/declarative/qml/qmlbasicscript_p.h
index 1117e11..43c0d36 100644
--- a/src/declarative/qml/qmlbasicscript_p.h
+++ b/src/declarative/qml/qmlbasicscript_p.h
@@ -38,7 +38,16 @@ public:
QByteArray expression() const;
- bool compile(const QmlParser::Variant &);
+ struct Expression
+ {
+ QmlParser::Object *component;
+ QmlParser::Object *context;
+ QmlParser::Property *property;
+ QmlParser::Variant expression;
+ QHash<QString, QPair<QmlParser::Object *, int> > ids;
+ };
+
+ bool compile(const Expression &);
bool isValid() const;
void clear();
diff --git a/src/declarative/qml/qmlbindablevalue.cpp b/src/declarative/qml/qmlbindablevalue.cpp
index 351e0bd..e1b6961 100644
--- a/src/declarative/qml/qmlbindablevalue.cpp
+++ b/src/declarative/qml/qmlbindablevalue.cpp
@@ -58,12 +58,6 @@ QmlBindableValuePrivate::QmlBindableValuePrivate()
}
QML_DEFINE_NOCREATE_TYPE(QmlBindableValue);
-QmlBindableValue::QmlBindableValue(QObject *parent)
-: QmlPropertyValueSource(*new QmlBindableValuePrivate, parent)
-{
- qFatal("QmlBindableValue: Default constructor not supported");
-}
-
QmlBindableValue::QmlBindableValue(void *data, QmlRefCount *rc, QObject *obj, QObject *parent)
: QmlPropertyValueSource(*new QmlBindableValuePrivate, parent), QmlExpression(QmlContext::activeContext(), data, rc, obj)
{
@@ -125,101 +119,25 @@ void QmlBindableValue::update()
if (!d->updating) {
d->updating = true;
- if (d->property.propertyCategory() == QmlMetaProperty::List) {
- QVariant value = this->value();
- int listType = QmlMetaType::listType(d->property.propertyType());
-
- if (value.userType() == qMetaTypeId<QList<QObject *> >()) {
- const QList<QObject *> &list =
- qvariant_cast<QList<QObject *> >(value);
- QVariant listVar = d->property.read();
- QmlMetaType::clear(listVar);
- for (int ii = 0; ii < list.count(); ++ii) {
- QVariant v = QmlMetaType::fromObject(list.at(ii), listType);
- QmlMetaType::append(listVar, v);
- }
-
- } else if (value.type() == uint(listType) ||
- value.userType() == listType) {
- QVariant listVar = d->property.read();
- QmlMetaType::clear(listVar);
- QmlMetaType::append(listVar, value);
- }
- } else if (d->property.propertyCategory() == QmlMetaProperty::QmlList) {
- // XXX - optimize!
- QVariant value = this->value();
- QVariant list = d->property.read();
- QmlPrivate::ListInterface *li =
- *(QmlPrivate::ListInterface **)list.constData();
-
- int type = li->type();
-
- if (QObject *obj = QmlMetaType::toQObject(value)) {
- const QMetaObject *mo =
- QmlMetaType::rawMetaObjectForType(type);
-
- const QMetaObject *objMo = obj->metaObject();
- bool found = false;
- while(!found && objMo) {
- if (objMo == mo)
- found = true;
- else
- objMo = objMo->superClass();
- }
-
- if (!found) {
- qWarning() << "Unable to assign object to list";
- return;
- }
-
- // NOTE: This assumes a cast to QObject does not alter
- // the object pointer
- void *d = (void *)&obj;
- li->append(d);
- }
- } else if (d->property.propertyCategory() == QmlMetaProperty::Bindable) {
-
- // NOTE: We assume that only core properties can have
- // propertyType == Bindable
+ if (d->property.propertyCategory() == QmlMetaProperty::Bindable) {
+
int idx = d->property.coreIndex();
Q_ASSERT(idx != -1);
void *a[1];
QmlBindableValue *t = this;
a[0] = (void *)&t;
- d->property.object()->qt_metacall(QMetaObject::WriteProperty,
- idx, a);
+ QMetaObject::metacall(d->property.object(),
+ QMetaObject::WriteProperty,
+ idx, a);
- } else if (d->property.propertyCategory() == QmlMetaProperty::Object) {
+ } else {
QVariant value = this->value();
- if ((int)value.type() != qMetaTypeId<QObject *>()) {
- if (scriptWarnings()) {
- if (!value.isValid()) {
- qWarning() << "QmlBindableValue: Unable to assign invalid value to object property";
- } else {
- qWarning() << "QmlBindableValue: Unable to assign non-object to object property";
- }
- }
- return;
- }
-
- // NOTE: This assumes a cast to QObject does not alter the
- // object pointer
- QObject *obj = *(QObject **)value.data();
-
- // NOTE: We assume that only core properties can have
- // propertyType == Object
- int idx = d->property.coreIndex();
- Q_ASSERT(idx != -1);
+ if (d->property.propertyType() == QVariant::Url &&
+ value.canConvert(QVariant::String) && !value.isNull())
+ value.setValue(context()->resolvedUrl(value.toString()));
- void *a[1];
- a[0] = (void *)&obj;
- d->property.object()->qt_metacall(QMetaObject::WriteProperty,
- idx, a);
-
- } else if (d->property.propertyCategory() == QmlMetaProperty::Normal) {
- QVariant value = this->value();
d->property.write(value);
}
diff --git a/src/declarative/qml/qmlbindablevalue.h b/src/declarative/qml/qmlbindablevalue.h
index 71a7051..f54481a 100644
--- a/src/declarative/qml/qmlbindablevalue.h
+++ b/src/declarative/qml/qmlbindablevalue.h
@@ -62,7 +62,6 @@ class Q_DECLARATIVE_EXPORT QmlBindableValue : public QmlPropertyValueSource,
{
Q_OBJECT
public:
- QmlBindableValue(QObject *parent);
QmlBindableValue(const QString &, QObject *, QObject *parent=0);
QmlBindableValue(void *, QmlRefCount *, QObject *, QObject *parent);
~QmlBindableValue();
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index b28d7dd..3123254 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -62,7 +62,7 @@
#include "private/qmlcustomparser_p_p.h"
#include <private/qmlcontext_p.h>
#include <private/qmlcomponent_p.h>
-#include "parser/javascriptast_p.h"
+#include "parser/qmljsast_p.h"
#include "qmlscriptparser_p.h"
@@ -278,6 +278,14 @@ bool QmlCompiler::compileStoreInstruction(QmlInstruction &instr,
instr.storeString.value = output->indexForString(string);
}
break;
+ case QVariant::Url:
+ {
+ instr.type = QmlInstruction::StoreUrl;
+ QUrl u = output->url.resolved(string);
+ instr.storeUrl.propertyIndex = prop.propertyIndex();
+ instr.storeUrl.value = output->indexForString(u.toString());
+ }
+ break;
case QVariant::UInt:
{
instr.type = QmlInstruction::StoreInteger;
@@ -533,6 +541,8 @@ bool QmlCompiler::compile(QmlEngine *engine,
void QmlCompiler::compileTree(Object *tree)
{
+ compileState.root = tree;
+
QmlInstruction init;
init.type = QmlInstruction::Init;
init.line = 0;
@@ -557,7 +567,7 @@ void QmlCompiler::compileTree(Object *tree)
finalizeComponent(0);
}
-bool QmlCompiler::compileObject(Object *obj, int ctxt)
+bool QmlCompiler::compileObject(Object *obj, const BindingContext &ctxt)
{
Q_ASSERT (obj->type != -1);
obj->metatype = output->types.at(obj->type).metaObject();
@@ -567,7 +577,7 @@ bool QmlCompiler::compileObject(Object *obj, int ctxt)
return true;
}
- ctxt = 0;
+ BindingContext objCtxt(obj);
int createInstrIdx = output->bytecode.count();
// Create the object
@@ -617,7 +627,7 @@ bool QmlCompiler::compileObject(Object *obj, int ctxt)
if (isCustomParser) {
// Custom parser types don't support signal properties
if (testProperty(prop, obj)) {
- COMPILE_CHECK(compileProperty(prop, obj, ctxt));
+ COMPILE_CHECK(compileProperty(prop, obj, objCtxt));
} else {
customProps << QmlCustomParserNodePrivate::fromProperty(prop);
}
@@ -625,7 +635,7 @@ bool QmlCompiler::compileObject(Object *obj, int ctxt)
if (isSignalPropertyName(prop->name)) {
COMPILE_CHECK(compileSignal(prop,obj));
} else {
- COMPILE_CHECK(compileProperty(prop, obj, ctxt));
+ COMPILE_CHECK(compileProperty(prop, obj, objCtxt));
}
}
@@ -637,12 +647,12 @@ bool QmlCompiler::compileObject(Object *obj, int ctxt)
if (isCustomParser) {
if (testProperty(prop, obj)) {
- COMPILE_CHECK(compileProperty(prop, obj, ctxt));
+ COMPILE_CHECK(compileProperty(prop, obj, objCtxt));
} else {
customProps << QmlCustomParserNodePrivate::fromProperty(prop);
}
} else {
- COMPILE_CHECK(compileProperty(prop, obj, ctxt));
+ COMPILE_CHECK(compileProperty(prop, obj, objCtxt));
}
}
@@ -673,7 +683,7 @@ bool QmlCompiler::compileObject(Object *obj, int ctxt)
return true;
}
-bool QmlCompiler::compileComponent(Object *obj, int ctxt)
+bool QmlCompiler::compileComponent(Object *obj, const BindingContext &ctxt)
{
Property *idProp = 0;
if (obj->properties.count() > 1 ||
@@ -709,6 +719,7 @@ bool QmlCompiler::compileComponent(Object *obj, int ctxt)
reference.id = val;
reference.object = obj;
reference.instructionIdx = output->bytecode.count();
+ reference.idx = compileState.ids.count();
compileState.ids.insert(val, reference);
int pref = output->indexForString(val);
@@ -724,7 +735,7 @@ bool QmlCompiler::compileComponent(Object *obj, int ctxt)
return true;
}
-bool QmlCompiler::compileComponentFromRoot(Object *obj, int ctxt)
+bool QmlCompiler::compileComponentFromRoot(Object *obj, const BindingContext &ctxt)
{
output->bytecode.push_back(QmlInstruction());
QmlInstruction &create = output->bytecode.last();
@@ -743,6 +754,7 @@ bool QmlCompiler::compileComponentFromRoot(Object *obj, int ctxt)
ComponentCompileState oldComponentCompileState = compileState;
compileState = ComponentCompileState();
+ compileState.root = obj;
if (obj)
COMPILE_CHECK(compileObject(obj, ctxt));
@@ -753,7 +765,7 @@ bool QmlCompiler::compileComponentFromRoot(Object *obj, int ctxt)
}
-bool QmlCompiler::compileFetchedObject(Object *obj, int ctxt)
+bool QmlCompiler::compileFetchedObject(Object *obj, const BindingContext &ctxt)
{
Q_ASSERT(obj->metatype);
@@ -871,7 +883,7 @@ bool QmlCompiler::testProperty(QmlParser::Property *prop,
return false;
}
-bool QmlCompiler::compileProperty(Property *prop, Object *obj, int ctxt)
+bool QmlCompiler::compileProperty(Property *prop, Object *obj, const BindingContext &ctxt)
{
if (prop->values.isEmpty() && !prop->value)
COMPILE_EXCEPTION2(prop, "Empty property assignment");
@@ -992,6 +1004,7 @@ bool QmlCompiler::compileIdProperty(QmlParser::Property *prop,
reference.id = val;
reference.object = obj;
reference.instructionIdx = output->bytecode.count();
+ reference.idx = compileState.ids.count();
compileState.ids.insert(val, reference);
QmlInstruction id;
@@ -1012,7 +1025,7 @@ bool QmlCompiler::compileIdProperty(QmlParser::Property *prop,
// }
// GridView is an attached property object.
bool QmlCompiler::compileAttachedProperty(QmlParser::Property *prop,
- int ctxt)
+ const BindingContext &ctxt)
{
Q_ASSERT(prop->value);
int id = QmlMetaType::attachedPropertiesFuncId(prop->name);
@@ -1024,7 +1037,7 @@ bool QmlCompiler::compileAttachedProperty(QmlParser::Property *prop,
fetch.fetchAttached.id = id;
output->bytecode << fetch;
- COMPILE_CHECK(compileFetchedObject(prop->value, ctxt + 1));
+ COMPILE_CHECK(compileFetchedObject(prop->value, ctxt.incr()));
QmlInstruction pop;
pop.type = QmlInstruction::PopFetchedObject;
@@ -1040,7 +1053,7 @@ bool QmlCompiler::compileAttachedProperty(QmlParser::Property *prop,
// }
// font is a nested property. size is not.
bool QmlCompiler::compileNestedProperty(QmlParser::Property *prop,
- int ctxt)
+ const BindingContext &ctxt)
{
Q_ASSERT(prop->type != 0);
Q_ASSERT(prop->index != -1);
@@ -1057,7 +1070,7 @@ bool QmlCompiler::compileNestedProperty(QmlParser::Property *prop,
fetch.line = prop->location.start.line;
output->bytecode << fetch;
- COMPILE_CHECK(compileFetchedObject(prop->value, ctxt + 1));
+ COMPILE_CHECK(compileFetchedObject(prop->value, ctxt.incr()));
QmlInstruction pop;
pop.type = QmlInstruction::PopFetchedObject;
@@ -1074,7 +1087,7 @@ bool QmlCompiler::compileNestedProperty(QmlParser::Property *prop,
// QmlList<T *> * types can accept a list of objects
bool QmlCompiler::compileListProperty(QmlParser::Property *prop,
QmlParser::Object *obj,
- int ctxt)
+ const BindingContext &ctxt)
{
Q_ASSERT(QmlMetaType::isList(prop->type) ||
QmlMetaType::isQmlList(prop->type));
@@ -1086,7 +1099,9 @@ bool QmlCompiler::compileListProperty(QmlParser::Property *prop,
fetch.line = prop->location.start.line;
fetch.type = QmlInstruction::FetchQmlList;
fetch.fetchQmlList.property = prop->index;
- fetch.fetchQmlList.type = QmlMetaType::qmlListType(t);
+ int listType = QmlMetaType::qmlListType(t);
+ bool listTypeIsInterface = QmlMetaType::isInterface(listType);
+ fetch.fetchQmlList.type = listType;
output->bytecode << fetch;
for (int ii = 0; ii < prop->values.count(); ++ii) {
@@ -1094,12 +1109,23 @@ bool QmlCompiler::compileListProperty(QmlParser::Property *prop,
if (v->object) {
v->type = Value::CreatedObject;
COMPILE_CHECK(compileObject(v->object, ctxt));
- QmlInstruction assign;
- assign.type = QmlInstruction::AssignObjectList;
- assign.line = prop->location.start.line;
- assign.assignObject.property = output->indexForByteArray(prop->name);
- assign.assignObject.castValue = 0;
- output->bytecode << assign;
+
+ if (!listTypeIsInterface) {
+ if (canConvert(listType, v->object)) {
+ QmlInstruction store;
+ store.type = QmlInstruction::StoreObjectQmlList;
+ store.line = prop->location.start.line;
+ output->bytecode << store;
+ } else {
+ COMPILE_EXCEPTION("Cannot assign object to list");
+ }
+
+ } else {
+ QmlInstruction assign;
+ assign.type = QmlInstruction::AssignObjectList;
+ assign.line = prop->location.start.line;
+ output->bytecode << assign;
+ }
} else {
COMPILE_EXCEPTION("Cannot assign primitives to lists");
}
@@ -1113,7 +1139,10 @@ bool QmlCompiler::compileListProperty(QmlParser::Property *prop,
QmlInstruction fetch;
fetch.type = QmlInstruction::FetchQList;
fetch.line = prop->location.start.line;
- fetch.fetch.property = prop->index;
+ fetch.fetchQmlList.property = prop->index;
+ int listType = QmlMetaType::listType(t);
+ bool listTypeIsInterface = QmlMetaType::isInterface(listType);
+ fetch.fetchQmlList.type = listType;
output->bytecode << fetch;
bool assignedBinding = false;
@@ -1122,12 +1151,22 @@ bool QmlCompiler::compileListProperty(QmlParser::Property *prop,
if (v->object) {
v->type = Value::CreatedObject;
COMPILE_CHECK(compileObject(v->object, ctxt));
- QmlInstruction assign;
- assign.type = QmlInstruction::AssignObjectList;
- assign.line = v->location.start.line;
- assign.assignObject.property = output->indexForByteArray(prop->name);
- assign.assignObject.castValue = 0;
- output->bytecode << assign;
+
+ if (!listTypeIsInterface) {
+ if (canConvert(listType, v->object)) {
+ QmlInstruction store;
+ store.type = QmlInstruction::StoreObjectQList;
+ store.line = prop->location.start.line;
+ output->bytecode << store;
+ } else {
+ COMPILE_EXCEPTION("Cannot assign object to list");
+ }
+ } else {
+ QmlInstruction assign;
+ assign.type = QmlInstruction::AssignObjectList;
+ assign.line = v->location.start.line;
+ output->bytecode << assign;
+ }
} else if (v->value.isScript()) {
if (assignedBinding)
COMPILE_EXCEPTION("Can only assign one binding to lists");
@@ -1166,7 +1205,7 @@ bool QmlCompiler::compileListProperty(QmlParser::Property *prop,
// We allow assignming multiple values to single value properties
bool QmlCompiler::compilePropertyAssignment(QmlParser::Property *prop,
QmlParser::Object *obj,
- int ctxt)
+ const BindingContext &ctxt)
{
for (int ii = 0; ii < prop->values.count(); ++ii) {
Value *v = prop->values.at(ii);
@@ -1187,7 +1226,7 @@ bool QmlCompiler::compilePropertyAssignment(QmlParser::Property *prop,
// Compile assigning a single object instance to a regular property
bool QmlCompiler::compilePropertyObjectAssignment(QmlParser::Property *prop,
QmlParser::Value *v,
- int ctxt)
+ const BindingContext &ctxt)
{
Q_ASSERT(prop->index != -1);
Q_ASSERT(v->object->type != -1);
@@ -1296,7 +1335,7 @@ bool QmlCompiler::compilePropertyObjectAssignment(QmlParser::Property *prop,
bool QmlCompiler::compilePropertyLiteralAssignment(QmlParser::Property *prop,
QmlParser::Object *obj,
QmlParser::Value *v,
- int ctxt)
+ const BindingContext &ctxt)
{
Q_ASSERT(prop->index != -1);
@@ -1355,6 +1394,9 @@ bool QmlCompiler::compileDynamicMeta(QmlParser::Object *obj)
case Object::DynamicProperty::String:
type = "QString";
break;
+ case Object::DynamicProperty::Url:
+ type = "QUrl";
+ break;
case Object::DynamicProperty::Color:
type = "QColor";
break;
@@ -1409,7 +1451,7 @@ bool QmlCompiler::compileDynamicMeta(QmlParser::Object *obj)
bool QmlCompiler::compileBinding(QmlParser::Value *value,
QmlParser::Property *prop,
- int ctxt)
+ const BindingContext &ctxt)
{
Q_ASSERT(prop->index);
Q_ASSERT(prop->parent);
@@ -1442,7 +1484,7 @@ bool QmlCompiler::compileBinding(QmlParser::Value *value,
////////////////////////////////////////////////////////////////////////////////
// AST Dump
////////////////////////////////////////////////////////////////////////////////
-class Dump: protected JavaScript::AST::Visitor
+class Dump: protected QmlJS::AST::Visitor
{
std::ostream &out;
int depth;
@@ -1452,11 +1494,11 @@ public:
: out(out), depth(-1)
{ }
- void operator()(JavaScript::AST::Node *node)
- { JavaScript::AST::Node::acceptChild(node, this); }
+ void operator()(QmlJS::AST::Node *node)
+ { QmlJS::AST::Node::acceptChild(node, this); }
protected:
- virtual bool preVisit(JavaScript::AST::Node *node)
+ virtual bool preVisit(QmlJS::AST::Node *node)
{
const char *name = typeid(*node).name();
#ifdef Q_CC_GNU
@@ -1466,7 +1508,7 @@ protected:
return true;
}
- virtual void postVisit(JavaScript::AST::Node *)
+ virtual void postVisit(QmlJS::AST::Node *)
{
--depth;
}
@@ -1491,7 +1533,15 @@ void QmlCompiler::finalizeComponent(int patch)
void QmlCompiler::finalizeBinding(const BindingReference &binding)
{
QmlBasicScript bs;
- bs.compile(binding.expression);
+ QmlBasicScript::Expression expr;
+ expr.component = compileState.root;
+ expr.context = binding.bindingContext.object;
+ expr.property = binding.property;
+ expr.expression = binding.expression;
+ foreach (const IdReference &id, compileState.ids)
+ expr.ids.insert(id.id, qMakePair(id.object, id.idx));
+
+ bs.compile(expr);
QmlInstruction &instr = output->bytecode[binding.instructionIdx];
instr.line = binding.value->location.start.line;
@@ -1553,7 +1603,7 @@ void QmlCompiler::finalizeBinding(const BindingReference &binding)
bref = output->indexForString(binding.expression.asScript());
}
- instr.assignBinding.context = binding.bindingContext;
+ instr.assignBinding.context = binding.bindingContext.stack;
if (bs.isValid())
instr.type = QmlInstruction::StoreCompiledBinding;
@@ -1566,6 +1616,24 @@ void QmlCompiler::finalizeBinding(const BindingReference &binding)
instr.assignBinding.category = QmlMetaProperty::propertyCategory(mp);
}
+/*!
+ Returns true if object can be assigned to a (QObject) property of type
+ convertType.
+*/
+bool QmlCompiler::canConvert(int convertType, QmlParser::Object *object)
+{
+ const QMetaObject *convertTypeMo =
+ QmlMetaType::rawMetaObjectForType(convertType);
+ const QMetaObject *objectMo = object->metaObject();
+
+ while (objectMo) {
+ if (objectMo == convertTypeMo)
+ return true;
+ objectMo = objectMo->superClass();
+ }
+ return false;
+}
+
QmlCompiledData::QmlCompiledData()
{
}
diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h
index 6b6e1e2..3b1a496 100644
--- a/src/declarative/qml/qmlcompiler_p.h
+++ b/src/declarative/qml/qmlcompiler_p.h
@@ -125,50 +125,67 @@ public:
private:
void reset(QmlCompiledComponent *, bool);
+ struct BindingContext {
+ BindingContext()
+ : stack(0), object(0) {}
+ BindingContext(QmlParser::Object *o)
+ : stack(0), object(o) {}
+ BindingContext incr() const {
+ BindingContext rv(object);
+ rv.stack = stack + 1;
+ return rv;
+ }
+ int stack;
+ QmlParser::Object *object;
+ };
+
void compileTree(QmlParser::Object *tree);
- bool compileObject(QmlParser::Object *obj, int);
- bool compileComponent(QmlParser::Object *obj, int);
- bool compileComponentFromRoot(QmlParser::Object *obj, int);
- bool compileFetchedObject(QmlParser::Object *obj, int);
+ bool compileObject(QmlParser::Object *obj, const BindingContext &);
+ bool compileComponent(QmlParser::Object *obj, const BindingContext &);
+ bool compileComponentFromRoot(QmlParser::Object *obj, const BindingContext &);
+ bool compileFetchedObject(QmlParser::Object *obj, const BindingContext &);
bool compileSignal(QmlParser::Property *prop, QmlParser::Object *obj);
bool testProperty(QmlParser::Property *prop, QmlParser::Object *obj);
int signalByName(const QMetaObject *, const QByteArray &name);
- bool compileProperty(QmlParser::Property *prop, QmlParser::Object *obj, int);
+ bool compileProperty(QmlParser::Property *prop, QmlParser::Object *obj, const BindingContext &);
bool compileIdProperty(QmlParser::Property *prop,
QmlParser::Object *obj);
bool compileAttachedProperty(QmlParser::Property *prop,
- int ctxt);
+ const BindingContext &ctxt);
bool compileNestedProperty(QmlParser::Property *prop,
- int ctxt);
+ const BindingContext &ctxt);
bool compileListProperty(QmlParser::Property *prop,
QmlParser::Object *obj,
- int ctxt);
+ const BindingContext &ctxt);
bool compilePropertyAssignment(QmlParser::Property *prop,
QmlParser::Object *obj,
- int ctxt);
+ const BindingContext &ctxt);
bool compilePropertyObjectAssignment(QmlParser::Property *prop,
QmlParser::Value *value,
- int ctxt);
+ const BindingContext &ctxt);
bool compilePropertyLiteralAssignment(QmlParser::Property *prop,
QmlParser::Object *obj,
QmlParser::Value *value,
- int ctxt);
+ const BindingContext &ctxt);
bool compileStoreInstruction(QmlInstruction &instr,
const QMetaProperty &prop,
QmlParser::Value *value);
bool compileDynamicMeta(QmlParser::Object *obj);
bool compileBinding(QmlParser::Value *, QmlParser::Property *prop,
- int ctxt);
+ const BindingContext &ctxt);
void finalizeComponent(int patch);
struct BindingReference;
void finalizeBinding(const BindingReference &);
+ bool canConvert(int, QmlParser::Object *);
+
struct IdReference {
QString id;
QmlParser::Object *object;
int instructionIdx;
+ int idx;
};
struct BindingReference {
@@ -176,17 +193,18 @@ private:
QmlParser::Property *property;
QmlParser::Value *value;
int instructionIdx;
- int bindingContext;
+ BindingContext bindingContext;
};
struct ComponentCompileState
{
- ComponentCompileState() : parserStatusCount(0), savedObjects(0), pushedProperties(0) {}
+ ComponentCompileState() : parserStatusCount(0), savedObjects(0), pushedProperties(0), root(0) {}
QHash<QString, IdReference> ids;
int parserStatusCount;
int savedObjects;
int pushedProperties;
QList<BindingReference> bindings;
+ QmlParser::Object *root;
};
ComponentCompileState compileState;
diff --git a/src/declarative/qml/qmlcomponent.cpp b/src/declarative/qml/qmlcomponent.cpp
index 267fba8..f90af4a 100644
--- a/src/declarative/qml/qmlcomponent.cpp
+++ b/src/declarative/qml/qmlcomponent.cpp
@@ -59,6 +59,7 @@
QT_BEGIN_NAMESPACE
class QByteArray;
+int statusId = qRegisterMetaType<QmlComponent::Status>("QmlComponent::Status");
/*!
\class QmlComponent
diff --git a/src/declarative/qml/qmlcomponent.h b/src/declarative/qml/qmlcomponent.h
index bb76c8b..fe0c422 100644
--- a/src/declarative/qml/qmlcomponent.h
+++ b/src/declarative/qml/qmlcomponent.h
@@ -104,6 +104,7 @@ private:
friend class QmlVME;
friend struct QmlCompositeTypeData;
};
+Q_DECLARE_METATYPE(QmlComponent::Status);
QML_DECLARE_TYPE(QmlComponent)
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmldom.cpp b/src/declarative/qml/qmldom.cpp
index e06afb5..d2608c8 100644
--- a/src/declarative/qml/qmldom.cpp
+++ b/src/declarative/qml/qmldom.cpp
@@ -1449,6 +1449,16 @@ int QmlDomList::length() const
return 0;
}
+/*!
+ Returns a list of positions of the commas in the QML file.
+*/
+QList<int> QmlDomList:: commaPositions() const
+{
+ if (d && d->property)
+ return d->property->listCommaPositions;
+ else
+ return QList<int>();
+}
/*!
\class QmlDomComponent
diff --git a/src/declarative/qml/qmldom.h b/src/declarative/qml/qmldom.h
index 442a4fc..fde35a8 100644
--- a/src/declarative/qml/qmldom.h
+++ b/src/declarative/qml/qmldom.h
@@ -268,6 +268,8 @@ public:
int position() const;
int length() const;
+ QList<int> commaPositions() const;
+
private:
friend class QmlDomValue;
QSharedDataPointer<QmlDomValuePrivate> d;
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index d8ca809..2c1d324 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -219,30 +219,11 @@ QmlContext *QmlEnginePrivate::setCurrentBindContext(QmlContext *c)
return old;
}
-QmlEnginePrivate::CapturedProperty::CapturedProperty(QObject *obj, int n)
-: object(obj), notifyIndex(n)
-{
-}
-
QmlEnginePrivate::CapturedProperty::CapturedProperty(const QmlMetaProperty &p)
-: object(p.object()), name(p.name()), notifyIndex(p.property().notifySignalIndex())
+: object(p.object()), notifyIndex(p.property().notifySignalIndex())
{
}
-QmlEnginePrivate::CapturedProperty::CapturedProperty(const CapturedProperty &o)
-: object(o.object), name(o.name), notifyIndex(o.notifyIndex)
-{
-}
-
-QmlEnginePrivate::CapturedProperty &
-QmlEnginePrivate::CapturedProperty::operator=(const CapturedProperty &o)
-{
- object = o.object;
- name = o.name;
- notifyIndex = o.notifyIndex;
- return *this;
-}
-
////////////////////////////////////////////////////////////////////
typedef QHash<QPair<const QMetaObject *, QString>, bool> FunctionCache;
Q_GLOBAL_STATIC(FunctionCache, functionCache);
@@ -842,27 +823,48 @@ QScriptValue QmlEngine::qmlScriptObject(QObject* object, QmlEngine* engine)
This function takes the URL of a QML file as its only argument. It returns
a component object which can be used to create and load that QML file.
- Example JavaScript:
+ Example QmlJS is below, remember that QML files that might be loaded
+ over the network cannot be expected to be ready immediately.
\code
- component = createComponent("Sprite.qml");
- if(component.isReady()){
- sprite = component.create();
- if(sprite == 0){
+ var component;
+ var sprite;
+ function finishCreation(){
+ if(component.isReady()){
+ sprite = component.createObject();
+ if(sprite == 0){
+ // Error Handling
+ }else{
+ sprite.parent = page;
+ sprite.x = 200;
+ //...
+ }
+ }else if(component.isError()){
// Error Handling
- }else{
- sprite.parent = page;
- sprite.x = 200;
- //...
}
+ }
+
+ component = createComponent("Sprite.qml");
+ if(component.isReady()){
+ finishCreation();
}else{
- // The finishCreation function does the same thing as the above
- // if(component.isReady()) branch
component.statusChanged.connect(finishCreation);
}
\endcode
- Remember that QML files that might be loaded over the network cannot be
- expected to be ready immediately.
+ If you are certain the files will be local, you could simplify to
+
+ \code
+ component = createComponent("Sprite.qml");
+ sprite = component.createObject();
+ if(sprite == 0){
+ // Error Handling
+ }else{
+ sprite.parent = page;
+ sprite.x = 200;
+ //...
+ }
+ \endcode
+
*/
QScriptValue QmlEngine::createComponent(QScriptContext *ctxt, QScriptEngine *engine)
{
@@ -872,8 +874,8 @@ QScriptValue QmlEngine::createComponent(QScriptContext *ctxt, QScriptEngine *eng
if(ctxt->argumentCount() != 1 || !activeEngine){
c = new QmlComponent(activeEngine);
}else{
- c = new QmlComponent(activeEngine, QUrl(ctxt->argument(0).toString()),
- activeEngine);
+ QUrl url = QUrl(ctxt->argument(0).toString());
+ c = new QmlComponent(activeEngine, url, activeEngine);
}
return engine->newQObject(c);
}
@@ -897,7 +899,7 @@ QScriptValue QmlEngine::createQMLObject(QScriptContext *ctxt, QScriptEngine *eng
if(ctxt->argumentCount() < 1){
qWarning() << "createQMLObject requires a string argument.";
}else{
- qWarning() << "createQMLObject failed inexplicably.";
+ qWarning() << "createQMLObject cannot find engine.";
}
return engine->nullValue();
}
@@ -1203,8 +1205,9 @@ QVariant QmlExpression::value()
QMetaObject::connect(prop.object, prop.notifyIndex,
d->proxy, changedIndex);
} else {
- QString warn = QLatin1String("Expression depends on property without a NOTIFY signal: [") + QLatin1String(prop.object->metaObject()->className()) + QLatin1String("].") + prop.name;
- log.addWarning(warn);
+ // ### FIXME
+ //QString warn = QLatin1String("Expression depends on property without a NOTIFY signal: [") + QLatin1String(prop.object->metaObject()->className()) + QLatin1String("].") + prop.name;
+ //log.addWarning(warn);
}
}
d->addLog(log);
@@ -1284,7 +1287,7 @@ void QmlExpression::setTrackChange(bool trackChange)
Set the location of this expression to \a line of \a fileName. This information
is used by the script engine.
*/
-void QmlExpression::setSourceLocation(const QString &fileName, int line)
+void QmlExpression::setSourceLocation(const QUrl &fileName, int line)
{
d->fileName = fileName;
d->line = line;
@@ -1518,18 +1521,37 @@ void QmlContextScriptClass::setProperty(QScriptValue &object,
/////////////////////////////////////////////////////////////
/*
The QmlObjectScriptClass handles property access for QObjects
- via QtScript.
+ via QtScript. It is also used to provide a more useful API in
+ QtScript for QML.
*/
+
+QScriptValue QmlObjectDestroy(QScriptContext *context, QScriptEngine *engine)
+{
+ QObject* obj = context->thisObject().data().toQObject();
+ if(obj)
+ delete obj;
+ context->thisObject().setData(QScriptValue(engine, 0));
+ return engine->nullValue();
+}
+
QmlObjectScriptClass::QmlObjectScriptClass(QmlEngine *bindEngine)
: QmlScriptClass(bindEngine)
{
engine = bindEngine;
+ prototypeObject = engine->scriptEngine()->newObject();
+ prototypeObject.setProperty("destroy",
+ engine->scriptEngine()->newFunction(QmlObjectDestroy));
}
QmlObjectScriptClass::~QmlObjectScriptClass()
{
}
+QScriptValue QmlObjectScriptClass::prototype() const
+{
+ return prototypeObject;
+}
+
QScriptClass::QueryFlags QmlObjectScriptClass::queryProperty(const QScriptValue &object,
const QScriptString &name,
QueryFlags flags, uint *id)
diff --git a/src/declarative/qml/qmlengine.h b/src/declarative/qml/qmlengine.h
index ca66097..f114379 100644
--- a/src/declarative/qml/qmlengine.h
+++ b/src/declarative/qml/qmlengine.h
@@ -90,7 +90,6 @@ public:
static QScriptValue qmlScriptObject(QObject*, QmlEngine*);
- // Below two functions provide a way to dynamically create objects from JS
static QScriptValue createComponent(QScriptContext*, QScriptEngine*);
static QScriptValue createQMLObject(QScriptContext*, QScriptEngine*);
diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h
index 89b0a4a..a1028e6 100644
--- a/src/declarative/qml/qmlengine_p.h
+++ b/src/declarative/qml/qmlengine_p.h
@@ -52,6 +52,7 @@
#include <private/qobject_p.h>
#include <private/qmlclassfactory_p.h>
#include <private/qmlcompositetypemanager_p.h>
+#include <private/qpodvector_p.h>
#include <QtDeclarative/qml.h>
#include <private/qmlbasicscript_p.h>
#include <QtDeclarative/qmlcontext.h>
@@ -90,16 +91,14 @@ public:
QScriptValue propertyObject(const QScriptString &propName, QObject *, uint id = 0);
struct CapturedProperty {
- CapturedProperty(QObject *, int);
+ CapturedProperty(QObject *o, int n)
+ : object(o), notifyIndex(n) {}
CapturedProperty(const QmlMetaProperty &);
- CapturedProperty(const CapturedProperty &);
- CapturedProperty &operator=(const CapturedProperty &);
QObject *object;
- QString name;
int notifyIndex;
};
- QList<CapturedProperty> capturedProperties;
+ QPODVector<CapturedProperty> capturedProperties;
QmlContext *rootContext;
QmlContext *currentBindContext;
@@ -221,6 +220,9 @@ public:
QmlObjectScriptClass(QmlEngine *);
~QmlObjectScriptClass();
+ virtual QScriptValue prototype () const;
+ QScriptValue prototypeObject;
+
virtual QueryFlags queryProperty(const QScriptValue &object,
const QScriptString &name,
QueryFlags flags, uint *id);
@@ -277,7 +279,8 @@ public:
BindExpressionProxy *proxy;
QObject *me;
bool trackChange;
- QString fileName;
+
+ QUrl fileName;
int line;
quint32 id;
diff --git a/src/declarative/qml/qmlexpression.h b/src/declarative/qml/qmlexpression.h
index 651fd9c..15d026a 100644
--- a/src/declarative/qml/qmlexpression.h
+++ b/src/declarative/qml/qmlexpression.h
@@ -77,7 +77,7 @@ public:
bool trackChange() const;
void setTrackChange(bool);
- void setSourceLocation(const QString &fileName, int line);
+ void setSourceLocation(const QUrl &fileName, int line);
QObject *scopeObject() const;
diff --git a/src/declarative/qml/qmlinstruction.cpp b/src/declarative/qml/qmlinstruction.cpp
index af1489a..a618fe7 100644
--- a/src/declarative/qml/qmlinstruction.cpp
+++ b/src/declarative/qml/qmlinstruction.cpp
@@ -85,6 +85,9 @@ void QmlCompiledComponent::dump(QmlInstruction *instr, int idx)
case QmlInstruction::StoreString:
qWarning() << idx << "\t" << line << "\t" << "STORE_STRING\t\t" << instr->storeString.propertyIndex << "\t" << instr->storeString.value << "\t\t" << primitives.at(instr->storeString.value);
break;
+ case QmlInstruction::StoreUrl:
+ qWarning() << idx << "\t" << line << "\t" << "STORE_URL\t\t" << instr->storeUrl.propertyIndex << "\t" << instr->storeUrl.value << "\t\t" << primitives.at(instr->storeUrl.value);
+ break;
case QmlInstruction::StoreColor:
qWarning() << idx << "\t" << line << "\t" << "STORE_COLOR\t\t" << instr->storeColor.propertyIndex << "\t" << QString::number(instr->storeColor.value, 16);
break;
@@ -146,7 +149,7 @@ void QmlCompiledComponent::dump(QmlInstruction *instr, int idx)
qWarning() << idx << "\t" << line << "\t" << "COMPLETE\t\t" << instr->complete.castValue;
break;
case QmlInstruction::AssignObjectList:
- qWarning() << idx << "\t" << line << "\t" << "ASSIGN_OBJECT_LIST\t" << instr->assignObject.property << "\t" << instr->assignObject.castValue << "\t\t" << ((instr->assignObject.property == -1)?QByteArray("default"):datas.at(instr->assignObject.property));
+ qWarning() << idx << "\t" << line << "\t" << "ASSIGN_OBJECT_LIST\t";
break;
case QmlInstruction::FetchAttached:
qWarning() << idx << "\t" << line << "\t" << "FETCH_ATTACHED\t\t" << instr->fetchAttached.id;
diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h
index 5a1729f..0f1f697 100644
--- a/src/declarative/qml/qmlinstruction_p.h
+++ b/src/declarative/qml/qmlinstruction_p.h
@@ -76,6 +76,7 @@ public:
// StoreInteger - Store a int or uint in a core property
// StoreBool - Store a bool in a core property
// StoreString - Store a QString in a core property
+ // StoreUrl - Store a QUrl in a core property
// StoreColor - Store a QColor in a core property
// StoreDate - Store a QDate in a core property
// StoreTime - Store a QTime in a core property
@@ -88,6 +89,7 @@ public:
StoreInteger, /* storeInteger */
StoreBool, /* storeBool */
StoreString, /* storeString */
+ StoreUrl, /* storeUrl */
StoreColor, /* storeColor */
StoreDate, /* storeDate */
StoreTime, /* storeTime */
@@ -105,8 +107,6 @@ public:
StoreSignal, /* storeSignal */
- StoreObjectQmlList,
-
// XXX need to handle storing objects in variants
//
@@ -122,7 +122,9 @@ public:
BeginObject, /* begin */
CompleteObject, /* complete */
- AssignObjectList, /* assignObject */
+ StoreObjectQmlList, /* NA */
+ StoreObjectQList, /* NA */
+ AssignObjectList, /* NA */
FetchAttached, /* fetchAttached */
FetchQmlList, /* fetchQmlList */
@@ -170,10 +172,6 @@ public:
} setId;
struct {
int property;
- int castValue;
- } assignObject;
- struct {
- int property;
} assignValueSource;
struct {
int property;
@@ -217,6 +215,10 @@ public:
} storeString;
struct {
int propertyIndex;
+ int value;
+ } storeUrl;
+ struct {
+ int propertyIndex;
unsigned int value;
} storeColor;
struct {
diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp
index 4f39ebc..a152807 100644
--- a/src/declarative/qml/qmlmetaproperty.cpp
+++ b/src/declarative/qml/qmlmetaproperty.cpp
@@ -646,159 +646,179 @@ void QmlMetaPropertyPrivate::writeValueProperty(const QVariant &value)
v.convert(QVariant::Int);
}
prop.write(object, v);
- } else {
- if (!value.isValid())
+ return;
+ }
+
+ if (!value.isValid())
+ return;
+
+ int t = propertyType();
+ int vt = value.userType();
+ int category = propertyCategory();
+
+ if (vt == t) {
+
+ void *a[1];
+ a[0] = (void *)value.constData();
+ QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);
+
+ } else if (qMetaTypeId<QVariant>() == t) {
+
+ prop.write(object, value);
+
+ } else if (category == QmlMetaProperty::Object) {
+
+ QObject *o = QmlMetaType::toQObject(value);
+
+ if (!o)
return;
- int t = propertyType();
- int vt = value.type();
+ const QMetaObject *valMo = o->metaObject();
+ const QMetaObject *propMo = QmlMetaType::rawMetaObjectForType(t);
- if (vt == t ||
- value.userType() == t) {
+ while (valMo) {
+ if (valMo == propMo)
+ break;
+ valMo = valMo->superClass();
+ }
- void *a[1];
- a[0] = (void *)value.constData();
- QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);
+ if (valMo) {
- } else if (qMetaTypeId<QVariant>() == t) {
+ void *args[] = { &o, 0 };
+ QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx,
+ args);
- prop.write(object, value);
+ }
- } else if (propertyCategory() == QmlMetaProperty::Object) {
+ } else if (category == QmlMetaProperty::List) {
- QObject *o = QmlMetaType::toQObject(value);
- if (o)
- prop.write(object, QmlMetaType::fromObject(o, propertyType()));
+ int listType = QmlMetaType::listType(t);
- } else if (propertyCategory() == QmlMetaProperty::List) {
+ if (value.userType() == qMetaTypeId<QList<QObject *> >()) {
+ const QList<QObject *> &list =
+ qvariant_cast<QList<QObject *> >(value);
+ QVariant listVar = prop.read(object);
+ QmlMetaType::clear(listVar);
+ for (int ii = 0; ii < list.count(); ++ii) {
+ QVariant v = QmlMetaType::fromObject(list.at(ii), listType);
+ QmlMetaType::append(listVar, v);
+ }
- int listType = QmlMetaType::listType(t);
- if (value.userType() == qMetaTypeId<QList<QObject *> >()) {
- const QList<QObject *> &list =
- qvariant_cast<QList<QObject *> >(value);
- QVariant listVar = prop.read(object);
- QmlMetaType::clear(listVar);
- for (int ii = 0; ii < list.count(); ++ii) {
- QVariant v = QmlMetaType::fromObject(list.at(ii), listType);
- QmlMetaType::append(listVar, v);
- }
+ } else if (vt == listType ||
+ value.userType() == listType) {
+ QVariant listVar = prop.read(object);
+ QmlMetaType::clear(listVar);
+ QmlMetaType::append(listVar, value);
+ }
+ } else if (category == QmlMetaProperty::QmlList) {
+
+ // XXX - optimize!
+ QVariant list = prop.read(object);
+ QmlPrivate::ListInterface *li =
+ *(QmlPrivate::ListInterface **)list.constData();
+
+ int type = li->type();
+
+ if (QObject *obj = QmlMetaType::toQObject(value)) {
+ const QMetaObject *mo =
+ QmlMetaType::rawMetaObjectForType(type);
+
+ const QMetaObject *objMo = obj->metaObject();
+ bool found = false;
+ while(!found && objMo) {
+ if (objMo == mo)
+ found = true;
+ else
+ objMo = objMo->superClass();
+ }
- } else if (vt == listType ||
- value.userType() == listType) {
- QVariant listVar = prop.read(object);
- if (!QmlMetaType::append(listVar, value)) {
- qWarning() << "QmlMetaProperty: Unable to assign object to list";
- }
+ if (!found) {
+ qWarning() << "Unable to assign object to list";
+ return;
}
- } else if (propertyCategory() == QmlMetaProperty::QmlList) {
- // XXX - optimize!
- QVariant list = prop.read(object);
- QmlPrivate::ListInterface *li =
- *(QmlPrivate::ListInterface **)list.constData();
-
- int type = li->type();
-
- if (QObject *obj = QmlMetaType::toQObject(value)) {
- const QMetaObject *mo =
- QmlMetaType::rawMetaObjectForType(type);
-
- const QMetaObject *objMo = obj->metaObject();
- bool found = false;
- while(!found && objMo) {
- if (objMo == mo)
- found = true;
- else
- objMo = objMo->superClass();
+
+ // NOTE: This assumes a cast to QObject does not alter
+ // the object pointer
+ void *d = (void *)&obj;
+ li->append(d);
+ }
+ } else if (category == QmlMetaProperty::Normal) {
+
+ switch(t) {
+ case QVariant::Double:
+ {
+ double d;
+ bool found = true;
+ if (vt == QVariant::Int) {
+ d = value.toInt();
+ } else if (vt == QVariant::UInt) {
+ d = value.toUInt();
+ } else {
+ found = false;
}
- if (!found) {
- qWarning() << "Unable to assign object to list";
+ if (found) {
+ void *a[1];
+ a[0] = &d;
+ QMetaObject::metacall(object,
+ QMetaObject::WriteProperty,
+ coreIdx, a);
return;
}
-
- // NOTE: This assumes a cast to QObject does not alter
- // the object pointer
- void *d = (void *)&obj;
- li->append(d);
}
- } else if (propertyCategory() == QmlMetaProperty::Normal) {
-
- switch(t) {
- case QVariant::Double:
- {
- double d;
- bool found = true;
- if (vt == QVariant::Int) {
- d = value.toInt();
- } else if (vt == QVariant::UInt) {
- d = value.toUInt();
- } else {
- found = false;
- }
-
- if (found) {
- void *a[1];
- a[0] = &d;
- QMetaObject::metacall(object,
- QMetaObject::WriteProperty,
- coreIdx, a);
- return;
- }
+ break;
+
+ case QVariant::Int:
+ {
+ int i;
+ bool found = true;
+ if (vt == QVariant::Double) {
+ i = (int)value.toDouble();
+ } else if (vt == QVariant::UInt) {
+ i = (int)value.toUInt();
+ } else {
+ found = false;
}
- break;
- case QVariant::Int:
- {
- int i;
- bool found = true;
- if (vt == QVariant::Double) {
- i = (int)value.toDouble();
- } else if (vt == QVariant::UInt) {
- i = (int)value.toUInt();
- } else {
- found = false;
- }
-
- if (found) {
- void *a[1];
- a[0] = &i;
- QMetaObject::metacall(object,
- QMetaObject::WriteProperty,
- coreIdx, a);
- return;
- }
+ if (found) {
+ void *a[1];
+ a[0] = &i;
+ QMetaObject::metacall(object,
+ QMetaObject::WriteProperty,
+ coreIdx, a);
+ return;
+ }
+ }
+ break;
+
+ case QVariant::String:
+ {
+ QString s;
+ bool found = true;
+ if (vt == QVariant::ByteArray) {
+ s = QLatin1String(value.toByteArray());
+ } else {
+ found = false;
}
- break;
- case QVariant::String:
- {
- QString s;
- bool found = true;
- if (vt == QVariant::ByteArray) {
- s = QLatin1String(value.toByteArray());
- } else {
- found = false;
- }
-
- if (found) {
- void *a[1];
- a[0] = &s;
- QMetaObject::metacall(object,
- QMetaObject::WriteProperty,
- coreIdx, a);
- return;
- }
+ if (found) {
+ void *a[1];
+ a[0] = &s;
+ QMetaObject::metacall(object,
+ QMetaObject::WriteProperty,
+ coreIdx, a);
+ return;
}
- break;
+ }
+ break;
- default:
- break;
- }
- prop.write(object, value);
+ default:
+ break;
}
-
+ prop.write(object, value);
}
+
}
/*!
@@ -813,168 +833,8 @@ void QmlMetaProperty::write(const QVariant &value) const
} else if (prop.name()) {
- if (prop.isEnumType()) {
- QVariant v = value;
- if (value.type() == QVariant::Double) { //enum values come through the script engine as doubles
- double integral;
- double fractional = modf(value.toDouble(), &integral);
- if (qFuzzyCompare(fractional, (double)0.0))
- v.convert(QVariant::Int);
- }
- prop.write(object(), v);
- } else {
- if (!value.isValid())
- return;
-
- int t = propertyType();
- int vt = value.type();
-
- if (vt == t ||
- value.userType() == t) {
+ d->writeValueProperty(value);
- void *a[1];
- a[0] = (void *)value.constData();
- QMetaObject::metacall(object(), QMetaObject::WriteProperty, d->coreIdx, a);
-
- } else if (qMetaTypeId<QVariant>() == t) {
-
- prop.write(object(), value);
-
- } else if (propertyCategory() == Object) {
-
- QObject *o = QmlMetaType::toQObject(value);
- if (o)
- prop.write(object(), QmlMetaType::fromObject(o, propertyType()));
-
- } else if (propertyCategory() == List) {
-
- int listType = QmlMetaType::listType(t);
- if (value.userType() == qMetaTypeId<QList<QObject *> >()) {
- const QList<QObject *> &list =
- qvariant_cast<QList<QObject *> >(value);
- QVariant listVar = prop.read(object());
- QmlMetaType::clear(listVar);
- for (int ii = 0; ii < list.count(); ++ii) {
- QVariant v = QmlMetaType::fromObject(list.at(ii), listType);
- QmlMetaType::append(listVar, v);
- }
-
- } else if (vt == listType ||
- value.userType() == listType) {
- QVariant listVar = prop.read(object());
- if (!QmlMetaType::append(listVar, value)) {
- qWarning() << "QmlMetaProperty: Unable to assign object to list";
- }
- }
- } else if (propertyCategory() == QmlList) {
- // XXX - optimize!
- QVariant list = prop.read(object());
- QmlPrivate::ListInterface *li =
- *(QmlPrivate::ListInterface **)list.constData();
-
- int type = li->type();
-
- if (QObject *obj = QmlMetaType::toQObject(value)) {
- const QMetaObject *mo =
- QmlMetaType::rawMetaObjectForType(type);
-
- const QMetaObject *objMo = obj->metaObject();
- bool found = false;
- while(!found && objMo) {
- if (objMo == mo)
- found = true;
- else
- objMo = objMo->superClass();
- }
-
- if (!found) {
- qWarning() << "Unable to assign object to list";
- return;
- }
-
- // NOTE: This assumes a cast to QObject does not alter
- // the object pointer
- void *d = (void *)&obj;
- li->append(d);
- }
- } else if (propertyCategory() == Normal) {
-
- switch(t) {
- case QVariant::Double:
- {
- double dd;
- bool found = true;
- if (vt == QVariant::Int) {
- dd = value.toInt();
- } else if (vt == QVariant::UInt) {
- dd = value.toUInt();
- } else {
- found = false;
- }
-
- if (found) {
- void *a[1];
- a[0] = &dd;
- QMetaObject::metacall(object(),
- QMetaObject::WriteProperty,
- d->coreIdx, a);
- return;
- }
- }
- break;
-
- case QVariant::Int:
- {
- int i;
- bool found = true;
- if (vt == QVariant::Double) {
- i = (int)value.toDouble();
- } else if (vt == QVariant::UInt) {
- i = (int)value.toUInt();
- } else {
- found = false;
- }
-
- if (found) {
- void *a[1];
- a[0] = &i;
- QMetaObject::metacall(object(),
- QMetaObject::WriteProperty,
- d->coreIdx, a);
- return;
- }
- }
- break;
-
- case QVariant::String:
- {
- QString s;
- bool found = true;
- if (vt == QVariant::ByteArray) {
- s = QLatin1String(value.toByteArray());
- } else {
- found = false;
- }
-
- if (found) {
- void *a[1];
- a[0] = &s;
- QMetaObject::metacall(object(),
- QMetaObject::WriteProperty,
- d->coreIdx, a);
- return;
- }
- }
- break;
-
-
- default:
- break;
- }
- prop.write(object(), value);
- }
-
- }
}
}
diff --git a/src/declarative/qml/qmlparser.cpp b/src/declarative/qml/qmlparser.cpp
index fadfbb1..5ad4a6e 100644
--- a/src/declarative/qml/qmlparser.cpp
+++ b/src/declarative/qml/qmlparser.cpp
@@ -290,7 +290,7 @@ QmlParser::Variant::Variant(const QString &v)
{
}
-QmlParser::Variant::Variant(const QString &v, JavaScript::AST::Node *n)
+QmlParser::Variant::Variant(const QString &v, QmlJS::AST::Node *n)
: t(Script), n(n), s(v)
{
}
@@ -342,7 +342,7 @@ QString QmlParser::Variant::asScript() const
}
}
-JavaScript::AST::Node *QmlParser::Variant::asAST() const
+QmlJS::AST::Node *QmlParser::Variant::asAST() const
{
if (type() == Script)
return n;
diff --git a/src/declarative/qml/qmlparser_p.h b/src/declarative/qml/qmlparser_p.h
index 0fdd26b..a38ce69 100644
--- a/src/declarative/qml/qmlparser_p.h
+++ b/src/declarative/qml/qmlparser_p.h
@@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
-namespace JavaScript { namespace AST { class Node; } }
+namespace QmlJS { namespace AST { class Node; } }
/*
XXX
@@ -131,7 +131,7 @@ namespace QmlParser
DynamicProperty();
DynamicProperty(const DynamicProperty &);
- enum Type { Variant, Int, Bool, Real, String, Color, Date };
+ enum Type { Variant, Int, Bool, Real, String, Url, Color, Date };
bool isDefaultProperty;
Type type;
@@ -178,7 +178,7 @@ namespace QmlParser
Variant(bool);
Variant(double, const QString &asWritten=QString());
Variant(const QString &);
- Variant(const QString &, JavaScript::AST::Node *);
+ Variant(const QString &, QmlJS::AST::Node *);
Variant &operator=(const Variant &);
Type type() const;
@@ -192,14 +192,14 @@ namespace QmlParser
QString asString() const;
double asNumber() const;
QString asScript() const;
- JavaScript::AST::Node *asAST() const;
+ QmlJS::AST::Node *asAST() const;
private:
Type t;
union {
bool b;
double d;
- JavaScript::AST::Node *n;
+ QmlJS::AST::Node *n;
};
QString s;
};
@@ -277,6 +277,7 @@ namespace QmlParser
LocationSpan location;
LocationRange listValueRange;
+ QList<int> listCommaPositions;
void dump(int = 0) const;
};
diff --git a/src/declarative/qml/qmlproxymetaobject.cpp b/src/declarative/qml/qmlproxymetaobject.cpp
index d24c5c4..686c6d7 100644
--- a/src/declarative/qml/qmlproxymetaobject.cpp
+++ b/src/declarative/qml/qmlproxymetaobject.cpp
@@ -50,7 +50,7 @@ QmlProxyMetaObject::QmlProxyMetaObject(QObject *obj, QList<ProxyData> *mList)
qWarning() << "QmlProxyMetaObject" << obj->metaObject()->className();
#endif
- *static_cast<QMetaObject *>(this) = *metaObjects->last().metaObject;
+ *static_cast<QMetaObject *>(this) = *metaObjects->first().metaObject;
QObjectPrivate *op = QObjectPrivate::get(obj);
if (op->metaObject)
diff --git a/src/declarative/qml/qmlscriptparser.cpp b/src/declarative/qml/qmlscriptparser.cpp
index 5207292..6c2e3e0 100644
--- a/src/declarative/qml/qmlscriptparser.cpp
+++ b/src/declarative/qml/qmlscriptparser.cpp
@@ -42,12 +42,12 @@
#include "qmlscriptparser_p.h"
#include "qmlparser_p.h"
-#include "parser/javascriptengine_p.h"
-#include "parser/javascriptparser_p.h"
-#include "parser/javascriptlexer_p.h"
-#include "parser/javascriptnodepool_p.h"
-#include "parser/javascriptastvisitor_p.h"
-#include "parser/javascriptast_p.h"
+#include "parser/qmljsengine_p.h"
+#include "parser/qmljsparser_p.h"
+#include "parser/qmljslexer_p.h"
+#include "parser/qmljsnodepool_p.h"
+#include "parser/qmljsastvisitor_p.h"
+#include "parser/qmljsast_p.h"
#include "rewriter/textwriter_p.h"
@@ -59,7 +59,7 @@
QT_BEGIN_NAMESPACE
-using namespace JavaScript;
+using namespace QmlJS;
using namespace QmlParser;
namespace {
@@ -501,6 +501,7 @@ bool ProcessAST::visit(AST::UiPublicMember *node)
{ "double", Object::DynamicProperty::Real },
{ "real", Object::DynamicProperty::Real },
{ "string", Object::DynamicProperty::String },
+ { "url", Object::DynamicProperty::Url },
{ "color", Object::DynamicProperty::Color },
{ "date", Object::DynamicProperty::Date },
{ "var", Object::DynamicProperty::Variant },
@@ -648,7 +649,20 @@ bool ProcessAST::visit(AST::ExpressionStatement *node)
return true;
}
-// UiObjectMember: UiQualifiedId T_COLON T_LBRACKET UiObjectMemberList T_RBRACKET ;
+static QList<int> collectCommas(AST::UiArrayMemberList *members)
+{
+ QList<int> commas;
+
+ if (members) {
+ for (AST::UiArrayMemberList *it = members->next; it; it = it->next) {
+ commas.append(it->commaToken.offset);
+ }
+ }
+
+ return commas;
+}
+
+// UiObjectMember: UiQualifiedId T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET ;
bool ProcessAST::visit(AST::UiArrayBinding *node)
{
int propertyCount = 0;
@@ -666,6 +680,9 @@ bool ProcessAST::visit(AST::UiArrayBinding *node)
prop->listValueRange.offset = node->lbracketToken.offset;
prop->listValueRange.length = node->rbracketToken.offset + node->rbracketToken.length - node->lbracketToken.offset;
+ // Store the positions of the comma token too, again for the DOM to be able to retreive it.
+ prop->listCommaPositions = collectCommas(node->members);
+
while (propertyCount--)
_stateStack.pop();
@@ -698,7 +715,7 @@ bool ProcessAST::visit(AST::UiSourceElement *node)
obj->dynamicSlots << slot;
} else {
QmlError error;
- error.setDescription(QCoreApplication::translate("QmlParser","JavaScript declaration outside Script element"));
+ error.setDescription(QCoreApplication::translate("QmlParser","QmlJS declaration outside Script element"));
error.setLine(node->firstSourceLocation().startLine);
error.setColumn(node->firstSourceLocation().startColumn);
_parser->_errors << error;
diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp
index f00d282..3a66c69 100644
--- a/src/declarative/qml/qmlvme.cpp
+++ b/src/declarative/qml/qmlvme.cpp
@@ -66,89 +66,6 @@
#include <private/qmlbindablevalue_p.h>
QT_BEGIN_NAMESPACE
-Q_DECLARE_PERFORMANCE_LOG(QFxCompiler) {
- Q_DECLARE_PERFORMANCE_METRIC(InstrCreateObject);
- Q_DECLARE_PERFORMANCE_METRIC(InstrCreateCustomObject);
- Q_DECLARE_PERFORMANCE_METRIC(InstrSetId);
- Q_DECLARE_PERFORMANCE_METRIC(InstrSetDefault);
- Q_DECLARE_PERFORMANCE_METRIC(InstrCreateComponent);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreMetaObject);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreReal);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreInteger);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreBool);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreString);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreColor);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreDate);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreDateTime);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreTime);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStorePoint);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreSize);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreVariant);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreObject);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreSignal);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreObjectQmlList);
- Q_DECLARE_PERFORMANCE_METRIC(InstrAssignSignalObject);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreBinding);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreCompiledBinding);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreValueSource);
- Q_DECLARE_PERFORMANCE_METRIC(InstrBeginObject);
- Q_DECLARE_PERFORMANCE_METRIC(InstrCompleteObject);
- Q_DECLARE_PERFORMANCE_METRIC(InstrAssignObjectList);
- Q_DECLARE_PERFORMANCE_METRIC(InstrFetchAttached);
- Q_DECLARE_PERFORMANCE_METRIC(InstrFetchQmlList);
- Q_DECLARE_PERFORMANCE_METRIC(InstrFetchQList);
- Q_DECLARE_PERFORMANCE_METRIC(InstrFetchObject);
- Q_DECLARE_PERFORMANCE_METRIC(InstrPopFetchedObject);
- Q_DECLARE_PERFORMANCE_METRIC(InstrPopQList);
- Q_DECLARE_PERFORMANCE_METRIC(InstrPushProperty);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreStackObject);
- Q_DECLARE_PERFORMANCE_METRIC(Dummy);
-}
-
-Q_DEFINE_PERFORMANCE_LOG(QFxCompiler, "QFxCompiler") {
- Q_DEFINE_PERFORMANCE_METRIC(InstrCreateObject, "CreateObject");
- Q_DEFINE_PERFORMANCE_METRIC(InstrCreateCustomObject, "CreateCustomObject");
- Q_DEFINE_PERFORMANCE_METRIC(InstrSetId, "SetId");
- Q_DEFINE_PERFORMANCE_METRIC(InstrSetDefault, "SetDefault");
- Q_DEFINE_PERFORMANCE_METRIC(InstrCreateComponent, "CreateComponent");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreMetaObject, "StoreMetaObject");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreReal, "StoreReal");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreInteger, "StoreInteger");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreBool, "StoreBool");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreString, "StoreString");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreColor, "StoreColor");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreDate, "StoreDate");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreDateTime, "StoreDateTime");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreTime, "StoreTime");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStorePoint, "StorePoint(F)");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreSize, "StoreSize(F)");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreVariant, "StoreVariant");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreObject, "StoreObject");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreSignal, "StoreSignal");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreObjectQmlList, "StoreObjectQmlList");
- Q_DEFINE_PERFORMANCE_METRIC(InstrAssignSignalObject, "AssignSignalObject");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreBinding, "StoreBinding");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreCompiledBinding, "StoreCompiledBinding");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreValueSource, "StoreValueSource");
- Q_DEFINE_PERFORMANCE_METRIC(InstrBeginObject, "BeginObject");
- Q_DEFINE_PERFORMANCE_METRIC(InstrCompleteObject, "CompleteObject");
- Q_DEFINE_PERFORMANCE_METRIC(InstrAssignObjectList, "AssignObjectList");
- Q_DEFINE_PERFORMANCE_METRIC(InstrFetchAttached, "FetchAttached");
- Q_DEFINE_PERFORMANCE_METRIC(InstrFetchQmlList, "FetchQmlList");
- Q_DEFINE_PERFORMANCE_METRIC(InstrFetchQList, "FetchQList");
- Q_DEFINE_PERFORMANCE_METRIC(InstrFetchObject, "FetchObject");
- Q_DEFINE_PERFORMANCE_METRIC(InstrPopFetchedObject, "PopFetchedObject");
- Q_DEFINE_PERFORMANCE_METRIC(InstrPopQList, "PopQList");
- Q_DEFINE_PERFORMANCE_METRIC(InstrPushProperty, "PushProperty");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreStackObject, "StoreStackObject");
- Q_DEFINE_PERFORMANCE_METRIC(Dummy, "Dummy");
-}
-
-static inline int qIndexOfProperty(QObject *o, const char *name)
-{
- int idx = o->metaObject()->indexOfProperty(name);
- return idx;
-}
QmlVME::QmlVME()
{
@@ -171,13 +88,18 @@ QmlVME::QmlVME()
struct ListInstance
{
ListInstance() {}
+ /*
ListInstance(const QVariant &l, int t)
: list(l), type(t), qmlListInterface(0) {}
+ */
+ ListInstance(QList<void *> *q, int t)
+ : type(t), qListInterface(q) {}
ListInstance(QmlPrivate::ListInterface *q, int t)
: type(t), qmlListInterface(q) {}
- QVariant list;
+ //QVariant list;
int type;
+ QList<void *> *qListInterface;
QmlPrivate::ListInterface *qmlListInterface;
};
@@ -200,9 +122,6 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
const QList<float> &floatData = comp->floatData;
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxPerfTimer<QFxPerf::VMEExecution> cr;
-#endif
QmlEnginePrivate::SimpleList<QmlBindableValue> bindValues;
QmlEnginePrivate::SimpleList<QmlParserStatus> parserStatus;
@@ -238,9 +157,6 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
case QmlInstruction::CreateObject:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrCreateObject> cc;
-#endif
QObject *o = types.at(instr.create.type).createInstance(QmlContext::activeContext());
if (!o) {
if(types.at(instr.create.type).component)
@@ -264,9 +180,6 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
case QmlInstruction::SetId:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrSetId> cc;
-#endif
QObject *target = stack.top();
QmlContext *ctxt =
QmlContext::activeContext();
@@ -280,9 +193,6 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
case QmlInstruction::SetDefault:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrSetDefault> cc;
-#endif
QObject *target = stack.top();
QmlContext::activeContext()->addDefaultObject(target);
}
@@ -290,9 +200,6 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
case QmlInstruction::CreateComponent:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrCreateComponent> cc;
-#endif
QObject *qcomp = new QmlComponent(ctxt->engine(), comp, ii + 1, instr.createComponent.count, stack.isEmpty() ? 0 : stack.top());
stack.push(qcomp);
ii += instr.createComponent.count;
@@ -301,9 +208,6 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
case QmlInstruction::StoreMetaObject:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreMetaObject> cc;
-#endif
QObject *target = stack.top();
new QmlVMEMetaObject(target, synthesizedMetaObjects.at(instr.storeMeta.data), &comp->primitives, instr.storeMeta.slotData, comp);
}
@@ -311,9 +215,6 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
case QmlInstruction::StoreVariant:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreVariant> cc;
-#endif
QObject *target = stack.top();
void *a[1];
// XXX - can be more efficient
@@ -326,9 +227,6 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
case QmlInstruction::StoreString:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreString> cc;
-#endif
QObject *target = stack.top();
void *a[1];
a[0] = (void *)&primitives.at(instr.storeString.value);
@@ -337,11 +235,19 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
}
break;
+ case QmlInstruction::StoreUrl:
+ {
+ QObject *target = stack.top();
+ void *a[1];
+ QUrl u(primitives.at(instr.storeUrl.value));
+ a[0] = (void *)&u;
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.storeUrl.propertyIndex, a);
+ }
+ break;
+
case QmlInstruction::StoreFloat:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreReal> cc;
-#endif
QObject *target = stack.top();
float f = instr.storeFloat.value;
void *a[1];
@@ -351,11 +257,8 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
}
break;
-case QmlInstruction::StoreDouble:
+ case QmlInstruction::StoreDouble:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreReal> cc;
-#endif
QObject *target = stack.top();
double d = instr.storeDouble.value;
void *a[1];
@@ -367,9 +270,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreBool:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreBool> cc;
-#endif
QObject *target = stack.top();
void *a[1];
a[0] = (void *)&instr.storeBool.value;
@@ -380,9 +280,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreInteger:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreInteger> cc;
-#endif
QObject *target = stack.top();
void *a[1];
a[0] = (void *)&instr.storeInteger.value;
@@ -393,9 +290,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreColor:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreColor> cc;
-#endif
QObject *target = stack.top();
void *a[1];
QColor c = QColor::fromRgba(instr.storeColor.value);
@@ -407,9 +301,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreDate:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreDate> cc;
-#endif
QObject *target = stack.top();
void *a[1];
QDate d = QDate::fromJulianDay(instr.storeDate.value);
@@ -421,9 +312,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreTime:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- //QFxCompilerTimer<QFxCompiler::InstrStoreTime> cc;
-#endif
QObject *target = stack.top();
void *a[1];
QTime t;
@@ -439,9 +327,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreDateTime:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- //QFxCompilerTimer<QFxCompiler::InstrStoreDateTime> cc;
-#endif
QObject *target = stack.top();
void *a[1];
QTime t;
@@ -458,9 +343,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StorePoint:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStorePoint> cc;
-#endif
QObject *target = stack.top();
void *a[1];
QPoint p = QPointF(floatData.at(instr.storeRealPair.valueIndex),
@@ -473,9 +355,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StorePointF:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStorePoint> cc;
-#endif
QObject *target = stack.top();
void *a[1];
QPointF p(floatData.at(instr.storeRealPair.valueIndex),
@@ -488,9 +367,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreSize:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreSize> cc;
-#endif
QObject *target = stack.top();
void *a[1];
QSize p = QSizeF(floatData.at(instr.storeRealPair.valueIndex),
@@ -503,9 +379,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreSizeF:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreSize> cc;
-#endif
QObject *target = stack.top();
void *a[1];
QSizeF s(floatData.at(instr.storeRealPair.valueIndex),
@@ -518,9 +391,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreRect:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- //QFxCompilerTimer<QFxCompiler::InstrStoreRect> cc;
-#endif
QObject *target = stack.top();
void *a[1];
QRect r = QRectF(floatData.at(instr.storeRect.valueIndex),
@@ -535,9 +405,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreRectF:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- //QFxCompilerTimer<QFxCompiler::InstrStoreRect> cc;
-#endif
QObject *target = stack.top();
void *a[1];
QRectF r(floatData.at(instr.storeRect.valueIndex),
@@ -552,9 +419,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreObject:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreObject> cc;
-#endif
QObject *assignObj = stack.pop();
QObject *target = stack.top();
@@ -590,9 +454,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::AssignSignalObject:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrAssignSignalObject> cc;
-#endif
// XXX optimize
QObject *assign = stack.pop();
@@ -622,9 +483,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreSignal:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreSignal> cc;
-#endif
QObject *target = stack.top();
// XXX scope
QMetaMethod signal =
@@ -640,9 +498,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::BeginObject:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrBeginObject> cc;
-#endif
QObject *target = stack.top();
QmlParserStatus *status = reinterpret_cast<QmlParserStatus *>(reinterpret_cast<char *>(target) + instr.begin.castValue);
parserStatus.append(status);
@@ -654,9 +509,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::CompleteObject:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrCompleteObject> cc;
-#endif
QObject *target = stack.top();
QmlParserStatus *status = reinterpret_cast<QmlParserStatus *>(reinterpret_cast<char *>(target) + instr.complete.castValue);
status->classComplete();
@@ -665,9 +517,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::PushProperty:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrPushProperty> cc;
-#endif
QObject *target = stack.top();
QmlMetaProperty mp(target, instr.pushProperty.property,
QmlMetaProperty::Object);
@@ -677,9 +526,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreCompiledBinding:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreCompiledBinding> cc;
-#endif
QObject *target = stack.top();
QObject *context =
stack.at(stack.count() - 1 - instr.assignBinding.context);
@@ -695,15 +541,11 @@ case QmlInstruction::StoreDouble:
QFx_setParent_noEvent(bind, target);
bind->setTarget(mp);
- bind->setSourceLocation(comp->url.toString(), instr.line);
}
break;
case QmlInstruction::StoreBinding:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreBinding> cc;
-#endif
QObject *target = stack.top();
QObject *context =
stack.at(stack.count() - 1 - instr.assignBinding.context);
@@ -719,15 +561,12 @@ case QmlInstruction::StoreDouble:
QFx_setParent_noEvent(bind, target);
bind->setTarget(mp);
- bind->setSourceLocation(comp->url.toString(), instr.line);
+ bind->setSourceLocation(comp->url, instr.line);
}
break;
case QmlInstruction::StoreValueSource:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreValueSource> cc;
-#endif
QObject *assign = stack.pop();
QmlPropertyValueSource *vs =
static_cast<QmlPropertyValueSource *>(assign);
@@ -737,65 +576,47 @@ case QmlInstruction::StoreDouble:
}
break;
+ case QmlInstruction::StoreObjectQmlList:
+ {
+ QObject *assign = stack.pop();
+ const ListInstance &list = qliststack.top();
+
+ void *d = (void *)&assign;
+ list.qmlListInterface->append(d);
+ }
+ break;
+
+ case QmlInstruction::StoreObjectQList:
+ {
+ QObject *assign = stack.pop();
+
+ const ListInstance &list = qliststack.top();
+ list.qListInterface->append((void *)assign);
+ }
+ break;
+
case QmlInstruction::AssignObjectList:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrAssignObjectList> cc;
-#endif
+ // This is only used for assigning interfaces
QObject *assign = stack.pop();
const ListInstance &list = qliststack.top();
- if (list.qmlListInterface) {
- int type = list.type;
-
- void *d = 0;
- void *ptr = 0;
- bool found = false;
-
- if (QmlMetaType::isInterface(type)) {
- const char *iid = QmlMetaType::interfaceIId(type);
- if (iid)
- ptr = assign->qt_metacast(iid);
- if (ptr) {
- d = &ptr;
- found = true;
- }
- } else {
- const QMetaObject *mo =
- QmlMetaType::rawMetaObjectForType(type);
-
- const QMetaObject *assignMo = assign->metaObject();
- while(!found && assignMo) {
- if (assignMo == mo)
- found = true;
- else
- assignMo = assignMo->superClass();
- }
-
- // NOTE: This assumes a cast to QObject does not alter
- // the object pointer
- d = (void *)&assign;
- }
+ int type = list.type;
- if (!found)
- VME_EXCEPTION("Cannot assign object to list");
+ void *ptr = 0;
+
+ const char *iid = QmlMetaType::interfaceIId(type);
+ if (iid)
+ ptr = assign->qt_metacast(iid);
+ if (!ptr)
+ VME_EXCEPTION("Cannot assign object to list");
- list.qmlListInterface->append(d);
+ if (list.qmlListInterface) {
+ void *d = (void *)&ptr;
+ list.qmlListInterface->append(d);
} else {
- int type = list.type;
-
- if (QmlMetaType::isInterface(type)) {
- void *ptr = 0;
- const char *iid = QmlMetaType::interfaceIId(type);
- if (iid)
- ptr = assign->qt_metacast(iid);
- QVariant v(list.type, &ptr);
- QmlMetaType::append(list.list, v);
- } else {
- QVariant v = QmlMetaType::fromObject(assign, list.type);
- QmlMetaType::append(list.list, v);
- }
+ list.qListInterface->append(ptr);
}
}
break;
@@ -842,9 +663,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::FetchAttached:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrFetchAttached> cc;
-#endif
QObject *target = stack.top();
QObject *qmlObject = qmlAttachedPropertiesObjectById(instr.fetchAttached.id, target);
@@ -858,9 +676,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::FetchQmlList:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrFetchQmlList> cc;
-#endif
QObject *target = stack.top();
void *a[1];
@@ -879,22 +694,24 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::FetchQList:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrFetchQList> cc;
-#endif
QObject *target = stack.top();
- QMetaProperty prop =
- target->metaObject()->property(instr.fetch.property);
- QVariant v = prop.read(target);
- qliststack.push(ListInstance(v, QmlMetaType::listType(prop.userType())));
+
+ void *a[1];
+ // We know that QList<T *>* can be converted to
+ // QList<void *>*
+ QList<void *> *list = 0;
+ a[0] = &list;
+ QMetaObject::metacall(target, QMetaObject::ReadProperty,
+ instr.fetchQmlList.property, a);
+ if (!list)
+ VME_EXCEPTION("Cannot assign to null list");
+
+ qliststack.push(ListInstance(list, instr.fetchQmlList.type));
}
break;
case QmlInstruction::FetchObject:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrFetchObject> cc;
-#endif
QObject *target = stack.top();
QObject *obj = 0;
@@ -924,28 +741,18 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::PopQList:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrPopQList> cc;
-#endif
qliststack.pop();
}
break;
case QmlInstruction::PopFetchedObject:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrPopFetchedObject> cc;
-#endif
stack.pop();
}
break;
case QmlInstruction::StoreStackObject:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreStackObject> cc;
-#endif
-
const QmlMetaProperty &prop =
pushedProperties.at(instr.assignStackObject.property);
QObject *obj = savedObjects[instr.assignStackObject.object];
diff --git a/src/declarative/qml/qmlvmemetaobject.cpp b/src/declarative/qml/qmlvmemetaobject.cpp
index 58708cf..0117448 100644
--- a/src/declarative/qml/qmlvmemetaobject.cpp
+++ b/src/declarative/qml/qmlvmemetaobject.cpp
@@ -134,6 +134,9 @@ int QmlVMEMetaObject::metaCall(QMetaObject::Call c, int id, void **a)
case QVariant::String:
*reinterpret_cast<QString *>(a[0]) = data[propId].toString();
break;
+ case QVariant::Url:
+ *reinterpret_cast<QUrl *>(a[0]) = data[propId].toUrl();
+ break;
case QVariant::Color:
*reinterpret_cast<QColor *>(a[0]) = data[propId].value<QColor>();
break;
diff --git a/src/declarative/qml/qpodvector_p.h b/src/declarative/qml/qpodvector_p.h
new file mode 100644
index 0000000..55c04e7
--- /dev/null
+++ b/src/declarative/qml/qpodvector_p.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPODVECTOR_P_H
+#define QPODVECTOR_P_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+template<class T>
+class QPODVector
+{
+public:
+ QPODVector()
+ : m_count(0), m_capacity(0), m_data(0) {}
+
+ const T &at(int idx) {
+ return m_data[idx];
+ }
+
+ T &operator[](int idx) {
+ return m_data[idx];
+ }
+
+ void clear() {
+ m_count = 0;
+ }
+
+ void prepend(const T &v) {
+ insert(0, v);
+ }
+
+ void append(const T &v) {
+ insert(m_count, v);
+ }
+
+ void insert(int idx, const T &v) {
+ if (m_count == m_capacity) {
+ m_capacity += 1024;
+ m_data = (T *)realloc(m_data, m_capacity * sizeof(T));
+ }
+ int moveCount = m_count - idx;
+ if (moveCount)
+ ::memmove(m_data + idx + 1, m_data + idx, moveCount * sizeof(T));
+ m_count++;
+ m_data[idx] = v;
+ }
+
+ void insertBlank(int idx, int count) {
+ int newSize = m_count + count;
+ if (newSize >= m_capacity) {
+ m_capacity = (newSize + 1023) & 0xFFFFFC00;
+ m_data = (T *)realloc(m_data, m_capacity * sizeof(T));
+ }
+
+ int moveCount = m_count - idx;
+ if (moveCount)
+ ::memmove(m_data + idx + count, m_data + idx,
+ moveCount * sizeof(T));
+ m_count = newSize;
+ }
+
+ void remove(int idx, int count = 1) {
+ int moveCount = m_count - (idx + count);
+ if (moveCount)
+ ::memmove(m_data + idx, m_data + idx + count,
+ moveCount * sizeof(T));
+ m_count -= count;
+ }
+
+ int count() const {
+ return m_count;
+ }
+
+ QPODVector<T> &operator<<(const T &v) { append(v); return *this; }
+private:
+ QPODVector(const QPODVector &);
+ QPODVector &operator=(const QPODVector &);
+ int m_count;
+ int m_capacity;
+ T *m_data;
+};
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/declarative/qml/rewriter/rewriter.cpp b/src/declarative/qml/rewriter/rewriter.cpp
index fce4fdf..2ce927c 100644
--- a/src/declarative/qml/rewriter/rewriter.cpp
+++ b/src/declarative/qml/rewriter/rewriter.cpp
@@ -40,11 +40,11 @@
****************************************************************************/
#include "rewriter_p.h"
-#include "javascriptast_p.h"
+#include "qmljsast_p.h"
QT_BEGIN_NAMESPACE
-using namespace JavaScript;
+using namespace QmlJS;
void Rewriter::replace(const AST::SourceLocation &loc, const QString &text)
{ replace(loc.offset, loc.length, text); }
@@ -76,8 +76,8 @@ QString Rewriter::textAt(const AST::SourceLocation &loc) const
QString Rewriter::textAt(const AST::SourceLocation &firstLoc, const AST::SourceLocation &lastLoc) const
{ return _code.mid(firstLoc.offset, lastLoc.offset + lastLoc.length - firstLoc.offset); }
-void Rewriter::accept(JavaScript::AST::Node *node)
-{ JavaScript::AST::Node::acceptChild(node, this); }
+void Rewriter::accept(QmlJS::AST::Node *node)
+{ QmlJS::AST::Node::acceptChild(node, this); }
void Rewriter::moveTextBefore(const AST::SourceLocation &firstLoc,
const AST::SourceLocation &lastLoc,
diff --git a/src/declarative/qml/rewriter/rewriter_p.h b/src/declarative/qml/rewriter/rewriter_p.h
index 02b4ee4..fcb9ca5 100644
--- a/src/declarative/qml/rewriter/rewriter_p.h
+++ b/src/declarative/qml/rewriter/rewriter_p.h
@@ -46,12 +46,12 @@
#include <QtCore/QString>
#include "textwriter_p.h"
-#include "javascriptastvisitor_p.h"
+#include "qmljsastvisitor_p.h"
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-namespace JavaScript {
+namespace QmlJS {
////////////////////////////////////////////////////////////////////////////////
// Replacement
@@ -143,7 +143,7 @@ private:
QList<Replacement> _replacementList;
};
-} // end of namespace JavaScript
+} // end of namespace QmlJS
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/declarative/qml/rewriter/textwriter.cpp b/src/declarative/qml/rewriter/textwriter.cpp
index 21122ff..fbbdb2bbab 100644
--- a/src/declarative/qml/rewriter/textwriter.cpp
+++ b/src/declarative/qml/rewriter/textwriter.cpp
@@ -43,7 +43,7 @@
QT_BEGIN_NAMESPACE
-using namespace JavaScript;
+using namespace QmlJS;
TextWriter::TextWriter()
:string(0), cursor(0)
diff --git a/src/declarative/qml/rewriter/textwriter_p.h b/src/declarative/qml/rewriter/textwriter_p.h
index 57800bf..3041e04 100644
--- a/src/declarative/qml/rewriter/textwriter_p.h
+++ b/src/declarative/qml/rewriter/textwriter_p.h
@@ -49,7 +49,7 @@
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-namespace JavaScript {
+namespace QmlJS {
class TextWriter
{
@@ -91,7 +91,7 @@ public:
};
-} // end of namespace JavaScript
+} // end of namespace QmlJS
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/declarative/util/qfxview.cpp b/src/declarative/util/qfxview.cpp
index 0d5b796..d8d9ba1 100644
--- a/src/declarative/util/qfxview.cpp
+++ b/src/declarative/util/qfxview.cpp
@@ -84,11 +84,6 @@ static QVariant stringToKeySequence(const QString &str)
return QVariant::fromValue(QKeySequence(str));
}
-static QVariant stringToUrl(const QString &str)
-{
- return QVariant(QUrl(str));
-}
-
class QFxViewPrivate
{
public:
@@ -166,7 +161,6 @@ void QFxViewPrivate::init()
QmlMetaType::registerCustomStringConverter(QVariant::Pixmap, &stringToPixmap);
QmlMetaType::registerCustomStringConverter(QVariant::Icon, &stringToIcon);
QmlMetaType::registerCustomStringConverter(QVariant::KeySequence, &stringToKeySequence);
- QmlMetaType::registerCustomStringConverter(QVariant::Url, &stringToUrl);
#ifdef Q_ENABLE_PERFORMANCE_LOG
QFxPerfTimer<QFxPerf::FontDatabase> perf;
diff --git a/src/declarative/util/qmlscript.cpp b/src/declarative/util/qmlscript.cpp
index 45370e2..e422f37 100644
--- a/src/declarative/util/qmlscript.cpp
+++ b/src/declarative/util/qmlscript.cpp
@@ -69,7 +69,6 @@ public:
void addScriptToEngine(const QString &, const QString &fileName=QString());
QString script;
- QString source;
QNetworkReply *reply;
QUrl url;
};
@@ -138,26 +137,26 @@ void QmlScript::setScript(const QString &script)
\property QmlScript::source
\brief the path to a script file.
*/
-QString QmlScript::source() const
+QUrl QmlScript::source() const
{
Q_D(const QmlScript);
- return d->source;
+ return d->url;
}
-void QmlScript::setSource(const QString &source)
+void QmlScript::setSource(const QUrl &source)
{
Q_D(QmlScript);
- if (d->source == source)
+ if (d->url == source)
return;
- d->source = source;
- d->url = qmlContext(this)->resolvedUrl(source);
+ d->url = source;
+ Q_ASSERT(!source.isRelative());
#ifndef QT_NO_LOCALFILE_OPTIMIZED_QML
if (d->url.scheme() == QLatin1String("file")) {
QFile file(d->url.toLocalFile());
file.open(QIODevice::ReadOnly);
QByteArray ba = file.readAll();
- d->addScriptToEngine(QString::fromUtf8(ba), d->source);
+ d->addScriptToEngine(QString::fromUtf8(ba), d->url);
} else
#endif
{
@@ -174,7 +173,7 @@ void QmlScript::replyFinished()
Q_D(QmlScript);
if (!d->reply->error()) {
QByteArray ba = d->reply->readAll();
- d->addScriptToEngine(QString::fromUtf8(ba), d->source);
+ d->addScriptToEngine(QString::fromUtf8(ba), d->url);
}
d->reply->deleteLater();
d->reply = 0;
diff --git a/src/declarative/util/qmlscript.h b/src/declarative/util/qmlscript.h
index dc090bc..09ebc2c 100644
--- a/src/declarative/util/qmlscript.h
+++ b/src/declarative/util/qmlscript.h
@@ -58,7 +58,7 @@ class Q_DECLARATIVE_EXPORT QmlScript : public QObject
Q_DECLARE_PRIVATE(QmlScript)
Q_PROPERTY(QString script READ script WRITE setScript)
- Q_PROPERTY(QString source READ source WRITE setSource)
+ Q_PROPERTY(QUrl source READ source WRITE setSource)
Q_CLASSINFO("DefaultProperty", "script")
public:
@@ -67,8 +67,8 @@ public:
QString script() const;
void setScript(const QString &);
- QString source() const;
- void setSource(const QString &);
+ QUrl source() const;
+ void setSource(const QUrl &);
private Q_SLOTS:
void replyFinished();
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index b9e462b..f50d210 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -133,12 +133,8 @@
\section1 Transformation
QGraphicsItem supports affine transformations in addition to its base
- position, pos(). To change the item's transformation, you can either pass
- a transformation matrix to setTransform(), or set the different transformation
- properties (transformOrigin, x/y/zRotation, x/yScale, horizontal/verticalShear).
- Note that setting the transformation matrix conflicts with using the properties.
- Setting the properties will overwrite the transformation set with setTransform,
- and using setTransform will reset the properties.
+ position, pos(). To change the item's transformation, you can pass
+ a transformation matrix to setTransform()
Item transformations accumulate from parent to child, so if both a parent and child
item are rotated 90 degrees, the child's total transformation will be 180 degrees.
@@ -152,19 +148,18 @@
and scenePos(), which returns its position in scene coordinates. To reset
an item's matrix, call resetTransform().
+ Another way to apply transformation to an item is to use the , or set the
+ different transformation properties (transformOrigin, x/y/zRotation, x/yScale,
+ horizontal/verticalShear). Those properties come in addition to the base transformation
+
The order you set the transformation properties does not affect the resulting transformation
The resulting transformation is always computed in the following order
\code
- [Origin] [RotateX] [RotateY] [RotateZ] [Shear] [Scale] [-Origin]
+ [Origin] [Base] [RotateX] [RotateY] [RotateZ] [Shear] [Scale] [-Origin]
\endcode
- So the transformation is equivalent to the following code
-
- \code
- QTransform().translate(xOrigin, yOrigin).rotate(xRotation, Qt::XAxis).rotate(yRotation, Qt::YAxis).rotate(zRotation, Qt::ZAxis)
- .shear(horizontalShear, verticalShear).scale(xScale, yScale).translate(-xOrigin, -yOrigin);
- \endcode
+ Where [Base] is the stransformation set by setTransform
\section1 Painting
@@ -309,6 +304,18 @@
and is always initialized to 1.
Use QStyleOptionGraphicsItem::levelOfDetailFromTransform for a more
fine-grained value.
+
+ \value ItemHasNoContents The item does not paint anything (i.e., calling
+ paint() on the item has no effect). You should set this flag on items that
+ do not need to be painted to ensure that Graphics View avoids unnecessary
+ painting preparations. This flag was introduced in Qt 4.6.
+
+ \value ItemSendsGeometryChanges The item enables itemChange()
+ notifications for ItemPositionChange, ItemPositionHasChanged,
+ ItemMatrixChange, ItemTransformChange, and ItemTransformHasChanged. For
+ performance reasons, these notifications are disabled by default. You must
+ enable this flag to receive notifications for position and transform
+ changes. This flag was introduced in Qt 4.6.
*/
/*!
@@ -347,33 +354,36 @@
changing. This value is obsolete; you can use ItemTransformChange instead.
\value ItemPositionChange The item's position changes. This notification
- is only sent when the item's local position changes, relative to its
- parent, has changed (i.e., as a result of calling setPos() or
- moveBy()). The value argument is the new position (i.e., a QPointF). You
- can call pos() to get the original position. Do not call setPos() or
- moveBy() in itemChange() as this notification is delivered; instead, you
- can return the new, adjusted position from itemChange(). After this
- notification, QGraphicsItem immediately sends the ItemPositionHasChanged
- notification if the position changed.
+ is sent if the ItemSendsGeometryChanges flag is enabled, and when the
+ item's local position changes, relative to its parent (i.e., as a result
+ of calling setPos() or moveBy()). The value argument is the new position
+ (i.e., a QPointF). You can call pos() to get the original position. Do
+ not call setPos() or moveBy() in itemChange() as this notification is
+ delivered; instead, you can return the new, adjusted position from
+ itemChange(). After this notification, QGraphicsItem immediately sends the
+ ItemPositionHasChanged notification if the position changed.
\value ItemPositionHasChanged The item's position has changed. This
- notification is only sent after the item's local position, relative to its
- parent, has changed. The value argument is the new position (the same as
- pos()), and QGraphicsItem ignores the return value for this notification
- (i.e., a read-only notification).
+ notification is sent if the ItemSendsGeometryChanges flag is enabled, and
+ after the item's local position, relative to its parent, has changed. The
+ value argument is the new position (the same as pos()), and QGraphicsItem
+ ignores the return value for this notification (i.e., a read-only
+ notification).
\value ItemTransformChange The item's transformation matrix changes. This
- notification is only sent when the item's local transformation matrix
- changes (i.e., as a result of calling setTransform(). The value
- argument is the new matrix (i.e., a QTransform); to get the old matrix,
- call transform(). Do not call setTransform() or set any of the transformation
- properties in itemChange() as this notification is delivered;
- instead, you can return the new matrix from itemChange().
- This notification is not sent if you change the transformation properties.
+ notification is send if the ItemSendsGeometryChanges flag is enabled, and
+ when the item's local transformation matrix changes (i.e., as a result of
+ calling setTransform(). The value argument is the new matrix (i.e., a
+ QTransform); to get the old matrix, call transform(). Do not call
+ setTransform() or set any of the transformation properties in itemChange()
+ as this notification is delivered; instead, you can return the new matrix
+ from itemChange(). This notification is not sent if you change the
+ transformation properties.
\value ItemTransformHasChanged The item's transformation matrix has
- changed either because setTransform is called, or one of the transformation
- properties is changed. This notification is only sent after the item's local
+ changed either because setTransform is called, or one of the
+ transformation properties is changed. This notification is sent if the
+ ItemSendsGeometryChanges flag is enabled, and after the item's local
transformation matrix has changed. The value argument is the new matrix
(same as transform()), and QGraphicsItem ignores the return value for this
notification (i.e., a read-only notification).
@@ -772,12 +782,43 @@ QPointF QGraphicsItemPrivate::genericMapFromScene(const QPointF &pos,
/*!
\internal
- Returns true if this item or any of its ancestors are untransformable.
+ Combines this item's position and transform onto \a transform.
+
+ If you need to change this function (e.g., adding more transformation
+ modes / options), make sure to change all places marked with COMBINE.
+*/
+void QGraphicsItemPrivate::combineTransformToParent(QTransform *x, const QTransform *viewTransform) const
+{
+ // COMBINE
+ if (itemIsUntransformable() && viewTransform) {
+ *x = q_ptr->deviceTransform(*viewTransform);
+ } else {
+ if (transformData)
+ *x *= transformData->computedFullTransform();
+ if (!pos.isNull())
+ *x *= QTransform::fromTranslate(pos.x(), pos.y());
+ }
+}
+
+/*!
+ \internal
+
+ Combines this item's position and transform onto \a transform.
+
+ If you need to change this function (e.g., adding more transformation
+ modes / options), make sure to change QGraphicsItem::deviceTransform() as
+ well.
*/
-bool QGraphicsItemPrivate::itemIsUntransformable() const
+void QGraphicsItemPrivate::combineTransformFromParent(QTransform *x, const QTransform *viewTransform) const
{
- return (flags & QGraphicsItem::ItemIgnoresTransformations)
- || (ancestorFlags & AncestorIgnoresTransformations);
+ // COMBINE
+ if (itemIsUntransformable() && viewTransform) {
+ *x = q_ptr->deviceTransform(*viewTransform);
+ } else {
+ x->translate(pos.x(), pos.y());
+ if (transformData)
+ *x = transformData->computedFullTransform() * *x;
+ }
}
/*!
@@ -799,11 +840,11 @@ QVariant QGraphicsItemPrivate::inputMethodQueryHelper(Qt::InputMethodQuery query
/*!
\internal
- If \a deleting is true, then this item is being deleted, and \a parent is
- null. Make sure not to trigger any pure virtual function calls (e.g.,
- prepareGeometryChange).
+ Make sure not to trigger any pure virtual function calls (e.g.,
+ prepareGeometryChange) if the item is in its destructor, i.e.
+ inDestructor is 1.
*/
-void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, bool deleting)
+void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
{
Q_Q(QGraphicsItem);
if (newParent == q) {
@@ -830,7 +871,7 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, bool de
// We anticipate geometry changes. If the item is deleted, it will be
// removed from the index at a later stage, and the whole scene will be
// updated.
- if (!deleting)
+ if (!inDestructor)
q_ptr->prepareGeometryChange();
const QVariant thisPointerVariant(qVariantFromValue<QGraphicsItem *>(q));
@@ -842,7 +883,7 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, bool de
// Update toplevelitem list. If this item is being deleted, its parent
// will be 0 but we don't want to register/unregister it in the TLI list.
- if (scene && !deleting) {
+ if (scene && !inDestructor) {
if (parent && !newParent) {
scene->d_func()->registerTopLevelItem(q);
} else if (!parent && newParent) {
@@ -863,8 +904,11 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, bool de
parent->d_ptr->addChild(q);
parent->itemChange(QGraphicsItem::ItemChildAddedChange, thisPointerVariant);
- if (!implicitUpdate)
- updateHelper(QRectF(), false, true);
+ if (!implicitUpdate && scene) {
+ scene->d_func()->markDirty(q_ptr, QRect(),
+ /*invalidateChildren=*/false,
+ /*maybeDirtyClipPath=*/true);
+ }
// Inherit ancestor flags from the new parent.
updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1));
@@ -887,7 +931,7 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, bool de
updateAncestorFlag(QGraphicsItem::ItemClipsChildrenToShape);
updateAncestorFlag(QGraphicsItem::ItemIgnoresTransformations);
- if (!deleting) {
+ if (!inDestructor) {
// Update item visible / enabled.
if (!visible && !explicitlyHidden)
setVisibleHelper(true, /* explicit = */ false);
@@ -895,7 +939,11 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, bool de
setEnabledHelper(true, /* explicit = */ false);
// If the item is being deleted, the whole scene will be updated.
- updateHelper(QRectF(), false, true);
+ if (scene) {
+ scene->d_func()->markDirty(q_ptr, QRect(),
+ /*invalidateChildren=*/false,
+ /*maybeDirtyClipPath=*/true);
+ }
}
}
@@ -905,14 +953,9 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, bool de
scene->d_func()->invalidateSortCache();
}
- // Resolve opacity.
- updateEffectiveOpacity();
-
// Resolve depth.
resolveDepth(parent ? parent->d_ptr->depth : -1);
-
- // Invalidate transform cache.
- invalidateSceneTransformCache();
+ dirtySceneTransform = 1;
// Deliver post-change notification
q->itemChange(QGraphicsItem::ItemParentHasChanged, newParentVariant);
@@ -925,20 +968,18 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, bool de
*/
void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rect)
{
+ if (!dirtyChildrenBoundingRect) {
+ *rect |= x->mapRect(childrenBoundingRect);
+ return;
+ }
+
for (int i = 0; i < children.size(); ++i) {
QGraphicsItem *child = children.at(i);
QGraphicsItemPrivate *childd = child->d_ptr;
- bool hasX = childd->hasTransform;
bool hasPos = !childd->pos.isNull();
- if (hasPos || hasX) {
- QTransform matrix;
- if (hasX)
- matrix = child->transform();
- if (hasPos) {
- const QPointF &p = childd->pos;
- matrix *= QTransform::fromTranslate(p.x(), p.y());
- }
- matrix *= *x;
+ if (hasPos || childd->transformData) {
+ // COMBINE
+ QTransform matrix = childd->transformToParent() * *x;
*rect |= matrix.mapRect(child->boundingRect());
if (!childd->children.isEmpty())
childd->childrenBoundingRectHelper(&matrix, rect);
@@ -948,6 +989,9 @@ void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rec
childd->childrenBoundingRectHelper(x, rect);
}
}
+
+ childrenBoundingRect = *rect;
+ dirtyChildrenBoundingRect = 0;
}
void QGraphicsItemPrivate::initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform,
@@ -979,14 +1023,12 @@ void QGraphicsItemPrivate::initStyleOption(QStyleOptionGraphicsItem *option, con
return;
// Initialize QStyleOptionGraphicsItem specific values (matrix, exposedRect).
-
- const QTransform itemToViewportTransform = q->deviceTransform(worldTransform);
- option->matrix = itemToViewportTransform.toAffine(); //### discards perspective
+ option->matrix = worldTransform.toAffine(); //### discards perspective
if (!allItems) {
// Determine the item's exposed area
option->exposedRect = QRectF();
- const QTransform reverseMap = itemToViewportTransform.inverted();
+ const QTransform reverseMap = worldTransform.inverted();
const QVector<QRect> exposedRects(exposedRegion.rects());
for (int i = 0; i < exposedRects.size(); ++i) {
option->exposedRect |= reverseMap.mapRect(exposedRects.at(i));
@@ -1073,20 +1115,22 @@ QGraphicsItem::QGraphicsItem(QGraphicsItemPrivate &dd, QGraphicsItem *parent,
*/
QGraphicsItem::~QGraphicsItem()
{
- if (d_ptr->scene && !d_ptr->parent)
- d_ptr->scene->d_func()->unregisterTopLevelItem(this);
+ d_ptr->inDestructor = 1;
+ d_ptr->removeExtraItemCache();
clearFocus();
+ if (!d_ptr->children.isEmpty()) {
+ QList<QGraphicsItem *> oldChildren = d_ptr->children;
+ qDeleteAll(oldChildren);
+ Q_ASSERT(d_ptr->children.isEmpty());
+ }
- d_ptr->removeExtraItemCache();
- QList<QGraphicsItem *> oldChildren = d_ptr->children;
- qDeleteAll(oldChildren);
- Q_ASSERT(d_ptr->children.isEmpty());
-
- d_ptr->setParentItemHelper(0, /* deleting = */ true);
if (d_ptr->scene)
- d_ptr->scene->d_func()->_q_removeItemLater(this);
+ d_ptr->scene->d_func()->removeItemHelper(this);
+ else
+ d_ptr->setParentItemHelper(0);
+ delete d_ptr->transformData;
delete d_ptr;
qt_dataStore()->data.remove(this);
@@ -1228,7 +1272,7 @@ QGraphicsWidget *QGraphicsItem::window() const
*/
void QGraphicsItem::setParentItem(QGraphicsItem *parent)
{
- d_ptr->setParentItemHelper(parent, /* deleting = */ false);
+ d_ptr->setParentItemHelper(parent);
}
/*!
@@ -1333,7 +1377,9 @@ static void _q_qgraphicsItemSetFlag(QGraphicsItem *item, QGraphicsItem::Graphics
item was selected, and \a flags does not enabled ItemIsSelectable, the
item is automatically unselected.
- By default, no flags are enabled.
+ By default, no flags are enabled. (QGraphicsWidget enables the
+ ItemSendsGeometryChanges flag by default in order to track position
+ changes.)
\sa flags(), setFlag()
*/
@@ -1350,7 +1396,7 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations);
bool fullUpdate = (quint32(flags) & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask);
if (fullUpdate)
- d_ptr->fullUpdateHelper(false, true);
+ d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
// Keep the old flags to compare the diff.
GraphicsItemFlags oldFlags = this->flags();
@@ -1358,11 +1404,6 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
// Update flags.
d_ptr->flags = flags;
- // Reresolve effective opacity if the opacity flags change.
- static const quint32 opacityFlagsMask = ItemIgnoresParentOpacity | ItemDoesntPropagateOpacityToChildren;
- if ((flags & opacityFlagsMask) != (oldFlags & opacityFlagsMask))
- d_ptr->updateEffectiveOpacity();
-
if (!(d_ptr->flags & ItemIsFocusable) && hasFocus()) {
// Clear focus on the item if it has focus when the focusable flag
// is unset.
@@ -1390,8 +1431,19 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
d_ptr->updateAncestorFlag(ItemIgnoresTransformations);
}
- // ### Why updateHelper?
- d_ptr->updateHelper(QRectF(), false, true);
+ if ((flags & ItemStacksBehindParent) != (oldFlags & ItemStacksBehindParent)) {
+ // Ensure child item sorting is up to date when toggling this flag.
+ if (d_ptr->parent)
+ d_ptr->parent->d_ptr->needSortChildren = 1;
+ else if (d_ptr->scene)
+ d_ptr->scene->d_func()->needSortTopLevelItems = 1;
+ }
+
+ if (d_ptr->scene) {
+ d_ptr->scene->d_func()->markDirty(this, QRectF(),
+ /*invalidateChildren=*/true,
+ /*maybeDirtyClipPath*/true);
+ }
// Notify change.
itemChange(ItemFlagsHaveChanged, quint32(flags));
@@ -1657,7 +1709,12 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo
QGraphicsItemCache *c = (QGraphicsItemCache *)qVariantValue<void *>(extra(ExtraCacheData));
if (c)
c->purge();
- updateHelper(QRectF(), /* force = */ true);
+ if (scene) {
+ scene->d_func()->markDirty(q_ptr, QRectF(),
+ /*invalidateChildren=*/false,
+ /*maybeDirtyClipPath=*/false,
+ /*force=*/true);
+ }
}
// Certain properties are dropped as an item becomes invisible.
@@ -1820,8 +1877,8 @@ void QGraphicsItemPrivate::setEnabledHelper(bool newEnabled, bool explicitly, bo
enabled = newEnabledVariant.toBool();
// Schedule redraw.
- if (update)
- updateHelper();
+ if (update && scene)
+ scene->d_func()->markDirty(q_ptr);
foreach (QGraphicsItem *child, children) {
if (!newEnabled || !child->d_ptr->explicitlyDisabled)
@@ -1922,9 +1979,8 @@ void QGraphicsItem::setSelected(bool selected)
return;
d_ptr->selected = newSelected;
- d_ptr->updateHelper();
-
if (d_ptr->scene) {
+ d_ptr->scene->d_func()->markDirty(this);
QGraphicsScenePrivate *sceneD = d_ptr->scene->d_func();
if (selected) {
sceneD->selectedItems << this;
@@ -1960,12 +2016,7 @@ void QGraphicsItem::setSelected(bool selected)
*/
qreal QGraphicsItem::opacity() const
{
- if (d_ptr->hasOpacity) {
- QVariant o = d_ptr->extra(QGraphicsItemPrivate::ExtraOpacity);
- if (!o.isNull())
- return o.toDouble();
- }
- return qreal(1.0);
+ return d_ptr->opacity;
}
/*!
@@ -1981,11 +2032,7 @@ qreal QGraphicsItem::opacity() const
*/
qreal QGraphicsItem::effectiveOpacity() const
{
- if (!d_ptr->hasEffectiveOpacity)
- return qreal(1.0);
-
- QVariant effectiveOpacity = d_ptr->extra(QGraphicsItemPrivate::ExtraEffectiveOpacity);
- return effectiveOpacity.isNull() ? qreal(1.0) : qreal(effectiveOpacity.toDouble());
+ return d_ptr->effectiveOpacity();
}
/*!
@@ -2020,30 +2067,21 @@ void QGraphicsItem::setOpacity(qreal opacity)
newOpacity = qBound<qreal>(0.0, newOpacity, 1.0);
// No change? Done.
- if (qFuzzyIsNull(newOpacity - this->opacity()))
+ if (newOpacity == d_ptr->opacity)
return;
- // Assign local opacity.
- if (qFuzzyIsNull(newOpacity - 1)) {
- // Opaque, unset opacity.
- d_ptr->hasOpacity = 0;
- d_ptr->unsetExtra(QGraphicsItemPrivate::ExtraOpacity);
- } else {
- d_ptr->hasOpacity = 1;
- d_ptr->setExtra(QGraphicsItemPrivate::ExtraOpacity, double(newOpacity));
- }
-
- // Resolve effective opacity.
- if (QGraphicsItem *p = d_ptr->parent)
- d_ptr->resolveEffectiveOpacity(p->effectiveOpacity());
- else
- d_ptr->resolveEffectiveOpacity(1.0);
+ d_ptr->opacity = newOpacity;
// Notify change.
- itemChange(ItemOpacityHasChanged, newOpacity);
+ itemChange(ItemOpacityHasChanged, newOpacityVariant);
// Update.
- d_ptr->fullUpdateHelper(/*childrenOnly=*/false, /*maybeDirtyClipPath=*/false, /*ignoreOpacity=*/true);
+ if (d_ptr->scene)
+ d_ptr->scene->d_func()->markDirty(this, QRectF(),
+ /*invalidateChildren=*/true,
+ /*maybeDirtyClipPath=*/false,
+ /*force=*/false,
+ /*ignoreOpacity=*/true);
}
/*!
@@ -2474,38 +2512,33 @@ QPointF QGraphicsItem::scenePos() const
/*!
\internal
- Sets the position \a pos and notifies the change. If \a update is true,
- the item is also updated; otherwise it is not updated before and after the
- change.
+ Sets the position \a pos.
*/
void QGraphicsItemPrivate::setPosHelper(const QPointF &pos)
{
Q_Q(QGraphicsItem);
- if (this->pos == pos)
- return;
-
- // Notify the item that the position is changing.
- const QVariant newPosVariant(q->itemChange(QGraphicsItem::ItemPositionChange, pos));
- QPointF newPos = newPosVariant.toPointF();
- if (newPos == this->pos)
- return;
-
- // Update and repositition.
inSetPosHelper = 1;
- updateCachedClipPathFromSetPosHelper(newPos);
- if (scene) {
- fullUpdateHelper(true);
+ updateCachedClipPathFromSetPosHelper(pos);
+ if (scene)
q->prepareGeometryChange();
- }
- this->pos = newPos;
- invalidateSceneTransformCache();
-
- // Send post-notification.
- q->itemChange(QGraphicsItem::ItemPositionHasChanged, newPosVariant);
+ this->pos = pos;
+ dirtySceneTransform = 1;
inSetPosHelper = 0;
}
/*!
+ \internal
+
+ Sets the transform \a transform.
+*/
+void QGraphicsItemPrivate::setTransformHelper(const QTransform &transform)
+{
+ q_ptr->prepareGeometryChange();
+ transformData->transform = transform;
+ dirtySceneTransform = 1;
+}
+
+/*!
Sets the position of the item to \a pos, which is in parent
coordinates. For items with no parent, \a pos is in scene
coordinates.
@@ -2517,7 +2550,26 @@ void QGraphicsItemPrivate::setPosHelper(const QPointF &pos)
*/
void QGraphicsItem::setPos(const QPointF &pos)
{
- d_ptr->setPosHelper(pos);
+ if (d_ptr->pos == pos)
+ return;
+
+ // Update and repositition.
+ if (!(d_ptr->flags & ItemSendsGeometryChanges)) {
+ d_ptr->setPosHelper(pos);
+ return;
+ }
+
+ // Notify the item that the position is changing.
+ const QVariant newPosVariant(itemChange(ItemPositionChange, qVariantFromValue<QPointF>(pos)));
+ QPointF newPos = newPosVariant.toPointF();
+ if (newPos == d_ptr->pos)
+ return;
+
+ // Update and repositition.
+ d_ptr->setPosHelper(newPos);
+
+ // Send post-notification.
+ itemChange(QGraphicsItem::ItemPositionHasChanged, newPosVariant);
}
/*!
@@ -2602,19 +2654,9 @@ QMatrix QGraphicsItem::matrix() const
*/
QTransform QGraphicsItem::transform() const
{
- if (!d_ptr->hasTransform)
+ if (!d_ptr->transformData)
return QTransform();
- if (d_ptr->hasDecomposedTransform && d_ptr->dirtyTransform) {
- QGraphicsItemPrivate::DecomposedTransform *decomposed = d_ptr->decomposedTransform();
- QTransform x;
- decomposed->generateTransform(&x);
- QVariant v(x);
- d_ptr->setExtra(QGraphicsItemPrivate::ExtraTransform, v);
- d_ptr->dirtyTransform = 0;
- const_cast<QGraphicsItem *>(this)->itemChange(ItemTransformHasChanged, v);
- return x;
- }
- return qVariantValue<QTransform>(d_ptr->extra(QGraphicsItemPrivate::ExtraTransform));
+ return d_ptr->transformData->transform;
}
/*!
@@ -2624,14 +2666,15 @@ QTransform QGraphicsItem::transform() const
The default is 0
- \warning setting this property is conflicting with calling setTransform.
- If a transform has been set, this function return the default value.
+ \warning The value doesn't take in account any rotation set with the setTransform() method.
\sa setXRotation(), {Transformations}
*/
qreal QGraphicsItem::xRotation() const
{
- return d_ptr->decomposedTransform()->xRotation;
+ if (!d_ptr->transformData)
+ return 0;
+ return d_ptr->transformData->xRotation;
}
/*!
@@ -2639,23 +2682,17 @@ qreal QGraphicsItem::xRotation() const
Sets the rotation around the X axis to \a angle degrees.
- \warning setting this property is conflicting with calling setTransform.
- If a transform has been set, it will be overwritten.
+ \warning The value doesn't take in account any rotation set with the setTransform() method.
- \sa xRotation(), {Transformations}
+ \sa xRotation(), setTransformOrigin(), {Transformations}
*/
void QGraphicsItem::setXRotation(qreal angle)
{
- if (!d_ptr->dirtyTransform) {
- d_ptr->fullUpdateHelper(true);
- prepareGeometryChange();
- }
- QGraphicsItemPrivate::DecomposedTransform *decomposed = d_ptr->decomposedTransform();
- decomposed->xRotation = angle;
- if (!d_ptr->dirtyTransform)
- d_ptr->invalidateSceneTransformCache();
- d_ptr->dirtyTransform = 1;
- d_ptr->hasTransform = 1;
+ prepareGeometryChange();
+ if (!d_ptr->transformData)
+ d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
+ d_ptr->transformData->xRotation = angle;
+ d_ptr->dirtySceneTransform = 1;
}
/*!
@@ -2665,14 +2702,15 @@ void QGraphicsItem::setXRotation(qreal angle)
The default is 0
- \warning setting this property is conflicting with calling setTransform.
- If a transform has been set, this function return the default value.
+ \warning The value doesn't take in account any rotation set with the setTransform() method.
\sa setYRotation(), {Transformations}
*/
qreal QGraphicsItem::yRotation() const
{
- return d_ptr->decomposedTransform()->yRotation;
+ if (!d_ptr->transformData)
+ return 0;
+ return d_ptr->transformData->yRotation;
}
/*!
@@ -2680,23 +2718,17 @@ qreal QGraphicsItem::yRotation() const
Sets the rotation around the Y axis to \a angle degrees.
- \warning setting this property is conflicting with calling setTransform.
- If a transform has been set, it will be overwritten.
+ \warning The value doesn't take in account any rotation set with the setTransform() method.
- \sa yRotation(), {Transformations}
+ \sa yRotation(), setTransformOrigin() {Transformations}
*/
void QGraphicsItem::setYRotation(qreal angle)
{
- if (!d_ptr->dirtyTransform) {
- d_ptr->fullUpdateHelper(true);
- prepareGeometryChange();
- }
- QGraphicsItemPrivate::DecomposedTransform *decomposed = d_ptr->decomposedTransform();
- decomposed->yRotation = angle;
- if (!d_ptr->dirtyTransform)
- d_ptr->invalidateSceneTransformCache();
- d_ptr->dirtyTransform = 1;
- d_ptr->hasTransform = 1;
+ prepareGeometryChange();
+ if (!d_ptr->transformData)
+ d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
+ d_ptr->transformData->yRotation = angle;
+ d_ptr->dirtySceneTransform = 1;
}
/*!
@@ -2706,14 +2738,15 @@ void QGraphicsItem::setYRotation(qreal angle)
The default is 0
- \warning setting this property is conflicting with calling setTransform.
- If a transform has been set, this function return the default value.
+ \warning The value doesn't take in account any rotation set with the setTransform() method.
\sa setZRotation(), {Transformations}
*/
qreal QGraphicsItem::zRotation() const
{
- return d_ptr->decomposedTransform()->zRotation;
+ if (!d_ptr->transformData)
+ return 0;
+ return d_ptr->transformData->zRotation;
}
/*!
@@ -2721,23 +2754,17 @@ qreal QGraphicsItem::zRotation() const
Sets the rotation around the Z axis to \a angle degrees.
- \warning setting this property is conflicting with calling setTransform.
- If a transform has been set, it will be overwritten.
+ \warning The value doesn't take in account any rotation set with the setTransform() method.
- \sa zRotation(), {Transformations}
+ \sa zRotation(), setTransformOrigin(), {Transformations}
*/
void QGraphicsItem::setZRotation(qreal angle)
{
- if (!d_ptr->dirtyTransform) {
- d_ptr->fullUpdateHelper(true);
- prepareGeometryChange();
- }
- QGraphicsItemPrivate::DecomposedTransform *decomposed = d_ptr->decomposedTransform();
- decomposed->zRotation = angle;
- if (!d_ptr->dirtyTransform)
- d_ptr->invalidateSceneTransformCache();
- d_ptr->dirtyTransform = 1;
- d_ptr->hasTransform = 1;
+ prepareGeometryChange();
+ if (!d_ptr->transformData)
+ d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
+ d_ptr->transformData->zRotation = angle;
+ d_ptr->dirtySceneTransform = 1;
}
/*!
@@ -2746,13 +2773,17 @@ void QGraphicsItem::setZRotation(qreal angle)
This convenience function set the rotation angles around the 3 axes
to \a x, \a y and \a z.
- \sa setXRotation(), setYRotation(), setZRotation()
+ \sa setXRotation(), setYRotation(), setZRotation(), {Transformations}
*/
void QGraphicsItem::setRotation(qreal x, qreal y, qreal z)
{
- setXRotation(x);
- setYRotation(y);
- setZRotation(z);
+ prepareGeometryChange();
+ if (!d_ptr->transformData)
+ d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
+ d_ptr->transformData->xRotation = x;
+ d_ptr->transformData->yRotation = y;
+ d_ptr->transformData->zRotation = z;
+ d_ptr->dirtySceneTransform = 1;
}
/*!
@@ -2762,14 +2793,15 @@ void QGraphicsItem::setRotation(qreal x, qreal y, qreal z)
The default is 1
- \warning setting this property is conflicting with calling setTransform.
- If a transform has been set, this function return the default value.
+ \warning The value doesn't take in account any scaling set with the setTransform() method.
\sa setXScale(), {Transformations}
*/
qreal QGraphicsItem::xScale() const
{
- return d_ptr->decomposedTransform()->xScale;
+ if (!d_ptr->transformData)
+ return 1;
+ return d_ptr->transformData->xScale;
}
/*!
@@ -2777,23 +2809,17 @@ qreal QGraphicsItem::xScale() const
Sets the scale factor on the X axis to \a factor.
- \warning setting this property is conflicting with calling setTransform.
- If a transform has been set, it will be overwritten.
+ \warning The value doesn't take in account any scaling set with the setTransform() method.
- \sa xScale(), {Transformations}
+ \sa xScale(), setTransformOrigin(), {Transformations}
*/
void QGraphicsItem::setXScale(qreal factor)
{
- if (!d_ptr->dirtyTransform) {
- d_ptr->fullUpdateHelper(true);
- prepareGeometryChange();
- }
- QGraphicsItemPrivate::DecomposedTransform *decomposed = d_ptr->decomposedTransform();
- decomposed->xScale = factor;
- if (!d_ptr->dirtyTransform)
- d_ptr->invalidateSceneTransformCache();
- d_ptr->dirtyTransform = 1;
- d_ptr->hasTransform = 1;
+ prepareGeometryChange();
+ if (!d_ptr->transformData)
+ d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
+ d_ptr->transformData->xScale = factor;
+ d_ptr->dirtySceneTransform = 1;
}
/*!
@@ -2803,14 +2829,15 @@ void QGraphicsItem::setXScale(qreal factor)
The default is 1
- \warning setting this property is conflicting with calling setTransform.
- If a transform has been set, this function return the default value.
+ \warning The value doesn't take in account any scaling set with the setTransform() method.
\sa setYScale(), {Transformations}
*/
qreal QGraphicsItem::yScale() const
{
- return d_ptr->decomposedTransform()->yScale;
+ if (!d_ptr->transformData)
+ return 1;
+ return d_ptr->transformData->yScale;
}
/*!
@@ -2818,23 +2845,17 @@ qreal QGraphicsItem::yScale() const
Sets the scale factor on the Y axis to \a factor.
- \warning setting this property is conflicting with calling setTransform.
- If a transform has been set, it will be overwritten.
+ \warning The value doesn't take in account any scaling set with the setTransform() method.
- \sa yScale(), {Transformations}
+ \sa yScale(), setTransformOrigin(), {Transformations}
*/
void QGraphicsItem::setYScale(qreal factor)
{
- if (!d_ptr->dirtyTransform) {
- d_ptr->fullUpdateHelper(true);
- prepareGeometryChange();
- }
- QGraphicsItemPrivate::DecomposedTransform *decomposed = d_ptr->decomposedTransform();
- decomposed->yScale = factor;
- if (!d_ptr->dirtyTransform)
- d_ptr->invalidateSceneTransformCache();
- d_ptr->dirtyTransform = 1;
- d_ptr->hasTransform = 1;
+ prepareGeometryChange();
+ if (!d_ptr->transformData)
+ d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
+ d_ptr->transformData->yScale = factor;
+ d_ptr->dirtySceneTransform = 1;
}
/*!
@@ -2842,12 +2863,18 @@ void QGraphicsItem::setYScale(qreal factor)
This convenience function set the scaling factors on X and Y axis to \a sx and \a sy.
- \sa setXScale(), setYScale()
+ \warning The value doesn't take in account any scaling set with the setTransform() method.
+
+ \sa setXScale(), setYScale(), {Transformations}
*/
void QGraphicsItem::setScale(qreal sx, qreal sy)
{
- setXScale(sx);
- setYScale(sy);
+ prepareGeometryChange();
+ if (!d_ptr->transformData)
+ d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
+ d_ptr->transformData->xScale = sx;
+ d_ptr->transformData->yScale = sy;
+ d_ptr->dirtySceneTransform = 1;
}
/*!
@@ -2857,14 +2884,15 @@ void QGraphicsItem::setScale(qreal sx, qreal sy)
The default is 0
- \warning setting this property is conflicting with calling setTransform.
- If a transform has been set, this function return the default value.
+ \warning The value doesn't take in account any shearing set with the setTransform() method.
\sa setHorizontalShear(), {Transformations}
*/
qreal QGraphicsItem::horizontalShear() const
{
- return d_ptr->decomposedTransform()->horizontalShear;
+ if (!d_ptr->transformData)
+ return 0;
+ return d_ptr->transformData->horizontalShear;
}
/*!
@@ -2872,23 +2900,17 @@ qreal QGraphicsItem::horizontalShear() const
Sets the horizontal shear to \a shear.
- \warning setting this property is conflicting with calling setTransform.
- If a transform has been set, it will be overwritten.
+ \warning The value doesn't take in account any shearing set with the setTransform() method.
\sa horizontalShear(), {Transformations}
*/
void QGraphicsItem::setHorizontalShear(qreal shear)
{
- if (!d_ptr->dirtyTransform) {
- d_ptr->fullUpdateHelper(true);
- prepareGeometryChange();
- }
- QGraphicsItemPrivate::DecomposedTransform *decomposed = d_ptr->decomposedTransform();
- decomposed->horizontalShear = shear;
- if (!d_ptr->dirtyTransform)
- d_ptr->invalidateSceneTransformCache();
- d_ptr->dirtyTransform = 1;
- d_ptr->hasTransform = 1;
+ prepareGeometryChange();
+ if (!d_ptr->transformData)
+ d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
+ d_ptr->transformData->horizontalShear = shear;
+ d_ptr->dirtySceneTransform = 1;
}
/*!
@@ -2898,14 +2920,15 @@ void QGraphicsItem::setHorizontalShear(qreal shear)
The default is 0
- \warning setting this property is conflicting with calling setTransform.
- If a transform has been set, this function return the default value.
+ \warning The value doesn't take in account any shearing set with the setTransform() method.
\sa setHorizontalShear(), {Transformations}
*/
qreal QGraphicsItem::verticalShear() const
{
- return d_ptr->decomposedTransform()->verticalShear;
+ if (!d_ptr->transformData)
+ return 0;
+ return d_ptr->transformData->verticalShear;
}
/*!
@@ -2913,23 +2936,17 @@ qreal QGraphicsItem::verticalShear() const
Sets the vertical shear to \a shear.
- \warning setting this property is conflicting with calling setTransform.
- If a transform has been set, it will be overwritten.
+ \warning The value doesn't take in account any shearing set with the setTransform() method.
\sa verticalShear(), {Transformations}
*/
void QGraphicsItem::setVerticalShear(qreal shear)
{
- if (!d_ptr->dirtyTransform) {
- d_ptr->fullUpdateHelper(true);
- prepareGeometryChange();
- }
- QGraphicsItemPrivate::DecomposedTransform *decomposed = d_ptr->decomposedTransform();
- decomposed->verticalShear = shear;
- if (!d_ptr->dirtyTransform)
- d_ptr->invalidateSceneTransformCache();
- d_ptr->dirtyTransform = 1;
- d_ptr->hasTransform = 1;
+ prepareGeometryChange();
+ if (!d_ptr->transformData)
+ d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
+ d_ptr->transformData->verticalShear = shear;
+ d_ptr->dirtySceneTransform = 1;
}
/*!
@@ -2937,69 +2954,62 @@ void QGraphicsItem::setVerticalShear(qreal shear)
This convenience function sets the horizontal shear to \a sh and the vertical shear to \a sv.
+ \warning The value doesn't take in account any shearing set with the setTransform() method.
+
\sa setHorizontalShear(), setVerticalShear()
*/
void QGraphicsItem::setShear(qreal sh, qreal sv)
{
- setHorizontalShear(sh);
- setVerticalShear(sv);
+ prepareGeometryChange();
+ if (!d_ptr->transformData)
+ d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
+ d_ptr->transformData->horizontalShear = sh;
+ d_ptr->transformData->verticalShear = sv;
+ d_ptr->dirtySceneTransform = 1;
}
/*!
\since 4.6
- Returns the transformation origin for the transformation properties.
+ Returns the origin point using for transformation in item coordinate.
The default is QPointF(0,0).
- \warning setting this property is conflicting with calling setTransform.
- If a transform has been set, this function return the default value.
-
\sa setTransformOrigin(), {Transformations}
*/
QPointF QGraphicsItem::transformOrigin() const
{
- const QGraphicsItemPrivate::DecomposedTransform *decomposed = d_ptr->decomposedTransform();
- return QPointF(decomposed->xOrigin, decomposed->yOrigin);
+ if (!d_ptr->transformData)
+ return QPointF(0,0);
+ return QPointF(d_ptr->transformData->xOrigin, d_ptr->transformData->yOrigin);
}
/*!
- \fn inline void setTransformOrigin(qreal x, qreal y)
-
\since 4.6
- This is an overloaded member function, provided for convenience.
- Sets the transformation origin for the transformation
- properties to the point(\a x, \a y).
+ Sets the origin for transformation in item coordinate
- \sa setTransformOrigin(), {Transformations}
+ \sa transformOrigin(), {Transformations}
*/
+void QGraphicsItem::setTransformOrigin(const QPointF &origin)
+{
+ prepareGeometryChange();
+ if (!d_ptr->transformData)
+ d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
+ d_ptr->transformData->xOrigin = origin.x();
+ d_ptr->transformData->yOrigin = origin.y();
+ d_ptr->dirtySceneTransform = 1;
+}
/*!
- \since 4.6
-
- Sets the transformation origin for the transformation properties to \a origin.
- This does not apply to the transformation set by setTransform.
+ \fn inline void setTransformOrigin(qreal x, qreal y)
- \warning setting this property is conflicting with calling setTransform.
- If a transform has been set, it will be overwritten.
+ \since 4.6
+ \overload
- \sa transformOrigin(), {Transformations}
+ \sa setTransformOrigin(), {Transformations}
*/
-void QGraphicsItem::setTransformOrigin(const QPointF &origin)
-{
- if (!d_ptr->dirtyTransform) {
- d_ptr->fullUpdateHelper(true);
- prepareGeometryChange();
- }
- QGraphicsItemPrivate::DecomposedTransform *decomposed = d_ptr->decomposedTransform();
- decomposed->xOrigin = origin.x();
- decomposed->yOrigin = origin.y();
- if (!d_ptr->dirtyTransform)
- d_ptr->invalidateSceneTransformCache();
- d_ptr->dirtyTransform = 1;
- d_ptr->hasTransform = 1;
-}
+
/*!
\obsolete
@@ -3027,51 +3037,23 @@ QMatrix QGraphicsItem::sceneMatrix() const
\snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 4
Unlike transform(), which returns only an item's local transformation, this
- function includes the item's (and any parents') position.
+ function includes the item's (and any parents') position, and all the transfomation properties.
- \sa transform(), setTransform(), scenePos(), {The Graphics View Coordinate System}
+ \sa transform(), setTransform(), scenePos(), {The Graphics View Coordinate System}, {Transformations}
*/
QTransform QGraphicsItem::sceneTransform() const
{
- // Check if there's any entry in the transform cache.
- QGraphicsScenePrivate *sd = d_ptr->scene ? d_ptr->scene->d_func() : 0;
- int index = d_ptr->sceneTransformIndex;
- if (sd && index != -1 && sd->validTransforms.testBit(index))
- return sd->sceneTransformCache[index];
-
- // Calculate local transform.
- QTransform m;
- if (d_ptr->hasTransform) {
- m = transform();
- if (!d_ptr->pos.isNull())
- m *= QTransform::fromTranslate(d_ptr->pos.x(), d_ptr->pos.y());
- } else if (!d_ptr->pos.isNull()) {
- m = QTransform::fromTranslate(d_ptr->pos.x(), d_ptr->pos.y());
- }
-
- // Combine with parent and add to cache.
- if (d_ptr->parent) {
- m *= d_ptr->parent->sceneTransform();
- // Don't cache toplevels
- if (sd) {
- if (index == -1) {
- if (!sd->freeSceneTransformSlots.isEmpty()) {
- index = sd->freeSceneTransformSlots.last();
- sd->freeSceneTransformSlots.pop_back();
- } else {
- index = sd->sceneTransformCache.size();
- }
- d_ptr->sceneTransformIndex = index;
- if (index >= sd->validTransforms.size()) {
- sd->validTransforms.resize(index + 1);
- sd->sceneTransformCache.resize(index + 1);
- }
- }
- sd->validTransforms.setBit(index, 1);
- sd->sceneTransformCache[index] = m;
- }
+ if (d_ptr->dirtySceneTransform) {
+ // This item and all its descendants have dirty scene transforms.
+ // We're about to validate this item's scene transform, so we have to
+ // invalidate all the children; otherwise there's no way for the descendants
+ // to detect that the ancestor has changed.
+ d_ptr->invalidateChildrenSceneTransform();
}
- return m;
+
+ QGraphicsItem *that = const_cast<QGraphicsItem *>(this);
+ d_ptr->ensureSceneTransformRecursive(&that);
+ return d_ptr->sceneTransform;
}
/*!
@@ -3121,17 +3103,17 @@ QTransform QGraphicsItem::deviceTransform(const QTransform &viewportTransform) c
// First translate the base untransformable item.
QPointF mappedPoint = (untransformedAncestor->sceneTransform() * viewportTransform).map(QPointF(0, 0));
+
+ // COMBINE
QTransform matrix;
matrix.translate(mappedPoint.x(), mappedPoint.y());
- matrix = untransformedAncestor->transform() * matrix;
+ if (untransformedAncestor->d_ptr->transformData)
+ matrix = untransformedAncestor->d_ptr->transformData->computedFullTransform() * matrix;
// Then transform and translate all children.
for (int i = 0; i < parents.size(); ++i) {
const QGraphicsItem *parent = parents.at(i);
- QPointF pos = parent->pos();
- QTransform moveMatrix;
- moveMatrix.translate(pos.x(), pos.y());
- matrix = (parent->transform() * moveMatrix) * matrix;
+ parent->d_ptr->combineTransformFromParent(&matrix);
}
return matrix;
@@ -3174,51 +3156,40 @@ QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) co
if (parent == other) {
if (ok)
*ok = true;
- const QPointF &itemPos = d_ptr->pos;
- if (itemPos.isNull())
- return d_ptr->hasTransform ? transform() : QTransform();
- if (d_ptr->hasTransform)
- return transform() * QTransform::fromTranslate(itemPos.x(), itemPos.y());
- return QTransform::fromTranslate(itemPos.x(), itemPos.y());
+ QTransform x;
+ d_ptr->combineTransformFromParent(&x);
+ return x;
}
// This is other's parent
if (otherParent == this) {
const QPointF &otherPos = other->d_ptr->pos;
- if (other->d_ptr->hasTransform) {
- QTransform otherToParent = other->transform();
- if (!otherPos.isNull())
- otherToParent *= QTransform::fromTranslate(otherPos.x(), otherPos.y());
+ if (other->d_ptr->transformData) {
+ QTransform otherToParent;
+ other->d_ptr->combineTransformFromParent(&otherToParent);
return otherToParent.inverted(ok);
- } else {
- if (ok)
- *ok = true;
- return QTransform::fromTranslate(-otherPos.x(), -otherPos.y());
}
+ if (ok)
+ *ok = true;
+ return QTransform::fromTranslate(-otherPos.x(), -otherPos.y());
}
// Siblings
if (parent == otherParent) {
- bool hasTr = d_ptr->hasTransform;
- bool otherHasTr = other->d_ptr->hasTransform;
+ // COMBINE
const QPointF &itemPos = d_ptr->pos;
const QPointF &otherPos = other->d_ptr->pos;
-
- if (!hasTr && !otherHasTr) {
+ if (!d_ptr->transformData && !other->d_ptr->transformData) {
QPointF delta = itemPos - otherPos;
if (ok)
*ok = true;
return QTransform::fromTranslate(delta.x(), delta.y());
}
- QTransform itemToParent = QTransform::fromTranslate(itemPos.x(), itemPos.y());
- if (hasTr)
- itemToParent = itemPos.isNull() ? transform() : transform() * itemToParent;
-
- QTransform otherToParent = QTransform::fromTranslate(otherPos.x(), otherPos.y());
- if (otherHasTr)
- otherToParent = otherPos.isNull() ? other->transform() : other->transform() * otherToParent;
-
+ QTransform itemToParent;
+ d_ptr->combineTransformFromParent(&itemToParent);
+ QTransform otherToParent;
+ other->d_ptr->combineTransformFromParent(&otherToParent);
return itemToParent * otherToParent.inverted(ok);
}
@@ -3254,11 +3225,7 @@ QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) co
QTransform x;
const QGraphicsItem *p = child;
do {
- const QGraphicsItemPrivate *pd = p->d_ptr;
- if (pd->hasTransform)
- x *= p->transform();
- if (!pd->pos.isNull())
- x *= QTransform::fromTranslate(pd->pos.x(), pd->pos.y());
+ p->d_ptr->combineTransformToParent(&x);
} while ((p = p->d_ptr->parent) && p != root);
if (parentOfOther)
return x.inverted(ok);
@@ -3280,35 +3247,30 @@ QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) co
*/
void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine)
{
- QTransform oldTransform = this->transform();
- QTransform newTransform;
- if (!combine)
- newTransform = QTransform(matrix);
- else
- newTransform = QTransform(matrix) * oldTransform;
- if (oldTransform == newTransform)
- return;
+ if (!d_ptr->transformData)
+ d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
- // Notify the item that the matrix is changing.
- QVariant newTransformVariant(itemChange(ItemMatrixChange,
- qVariantFromValue<QMatrix>(newTransform.toAffine())));
- newTransform = QTransform(qVariantValue<QMatrix>(newTransformVariant));
- if (oldTransform == newTransform)
+ QTransform newTransform(combine ? QTransform(matrix) * d_ptr->transformData->transform : QTransform(matrix));
+ if (d_ptr->transformData->transform == newTransform)
return;
// Update and set the new transformation.
- d_ptr->fullUpdateHelper(true, true);
- prepareGeometryChange();
- d_ptr->hasTransform = !newTransform.isIdentity();
- d_ptr->setExtra(QGraphicsItemPrivate::ExtraTransform, newTransform);
- d_ptr->dirtyTransformComponents = 1;
- d_ptr->dirtyTransform = 0;
- d_ptr->invalidateSceneTransformCache();
+ if (!(d_ptr->flags & ItemSendsGeometryChanges)) {
+ d_ptr->setTransformHelper(newTransform);
+ return;
+ }
+
+ // Notify the item that the transformation matrix is changing.
+ const QVariant newMatrixVariant = qVariantFromValue<QMatrix>(newTransform.toAffine());
+ newTransform = QTransform(qVariantValue<QMatrix>(itemChange(ItemMatrixChange, newMatrixVariant)));
+ if (d_ptr->transformData->transform == newTransform)
+ return;
+ // Update and set the new transformation.
+ d_ptr->setTransformHelper(newTransform);
+
// Send post-notification.
- // NB! We have to change the value from QMatrix to QTransform.
- qVariantSetValue<QTransform>(newTransformVariant, newTransform);
- itemChange(ItemTransformHasChanged, newTransformVariant);
+ itemChange(ItemTransformHasChanged, qVariantFromValue<QTransform>(newTransform));
}
/*!
@@ -3326,37 +3288,34 @@ void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine)
to map an item coordiate to a scene coordinate, or mapFromScene() to map
from scene coordinates to item coordinates.
- \warning using this function conflicts with using the transformation properties.
- If you set a transformation, getting the properties will return default values.
+ \warning using this function doesnt affect the value of the transformation properties
- \sa transform(), setRotation(), setScale(), setShear(), setTransformOrigin() {The Graphics View Coordinate System}
+ \sa transform(), setRotation(), setScale(), setShear(), setTransformOrigin(), {The Graphics View Coordinate System}, {Transformations}
*/
void QGraphicsItem::setTransform(const QTransform &matrix, bool combine)
{
- QTransform oldTransform = this->transform();
- QTransform newTransform;
- if (!combine)
- newTransform = matrix;
- else
- newTransform = matrix * oldTransform;
- if (oldTransform == newTransform)
+ if (!d_ptr->transformData)
+ d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
+
+ QTransform newTransform(combine ? matrix * d_ptr->transformData->transform : matrix);
+ if (d_ptr->transformData->transform == newTransform)
return;
+ // Update and set the new transformation.
+ if (!(d_ptr->flags & ItemSendsGeometryChanges)) {
+ d_ptr->setTransformHelper(newTransform);
+ return;
+ }
+
// Notify the item that the transformation matrix is changing.
const QVariant newTransformVariant(itemChange(ItemTransformChange,
qVariantFromValue<QTransform>(newTransform)));
newTransform = qVariantValue<QTransform>(newTransformVariant);
- if (oldTransform == newTransform)
+ if (d_ptr->transformData->transform == newTransform)
return;
// Update and set the new transformation.
- d_ptr->fullUpdateHelper(true, true);
- prepareGeometryChange();
- d_ptr->hasTransform = !newTransform.isIdentity();
- d_ptr->setExtra(QGraphicsItemPrivate::ExtraTransform, newTransform);
- d_ptr->dirtyTransformComponents = 1;
- d_ptr->dirtyTransform = 0;
- d_ptr->invalidateSceneTransformCache();
+ d_ptr->setTransformHelper(newTransform);
// Send post-notification.
itemChange(ItemTransformHasChanged, newTransformVariant);
@@ -3398,8 +3357,7 @@ void QGraphicsItem::resetTransform()
\snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 6
- \warning using this function conflicts with using the transformation properties.
- Getting those properties after using this function will return default values.
+ \warning using this functionhas no effect on the zRotation value
\sa setTransform(), transform(), scale(), shear(), translate()
*/
@@ -3420,8 +3378,7 @@ void QGraphicsItem::rotate(qreal angle)
\snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 7
- \warning using this function conflicts with using the transformation properties.
- Getting those properties after using this function will return default values.
+ \warning using this function has no effect on the xScale or yScale value
\sa setTransform(), transform()
*/
@@ -3436,8 +3393,7 @@ void QGraphicsItem::scale(qreal sx, qreal sy)
Shears the current item transformation by (\a sh, \a sv).
- \warning using this function conflicts with using the transformation properties.
- Getting those properties after using this function will return default values.
+ \warning using this function has no effect on the horizontalShear or verticalShear value
\sa setTransform(), transform()
*/
@@ -3456,9 +3412,6 @@ void QGraphicsItem::shear(qreal sh, qreal sv)
setPos() instead; this function changes the item's translation,
which is conceptually separate from its position.
- \warning using this function conflicts with using the transformation properties.
- Getting those properties after using this function will return default values.
-
\sa setTransform(), transform()
*/
void QGraphicsItem::translate(qreal dx, qreal dy)
@@ -3537,9 +3490,13 @@ void QGraphicsItem::setZValue(qreal z)
if (newZ == d_ptr->z)
return;
d_ptr->z = newZ;
- d_ptr->fullUpdateHelper();
+ if (d_ptr->parent)
+ d_ptr->parent->d_ptr->needSortChildren = 1;
+ else if (d_ptr->scene)
+ d_ptr->scene->d_func()->needSortTopLevelItems = 1;
if (d_ptr->scene) {
+ d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true);
// Invalidate any sort caching; arrival of a new item means we need to
// resort.
d_ptr->scene->d_func()->invalidateSortCache();
@@ -3567,6 +3524,9 @@ void QGraphicsItem::setZValue(qreal z)
*/
QRectF QGraphicsItem::childrenBoundingRect() const
{
+ if (!d_ptr->dirtyChildrenBoundingRect)
+ return d_ptr->childrenBoundingRect;
+
QRectF childRect;
QTransform x;
d_ptr->childrenBoundingRectHelper(&x, &childRect);
@@ -3615,12 +3575,13 @@ QRectF QGraphicsItem::childrenBoundingRect() const
QRectF QGraphicsItem::sceneBoundingRect() const
{
// Find translate-only offset
+ // COMBINE
QPointF offset;
const QGraphicsItem *parentItem = this;
const QGraphicsItemPrivate *itemd;
do {
itemd = parentItem->d_ptr;
- if (itemd->hasTransform)
+ if (itemd->transformData)
break;
offset += itemd->pos;
} while ((parentItem = itemd->parent));
@@ -4197,7 +4158,7 @@ bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreClipping, bool ignore
// No scene, or if the scene is updating everything, means we have nothing
// to do. The only exception is if the scene tracks the growing scene rect.
return (!visible && !ignoreVisibleBit)
- || (dirty && !ignoreDirtyBit)
+ || (!ignoreDirtyBit && fullUpdatePending)
|| !scene
|| (scene->d_func()->updateAll && scene->d_func()->hasSceneRect)
|| (!ignoreClipping && (childrenClippedToShape() && isClippedAway()))
@@ -4207,141 +4168,6 @@ bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreClipping, bool ignore
/*!
\internal
- Asks the scene to mark this item's scene rect as dirty, requesting a
- redraw. This does not invalidate any cache.
-
- The \a force argument is for the update call in setVisible(), which is the
- only case where the item's background should be marked as dirty even when
- the item isn't visible.
-*/
-void QGraphicsItemPrivate::updateHelper(const QRectF &rect, bool force, bool maybeDirtyClipPath)
-{
- // No scene, or if the scene is updating everything, means we have nothing
- // to do. The only exception is if the scene tracks the growing scene rect.
- if (discardUpdateRequest(/*ignoreClipping=*/maybeDirtyClipPath, /*ignoreVisibleBit=*/force))
- return;
-
- if (rect.isNull())
- dirty = 1;
- scene->itemUpdated(q_ptr, rect);
-}
-
-/*!
- \internal
-
- Propagates updates to \a item and all its children.
-*/
-void QGraphicsItemPrivate::fullUpdateHelper(bool childrenOnly, bool maybeDirtyClipPath, bool ignoreOpacity)
-{
- if (discardUpdateRequest(/*ignoreClipping=*/maybeDirtyClipPath, /*ignoreVisibleBit=*/false,
- /*ignoreDirtyBit=*/true, ignoreOpacity)) {
- return;
- }
-
- if (!childrenOnly && !dirty) {
- // Effectively the same as updateHelper(QRectF(), false, maybeDirtyClipPath).
- dirty = 1;
- scene->itemUpdated(q_ptr, QRectF());
- }
-
- if (dirtyChildren || childrenClippedToShape()) {
- // Unnecessary to update children as well.
- return;
- }
-
- if (ancestorFlags & AncestorClipsChildren) {
- Q_Q(QGraphicsItem);
- // Check if we can avoid updating all children.
- QGraphicsItem *p = parent;
- QRectF br = q->boundingRect();
- while (p) {
- if (p->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape) {
- bool ok;
- QTransform x = q->itemTransform(p, &ok);
- if (!ok)
- break;
- if (x.mapRect(br).contains(p->boundingRect()))
- return;
- }
- p = p->d_ptr->parent;
- if (!p || !(p->d_ptr->ancestorFlags & AncestorClipsChildren))
- break;
- // ### check one level only
- break;
- }
- }
- foreach (QGraphicsItem *child, children)
- child->d_ptr->fullUpdateHelper(false, maybeDirtyClipPath);
- dirtyChildren = 1;
-}
-
-static inline bool allChildrenCombineOpacityHelper(QGraphicsItem *parent)
-{
- Q_ASSERT(parent);
- if (parent->flags() & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)
- return false;
-
- const QList<QGraphicsItem *> children(parent->childItems());
- for (int i = 0; i < children.size(); ++i) {
- if (children.at(i)->flags() & QGraphicsItem::ItemIgnoresParentOpacity)
- return false;
- }
- return true;
-}
-
-void QGraphicsItemPrivate::updateEffectiveOpacity()
-{
- Q_Q(QGraphicsItem);
- if (parent) {
- resolveEffectiveOpacity(parent->effectiveOpacity());
- parent->d_ptr->allChildrenCombineOpacity = allChildrenCombineOpacityHelper(parent);
- } else {
- resolveEffectiveOpacity(1.0);
- }
- allChildrenCombineOpacity = allChildrenCombineOpacityHelper(q);
-}
-
-/*!
- \internal
-
- Resolves and propagates this item's effective opacity to its children.
-*/
-void QGraphicsItemPrivate::resolveEffectiveOpacity(qreal parentEffectiveOpacity)
-{
- Q_Q(QGraphicsItem);
- QGraphicsItem::GraphicsItemFlags myFlags = q->flags();
- QGraphicsItem::GraphicsItemFlags parentFlags = parent ? parent->flags() : QGraphicsItem::GraphicsItemFlags(0);
-
- // My local opacity is always part of my effective opacity.
- qreal myEffectiveOpacity = q->opacity();
-
- // If I have a parent, and I don't ignore my parent's opacity, and my
- // parent propagates to me, then combine my local opacity with my parent's
- // effective opacity into my effective opacity.
- if (parent
- && !(myFlags & QGraphicsItem::ItemIgnoresParentOpacity)
- && !(parentFlags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) {
- myEffectiveOpacity *= parentEffectiveOpacity;
- }
-
- // Set this item's resolved opacity.
- if (qFuzzyIsNull(myEffectiveOpacity - 1)) {
- // Opaque, unset effective opacity.
- hasEffectiveOpacity = 0;
- unsetExtra(ExtraEffectiveOpacity);
- } else {
- hasEffectiveOpacity = 1;
- setExtra(ExtraEffectiveOpacity, myEffectiveOpacity);
- }
-
- // Resolve children always.
- for (int i = 0; i < children.size(); ++i)
- children.at(i)->d_ptr->resolveEffectiveOpacity(myEffectiveOpacity);
-}
-
-/*!
- \internal
-
Resolves the stacking depth of this object and all its children.
*/
void QGraphicsItemPrivate::resolveDepth(int parentDepth)
@@ -4354,22 +4180,9 @@ void QGraphicsItemPrivate::resolveDepth(int parentDepth)
/*!
\internal
*/
-void QGraphicsItemPrivate::invalidateSceneTransformCache()
-{
- if (!scene || (parent && sceneTransformIndex == -1))
- return;
- if (sceneTransformIndex != -1)
- scene->d_func()->validTransforms.setBit(sceneTransformIndex, 0);
- for (int i = 0; i < children.size(); ++i)
- children.at(i)->d_ptr->invalidateSceneTransformCache();
-}
-
-/*!
- \internal
-*/
void QGraphicsItemPrivate::addChild(QGraphicsItem *child)
{
- child->d_ptr->siblingIndex = children.size();
+ needSortChildren = 1;
children.append(child);
}
@@ -4378,14 +4191,7 @@ void QGraphicsItemPrivate::addChild(QGraphicsItem *child)
*/
void QGraphicsItemPrivate::removeChild(QGraphicsItem *child)
{
- int idx = child->d_ptr->siblingIndex;
- int size = children.size();
- for (int i = idx; i < size - 1; ++i) {
- QGraphicsItem *p = children[i + 1];
- children[i] = p;
- p->d_ptr->siblingIndex = i;
- }
- children.removeLast();
+ children.removeOne(child);
}
/*!
@@ -4474,17 +4280,11 @@ void QGraphicsItemPrivate::updateCachedClipPathFromSetPosHelper(const QPointF &n
// Find closest clip ancestor and transform.
Q_Q(QGraphicsItem);
- QTransform thisToParentTransform = hasTransform
- ? q->transform() * QTransform::fromTranslate(newPos.x(), newPos.y())
- : QTransform::fromTranslate(newPos.x(), newPos.y());
+ // COMBINE
+ QTransform thisToParentTransform = transformToParent();
QGraphicsItem *clipParent = parent;
while (clipParent && !(clipParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)) {
- if (clipParent->d_ptr->hasTransform)
- thisToParentTransform *= clipParent->transform();
- if (!clipParent->d_ptr->pos.isNull()) {
- thisToParentTransform *= QTransform::fromTranslate(clipParent->d_ptr->pos.x(),
- clipParent->d_ptr->pos.y());
- }
+ thisToParentTransform *= clipParent->d_ptr->transformToParent();
clipParent = clipParent->d_ptr->parent;
}
@@ -4526,6 +4326,35 @@ void QGraphicsItemPrivate::updateCachedClipPathFromSetPosHelper(const QPointF &n
}
}
+// Traverses all the ancestors up to the top-level and updates the pointer to
+// always point to the top-most item that has a dirty scene transform.
+// It then backtracks to the top-most dirty item and start calculating the
+// scene transform by combining the item's transform (+pos) with the parent's
+// cached scene transform (which we at this point know for sure is valid).
+void QGraphicsItemPrivate::ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem)
+{
+ Q_ASSERT(topMostDirtyItem);
+
+ if (dirtySceneTransform)
+ *topMostDirtyItem = q_ptr;
+
+ if (parent)
+ parent->d_ptr->ensureSceneTransformRecursive(topMostDirtyItem);
+
+ if (*topMostDirtyItem == q_ptr) {
+ if (!dirtySceneTransform)
+ return; // OK, neither my ancestors nor I have dirty scene transforms.
+ *topMostDirtyItem = 0;
+ } else if (*topMostDirtyItem) {
+ return; // Continue backtrack.
+ }
+
+ // COMBINE my transform with the parent's scene transform.
+ sceneTransform = parent ? parent->d_ptr->sceneTransform : QTransform();
+ combineTransformFromParent(&sceneTransform);
+ dirtySceneTransform = 0;
+}
+
/*!
\internal
@@ -4577,16 +4406,12 @@ void QGraphicsItem::update(const QRectF &rect)
}
}
// Only invalidate cache; item is already dirty.
- if (d_ptr->dirty)
+ if (d_ptr->fullUpdatePending)
return;
- } else if (d_ptr->discardUpdateRequest()) {
- return;
}
- // Effectively the same as updateHelper(rect);
- if (rect.isNull())
- d_ptr->dirty = 1;
- d_ptr->scene->itemUpdated(this, rect);
+ if (d_ptr->scene)
+ d_ptr->scene->d_func()->markDirty(this, rect);
}
/*!
@@ -4684,7 +4509,7 @@ void QGraphicsItem::scroll(qreal dx, qreal dy, const QRectF &rect)
exposed -= r.translated(dx, dy);
foreach (QRect rect, exposed.rects())
update(rect);
- d_ptr->updateHelper();
+ d->scene->d_func()->markDirty(this);
} else {
update(rect);
}
@@ -4713,13 +4538,7 @@ void QGraphicsItem::scroll(qreal dx, qreal dy, const QRectF &rect)
static const QLineF left(0, 0, -1, 0);
static const QLineF right(0, 0, 1, 0);
- QTransform deviceTr;
- if (d->itemIsUntransformable()) {
- deviceTr = deviceTransform(view->viewportTransform());
- } else {
- deviceTr = sceneTransform() * view->viewportTransform();
- }
-
+ QTransform deviceTr = deviceTransform(view->viewportTransform());
QRect deviceScrollRect = deviceTr.mapRect(scrollRect).toRect();
QLineF v1 = deviceTr.map(right);
QLineF v2 = deviceTr.map(down);
@@ -4851,9 +4670,10 @@ QPointF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPointF &point
*/
QPointF QGraphicsItem::mapToParent(const QPointF &point) const
{
- if (!d_ptr->hasTransform)
+ // COMBINE
+ if (!d_ptr->transformData)
return point + d_ptr->pos;
- return transform().map(point) + d_ptr->pos;
+ return d_ptr->transformToParent().map(point);
}
/*!
@@ -4918,9 +4738,10 @@ QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QRectF &rect
*/
QPolygonF QGraphicsItem::mapToParent(const QRectF &rect) const
{
- if (!d_ptr->hasTransform)
+ // COMBINE
+ if (!d_ptr->transformData)
return rect.translated(d_ptr->pos);
- return transform().map(rect).translated(d_ptr->pos);
+ return d_ptr->transformToParent().map(rect);
}
/*!
@@ -4987,8 +4808,10 @@ QRectF QGraphicsItem::mapRectToItem(const QGraphicsItem *item, const QRectF &rec
*/
QRectF QGraphicsItem::mapRectToParent(const QRectF &rect) const
{
- QRectF r = !d_ptr->hasTransform ? rect : transform().mapRect(rect);
- return r.translated(d_ptr->pos);
+ // COMBINE
+ if (!d_ptr->transformData)
+ return rect.translated(d_ptr->pos);
+ return d_ptr->transformToParent().mapRect(rect);
}
/*!
@@ -5059,8 +4882,10 @@ QRectF QGraphicsItem::mapRectFromItem(const QGraphicsItem *item, const QRectF &r
*/
QRectF QGraphicsItem::mapRectFromParent(const QRectF &rect) const
{
- QRectF r = rect.translated(-d_ptr->pos);
- return d_ptr->hasTransform ? transform().inverted().mapRect(r) : r;
+ // COMBINE
+ if (!d_ptr->transformData)
+ return rect.translated(-d_ptr->pos);
+ return d_ptr->transformToParent().inverted().mapRect(rect);
}
/*!
@@ -5119,9 +4944,10 @@ QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPolygonF &p
*/
QPolygonF QGraphicsItem::mapToParent(const QPolygonF &polygon) const
{
- if (!d_ptr->hasTransform)
+ // COMBINE
+ if (!d_ptr->transformData)
return polygon.translated(d_ptr->pos);
- return transform().map(polygon).translated(d_ptr->pos);
+ return d_ptr->transformToParent().map(polygon);
}
/*!
@@ -5163,9 +4989,10 @@ QPainterPath QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPainterP
*/
QPainterPath QGraphicsItem::mapToParent(const QPainterPath &path) const
{
- if (!d_ptr->hasTransform)
+ // COMBINE
+ if (!d_ptr->transformData)
return path.translated(d_ptr->pos);
- return transform().map(path).translated(d_ptr->pos);
+ return d_ptr->transformToParent().map(path);
}
/*!
@@ -5214,8 +5041,9 @@ QPointF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPointF &poi
*/
QPointF QGraphicsItem::mapFromParent(const QPointF &point) const
{
- if (d_ptr->hasTransform)
- return transform().inverted().map(point - d_ptr->pos);
+ // COMBINE
+ if (d_ptr->transformData)
+ return d_ptr->transformToParent().inverted().map(point);
return point - d_ptr->pos;
}
@@ -5282,8 +5110,10 @@ QPolygonF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QRectF &re
*/
QPolygonF QGraphicsItem::mapFromParent(const QRectF &rect) const
{
- QRectF r = rect.translated(-d_ptr->pos);
- return d_ptr->hasTransform ? transform().inverted().map(r) : r;
+ // COMBINE
+ if (!d_ptr->transformData)
+ return rect.translated(-d_ptr->pos);
+ return d_ptr->transformToParent().inverted().map(rect);
}
/*!
@@ -5338,9 +5168,10 @@ QPolygonF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPolygonF
*/
QPolygonF QGraphicsItem::mapFromParent(const QPolygonF &polygon) const
{
- QPolygonF p = polygon;
- p.translate(-d_ptr->pos);
- return d_ptr->hasTransform ? transform().inverted().map(p) : p;
+ // COMBINE
+ if (!d_ptr->transformData)
+ return polygon.translated(-d_ptr->pos);
+ return d_ptr->transformToParent().inverted().map(polygon);
}
/*!
@@ -5380,9 +5211,10 @@ QPainterPath QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPainte
*/
QPainterPath QGraphicsItem::mapFromParent(const QPainterPath &path) const
{
- QPainterPath p(path);
- p.translate(-d_ptr->pos);
- return d_ptr->hasTransform ? transform().inverted().map(p) : p;
+ // COMBINE
+ if (!d_ptr->transformData)
+ return path.translated(-d_ptr->pos);
+ return d_ptr->transformToParent().inverted().map(path);
}
/*!
@@ -5900,7 +5732,8 @@ void QGraphicsItem::focusOutEvent(QFocusEvent *event)
void QGraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
Q_UNUSED(event);
- d_ptr->updateHelper();
+ if (d_ptr->scene)
+ d_ptr->scene->d_func()->markDirty(this);
}
/*!
@@ -5928,7 +5761,8 @@ void QGraphicsItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
void QGraphicsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
Q_UNUSED(event);
- d_ptr->updateHelper();
+ if (d_ptr->scene)
+ d_ptr->scene->d_func()->markDirty(this);
}
/*!
@@ -6358,7 +6192,6 @@ void QGraphicsItem::addToIndex()
}
if (d_ptr->scene)
d_ptr->scene->d_func()->addToIndex(this);
- d_ptr->updateHelper();
}
/*!
@@ -6374,7 +6207,6 @@ void QGraphicsItem::removeFromIndex()
// ### remove from child index only if applicable
return;
}
- d_ptr->updateHelper();
if (d_ptr->scene)
d_ptr->scene->d_func()->removeFromIndex(this);
}
@@ -6395,11 +6227,30 @@ void QGraphicsItem::removeFromIndex()
void QGraphicsItem::prepareGeometryChange()
{
if (d_ptr->scene) {
- d_ptr->updateHelper(QRectF(), false, /*maybeDirtyClipPath=*/!d_ptr->inSetPosHelper);
+ d_ptr->geometryChanged = 1;
+ d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
+
QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func();
+ scenePrivate->markDirty(this, QRectF(),
+ /*invalidateChildren=*/true,
+ /*maybeDirtyClipPath=*/!d_ptr->inSetPosHelper);
+
+ // For compatibility reasons, we have to update the item's old geometry
+ // if someone is connected to the changed signal or the scene has no views.
+ // Note that this has to be done *after* markDirty to ensure that
+ // _q_processDirtyItems is called before _q_emitUpdated.
+ if ((scenePrivate->connectedSignals & scenePrivate->changedSignalMask)
+ || scenePrivate->views.isEmpty()) {
+ d_ptr->scene->update(sceneTransform().mapRect(boundingRect()));
+ }
+
scenePrivate->removeFromIndex(this);
}
+ QGraphicsItem *parent = this;
+ while ((parent = parent->d_ptr->parent))
+ parent->d_ptr->dirtyChildrenBoundingRect = 1;
+
if (d_ptr->inSetPosHelper)
return;
@@ -8060,7 +7911,6 @@ void QGraphicsPixmapItem::setTransformationMode(Qt::TransformationMode mode)
{
Q_D(QGraphicsPixmapItem);
if (mode != d->transformationMode) {
- d_ptr->updateHelper();
d->transformationMode = mode;
update();
}
@@ -9442,6 +9292,8 @@ void QGraphicsItemGroup::addToGroup(QGraphicsItem *item)
return;
}
+ // COMBINE
+ // ### Use itemTransform() instead.
QTransform oldSceneMatrix = item->sceneTransform();
item->setPos(mapFromItem(item, 0, 0));
item->setParentItem(this);
@@ -9683,6 +9535,12 @@ QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlag flag)
case QGraphicsItem::ItemUsesExtendedStyleOption:
str = "ItemUsesExtendedStyleOption";
break;
+ case QGraphicsItem::ItemHasNoContents:
+ str = "ItemHasNoContents";
+ break;
+ case QGraphicsItem::ItemSendsGeometryChanges:
+ str = "ItemSendsGeometryChanges";
+ break;
}
debug << str;
return debug;
diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h
index e398dcf..79f7362 100644
--- a/src/gui/graphicsview/qgraphicsitem.h
+++ b/src/gui/graphicsview/qgraphicsitem.h
@@ -95,7 +95,9 @@ public:
ItemIgnoresParentOpacity = 0x40,
ItemDoesntPropagateOpacityToChildren = 0x80,
ItemStacksBehindParent = 0x100,
- ItemUsesExtendedStyleOption = 0x200
+ ItemUsesExtendedStyleOption = 0x200,
+ ItemHasNoContents = 0x400,
+ ItemSendsGeometryChanges = 0x800
// NB! Don't forget to increase the d_ptr->flags bit field by 1 when adding a new flag.
};
Q_DECLARE_FLAGS(GraphicsItemFlags, GraphicsItemFlag)
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index bd81fe5..c502655 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -95,25 +95,12 @@ class Q_AUTOTEST_EXPORT QGraphicsItemPrivate
{
Q_DECLARE_PUBLIC(QGraphicsItem)
public:
- struct TransformData
- {
- TransformData() : rotationX(0),rotationY(0),rotationZ(0),scaleX(1),scaleY(1), dirty(true) {}
- QTransform baseTransform;
- QTransform transform;
- QPointF transformCenter;
- qreal rotationX,rotationY,rotationZ,scaleX,scaleY;
- bool dirty;
- };
enum Extra {
- ExtraTransform,
ExtraToolTip,
ExtraCursor,
ExtraCacheData,
ExtraMaxDeviceCoordCacheSize,
- ExtraBoundingRegionGranularity,
- ExtraOpacity,
- ExtraEffectiveOpacity,
- ExtraDecomposedTransform
+ ExtraBoundingRegionGranularity
};
enum AncestorFlag {
@@ -125,9 +112,10 @@ public:
inline QGraphicsItemPrivate()
: z(0),
+ opacity(1.),
scene(0),
parent(0),
- siblingIndex(-1),
+ transformData(0),
index(-1),
depth(0),
acceptedMouseButtons(0x1f),
@@ -141,13 +129,10 @@ public:
isMemberOfGroup(0),
handlesChildEvents(0),
itemDiscovered(0),
- hasTransform(0),
hasCursor(0),
ancestorFlags(0),
cacheMode(0),
hasBoundingRegionGranularity(0),
- hasOpacity(0),
- hasEffectiveOpacity(0),
isWidget(0),
dirty(0),
dirtyChildren(0),
@@ -155,13 +140,16 @@ public:
dirtyClipPath(1),
emptyClipPath(0),
inSetPosHelper(0),
+ needSortChildren(1),
+ allChildrenDirty(0),
+ fullUpdatePending(0),
flags(0),
- allChildrenCombineOpacity(1),
- hasDecomposedTransform(0),
- dirtyTransform(0),
- dirtyTransformComponents(0),
+ dirtyChildrenBoundingRect(1),
+ paintedViewBoundingRectsNeedRepaint(0),
+ dirtySceneTransform(1),
+ geometryChanged(0),
+ inDestructor(0),
globalStackingOrder(-1),
- sceneTransformIndex(-1),
q_ptr(0)
{
}
@@ -174,26 +162,29 @@ public:
void setIsMemberOfGroup(bool enabled);
void remapItemPos(QEvent *event, QGraphicsItem *item);
QPointF genericMapFromScene(const QPointF &pos, const QWidget *viewport) const;
- bool itemIsUntransformable() const;
+ inline bool itemIsUntransformable() const
+ {
+ return (flags & QGraphicsItem::ItemIgnoresTransformations)
+ || (ancestorFlags & AncestorIgnoresTransformations);
+ }
+ void combineTransformToParent(QTransform *x, const QTransform *viewTransform = 0) const;
+ void combineTransformFromParent(QTransform *x, const QTransform *viewTransform = 0) const;
+
// ### Qt 5: Remove. Workaround for reimplementation added after Qt 4.4.
virtual QVariant inputMethodQueryHelper(Qt::InputMethodQuery query) const;
static bool movableAncestorIsSelected(const QGraphicsItem *item);
void setPosHelper(const QPointF &pos);
+ void setTransformHelper(const QTransform &transform);
void setVisibleHelper(bool newVisible, bool explicitly, bool update = true);
void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true);
bool discardUpdateRequest(bool ignoreClipping = false, bool ignoreVisibleBit = false,
bool ignoreDirtyBit = false, bool ignoreOpacity = false) const;
- void updateHelper(const QRectF &rect = QRectF(), bool force = false, bool maybeDirtyClipPath = false);
- void fullUpdateHelper(bool childrenOnly = false, bool maybeDirtyClipPath = false, bool ignoreOpacity = false);
- void updateEffectiveOpacity();
- void resolveEffectiveOpacity(qreal effectiveParentOpacity);
void resolveDepth(int parentDepth);
- void invalidateSceneTransformCache();
void addChild(QGraphicsItem *child);
void removeChild(QGraphicsItem *child);
- void setParentItemHelper(QGraphicsItem *parent, bool deleting);
+ void setParentItemHelper(QGraphicsItem *parent);
void childrenBoundingRectHelper(QTransform *x, QRectF *rect);
void initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform,
const QRegion &exposedRegion, bool allItems = false) const;
@@ -287,12 +278,67 @@ public:
void invalidateCachedClipPathRecursively(bool childrenOnly = false, const QRectF &emptyIfOutsideThisRect = QRectF());
void updateCachedClipPathFromSetPosHelper(const QPointF &newPos);
+ void ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem);
+
+ inline void invalidateChildrenSceneTransform()
+ {
+ for (int i = 0; i < children.size(); ++i)
+ children.at(i)->d_ptr->dirtySceneTransform = 1;
+ }
+
+ inline qreal calcEffectiveOpacity() const
+ {
+ qreal o = opacity;
+ QGraphicsItem *p = parent;
+ int myFlags = flags;
+ while (p) {
+ int parentFlags = p->d_ptr->flags;
+
+ // If I have a parent, and I don't ignore my parent's opacity, and my
+ // parent propagates to me, then combine my local opacity with my parent's
+ // effective opacity into my effective opacity.
+ if ((myFlags & QGraphicsItem::ItemIgnoresParentOpacity)
+ || (parentFlags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) {
+ break;
+ }
+
+ o *= p->d_ptr->opacity;
+ p = p->d_ptr->parent;
+ myFlags = parentFlags;
+ }
+ return o;
+ }
inline bool isFullyTransparent() const
- { return hasEffectiveOpacity && qFuzzyIsNull(q_func()->effectiveOpacity()); }
+ {
+ if (opacity < 0.001)
+ return true;
+ if (!parent)
+ return false;
+
+ return calcEffectiveOpacity() < 0.001;
+ }
+
+ inline qreal effectiveOpacity() const {
+ if (!parent || !opacity)
+ return opacity;
+
+ return calcEffectiveOpacity();
+ }
inline bool childrenCombineOpacity() const
- { return allChildrenCombineOpacity || children.isEmpty(); }
+ {
+ if (!children.size())
+ return true;
+ if (flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)
+ return false;
+
+ for (int i = 0; i < children.size(); ++i) {
+ if (children.at(i)->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity)
+ return false;
+ }
+ return true;
+ }
inline bool isClippedAway() const
{ return !dirtyClipPath && q_func()->isClipped() && (emptyClipPath || cachedClipPath.isEmpty()); }
@@ -307,13 +353,21 @@ public:
|| (childrenCombineOpacity() && isFullyTransparent());
}
+ inline QTransform transformToParent() const;
+
QPainterPath cachedClipPath;
+ QRectF childrenBoundingRect;
+ QRectF needsRepaint;
+ QMap<QWidget *, QRect> paintedViewBoundingRects;
QPointF pos;
qreal z;
+ qreal opacity;
QGraphicsScene *scene;
QGraphicsItem *parent;
QList<QGraphicsItem *> children;
- int siblingIndex;
+ class TransformData;
+ TransformData *transformData;
+ QTransform sceneTransform;
int index;
int depth;
@@ -329,13 +383,10 @@ public:
quint32 isMemberOfGroup : 1;
quint32 handlesChildEvents : 1;
quint32 itemDiscovered : 1;
- quint32 hasTransform : 1;
quint32 hasCursor : 1;
quint32 ancestorFlags : 3;
quint32 cacheMode : 2;
quint32 hasBoundingRegionGranularity : 1;
- quint32 hasOpacity : 1;
- quint32 hasEffectiveOpacity : 1;
quint32 isWidget : 1;
quint32 dirty : 1;
quint32 dirtyChildren : 1;
@@ -343,89 +394,67 @@ public:
quint32 dirtyClipPath : 1;
quint32 emptyClipPath : 1;
quint32 inSetPosHelper : 1;
+ quint32 needSortChildren : 1;
+ quint32 allChildrenDirty : 1;
+ quint32 fullUpdatePending : 1;
// New 32 bits
- quint32 flags : 10;
- quint32 allChildrenCombineOpacity : 1;
- quint32 hasDecomposedTransform : 1;
- quint32 dirtyTransform : 1;
- quint32 dirtyTransformComponents : 1;
- quint32 padding : 18; // feel free to use
+ quint32 flags : 12;
+ quint32 dirtyChildrenBoundingRect : 1;
+ quint32 paintedViewBoundingRectsNeedRepaint : 1;
+ quint32 dirtySceneTransform : 1;
+ quint32 geometryChanged : 1;
+ quint32 inDestructor : 1;
+ quint32 unused : 15; // feel free to use
// Optional stacking order
int globalStackingOrder;
- int sceneTransformIndex;
+ QGraphicsItem *q_ptr;
+};
- struct DecomposedTransform;
- DecomposedTransform *decomposedTransform() const
+struct QGraphicsItemPrivate::TransformData {
+ QTransform transform;
+ qreal xScale;
+ qreal yScale;
+ qreal xRotation;
+ qreal yRotation;
+ qreal zRotation;
+ qreal horizontalShear;
+ qreal verticalShear;
+ qreal xOrigin;
+ qreal yOrigin;
+
+ TransformData() :
+ xScale(1.0), yScale(1.0), xRotation(0.0), yRotation(0.0), zRotation(0.0),
+ horizontalShear(0.0), verticalShear(0.0), xOrigin(0.0), yOrigin(0.0)
+ {}
+
+ QTransform computedFullTransform() const
{
- QGraphicsItemPrivate *that = const_cast<QGraphicsItemPrivate *>(this);
- DecomposedTransform *decomposed;
- if (hasDecomposedTransform) {
- decomposed = qVariantValue<DecomposedTransform *>(extra(ExtraDecomposedTransform));
- } else {
- decomposed = new DecomposedTransform;
- that->setExtra(ExtraDecomposedTransform, qVariantFromValue<DecomposedTransform *>(decomposed));
- that->hasDecomposedTransform = 1;
- if (!dirtyTransformComponents)
- decomposed->reset();
- }
- if (dirtyTransformComponents) {
- decomposed->initFrom(q_ptr->transform());
- that->dirtyTransformComponents = 0;
- }
- return decomposed;
+ QTransform x;
+ x.translate(xOrigin, yOrigin);
+ x = transform * x;
+ x.rotate(xRotation, Qt::XAxis);
+ x.rotate(yRotation, Qt::YAxis);
+ x.rotate(zRotation, Qt::ZAxis);
+ x.shear(horizontalShear, verticalShear);
+ x.scale(xScale, yScale);
+ x.translate(-xOrigin, -yOrigin);
+ return x;
}
-
- struct DecomposedTransform {
- qreal xScale;
- qreal yScale;
- qreal xRotation;
- qreal yRotation;
- qreal zRotation;
- qreal horizontalShear;
- qreal verticalShear;
- qreal xOrigin;
- qreal yOrigin;
-
- inline void reset()
- {
- xScale = 1.0;
- yScale = 1.0;
- xRotation = 0.0;
- yRotation = 0.0;
- zRotation = 0.0;
- horizontalShear = 0.0;
- verticalShear = 0.0;
- xOrigin = 0.0;
- yOrigin = 0.0;
- }
-
- inline void initFrom(const QTransform &x)
- {
- reset();
- // ### decompose transform
- Q_UNUSED(x);
- }
-
- inline void generateTransform(QTransform *x) const
- {
- x->translate(xOrigin, yOrigin);
- x->rotate(xRotation, Qt::XAxis);
- x->rotate(yRotation, Qt::YAxis);
- x->rotate(zRotation, Qt::ZAxis);
- x->shear(horizontalShear, verticalShear);
- x->scale(xScale, yScale);
- x->translate(-xOrigin, -yOrigin);
- }
- };
-
- QGraphicsItem *q_ptr;
};
-QT_END_NAMESPACE
+/*
+ return the full transform of the item to the parent. This include the position and all the transform data
+*/
+inline QTransform QGraphicsItemPrivate::transformToParent() const
+{
+ QTransform matrix;
+ combineTransformToParent(&matrix);
+ return matrix;
+}
-Q_DECLARE_METATYPE(QGraphicsItemPrivate::DecomposedTransform *)
+QT_END_NAMESPACE
#endif // QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 49c2329..e6c3503 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -39,7 +39,6 @@
**
****************************************************************************/
-static const int QGRAPHICSSCENE_INDEXTIMER_TIMEOUT = 2000;
/*!
\class QGraphicsScene
@@ -250,6 +249,8 @@ static const int QGRAPHICSSCENE_INDEXTIMER_TIMEOUT = 2000;
QT_BEGIN_NAMESPACE
+static inline bool qt_notclosestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2);
+
static inline bool QRectF_intersects(const QRectF &s, const QRectF &r)
{
qreal xp = s.left();
@@ -333,8 +334,9 @@ QGraphicsScenePrivate::QGraphicsScenePrivate()
hasSceneRect(false),
updateAll(false),
calledEmitUpdated(false),
+ processDirtyItemsEmitted(false),
selectionChanging(0),
- dirtyItemResetPending(false),
+ needSortTopLevelItems(true),
regenerateIndex(true),
purgePending(false),
indexTimerId(0),
@@ -412,7 +414,7 @@ QList<QGraphicsItem *> QGraphicsScenePrivate::estimateItemsInRect(const QRectF &
if (QGraphicsItem *item = unindexedItems.at(i)) {
if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
continue;
- if (item->d_ptr->visible && item->effectiveOpacity() > qreal(0.0))
+ if (item->d_ptr->visible && !item->d_ptr->isFullyTransparent())
itemsInRect << item;
}
}
@@ -420,7 +422,7 @@ QList<QGraphicsItem *> QGraphicsScenePrivate::estimateItemsInRect(const QRectF &
if (QGraphicsItem *item = indexedItems.at(i)) {
if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
continue;
- if (item->d_ptr->visible && item->effectiveOpacity() > qreal(0.0))
+ if (item->d_ptr->visible && !item->d_ptr->isFullyTransparent())
itemsInRect << item;
}
}
@@ -598,7 +600,7 @@ void QGraphicsScenePrivate::_q_emitUpdated()
// the optimization that items send updates directly to the views, but it
// needs to happen in order to keep compatibility with the behavior from
// Qt 4.4 and backward.
- if (!views.isEmpty() && (connectedSignals & changedSignalMask)) {
+ if (connectedSignals & changedSignalMask) {
for (int i = 0; i < views.size(); ++i) {
QGraphicsView *view = views.at(i);
if (!view->d_func()->connectedToScene) {
@@ -607,13 +609,13 @@ void QGraphicsScenePrivate::_q_emitUpdated()
views.at(i), SLOT(updateScene(QList<QRectF>)));
}
}
+ } else {
+ updateAll = false;
+ for (int i = 0; i < views.size(); ++i)
+ views.at(i)->d_func()->processPendingUpdates();
+ return;
}
- // Ensure all dirty items's current positions are recorded in the list of
- // updated rects.
- for (int i = 0; i < dirtyItems.size(); ++i)
- updatedRects += dirtyItems.at(i)->sceneBoundingRect();
-
// Notify the changes to anybody interested.
QList<QRectF> oldUpdatedRects;
oldUpdatedRects = updateAll ? (QList<QRectF>() << q->sceneRect()) : updatedRects;
@@ -627,7 +629,7 @@ void QGraphicsScenePrivate::_q_emitUpdated()
*/
void QGraphicsScenePrivate::registerTopLevelItem(QGraphicsItem *item)
{
- item->d_ptr->siblingIndex = topLevelItems.size();
+ needSortTopLevelItems = true;
topLevelItems.append(item);
}
@@ -636,14 +638,7 @@ void QGraphicsScenePrivate::registerTopLevelItem(QGraphicsItem *item)
*/
void QGraphicsScenePrivate::unregisterTopLevelItem(QGraphicsItem *item)
{
- int idx = item->d_ptr->siblingIndex;
- int size = topLevelItems.size();
- for (int i = idx; i < size - 1; ++i) {
- QGraphicsItem *p = topLevelItems[i + 1];
- topLevelItems[i] = p;
- p->d_ptr->siblingIndex = i;
- }
- topLevelItems.removeLast();
+ topLevelItems.removeOne(item);
}
/*!
@@ -678,70 +673,102 @@ void QGraphicsScenePrivate::_q_polishItems()
unpolishedItems.clear();
}
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::_q_resetDirtyItems()
+void QGraphicsScenePrivate::_q_processDirtyItems()
{
- for (int i = 0; i < dirtyItems.size(); ++i) {
- QGraphicsItem *item = dirtyItems.at(i);
- item->d_ptr->dirty = 0;
- item->d_ptr->dirtyChildren = 0;
- }
- dirtyItems.clear();
- dirtyItemResetPending = false;
-}
+ processDirtyItemsEmitted = false;
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::resetDirtyItemsLater()
-{
- Q_Q(QGraphicsScene);
- if (dirtyItemResetPending)
+ const bool wasPendingSceneUpdate = calledEmitUpdated;
+ const QRectF oldGrowingItemsBoundingRect = growingItemsBoundingRect;
+ processDirtyItemsRecursive(0);
+ if (!hasSceneRect && oldGrowingItemsBoundingRect != growingItemsBoundingRect)
+ emit q_func()->sceneRectChanged(growingItemsBoundingRect);
+
+ if (wasPendingSceneUpdate)
return;
- // dirtyItems.reserve(indexedItems.size() + unindexedItems.size());
- dirtyItemResetPending = true;
- QMetaObject::invokeMethod(q, "_q_resetDirtyItems", Qt::QueuedConnection);
+
+ for (int i = 0; i < views.size(); ++i)
+ views.at(i)->d_func()->processPendingUpdates();
+
+ if (calledEmitUpdated) {
+ // We did a compatibility QGraphicsScene::update in processDirtyItemsRecursive
+ // and we cannot wait for the control to reach the eventloop before the
+ // changed signal is emitted, so we emit it now.
+ _q_emitUpdated();
+ }
+
+ // Immediately dispatch all pending update requests on the views.
+ for (int i = 0; i < views.size(); ++i) {
+ QWidget *viewport = views.at(i)->d_func()->viewport;
+ if (qt_widget_private(viewport)->paintOnScreen())
+ QCoreApplication::sendPostedEvents(viewport, QEvent::UpdateRequest);
+ else
+ QCoreApplication::sendPostedEvents(viewport->window(), QEvent::UpdateRequest);
+ }
}
/*!
\internal
Schedules an item for removal. This function leaves some stale indexes
- around in the BSP tree; these will be cleaned up the next time someone
- triggers purgeRemovedItems().
+ around in the BSP tree if called from the item's destructor; these will
+ be cleaned up the next time someone triggers purgeRemovedItems().
- Note: This function is called from QGraphicsItem's destructor. \a item is
+ Note: This function might get called from QGraphicsItem's destructor. \a item is
being destroyed, so we cannot call any pure virtual functions on it (such
as boundingRect()). Also, it is unnecessary to update the item's own state
in any way.
-
- ### Refactoring: This function shares much functionality with removeItem()
*/
-void QGraphicsScenePrivate::_q_removeItemLater(QGraphicsItem *item)
+void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
{
Q_Q(QGraphicsScene);
- // Clear focus on the item to remove any reference in the focusWidget
- // chain.
+ // Clear focus on the item to remove any reference in the focusWidget chain.
item->clearFocus();
-
- int index = item->d_func()->index;
- if (index != -1) {
- // Important: The index is useless until purgeRemovedItems() is
- // called.
- indexedItems[index] = (QGraphicsItem *)0;
- if (!purgePending) {
+ markDirty(item, QRectF(), false, false, false, false, /*removingItemFromScene=*/true);
+
+ if (!item->d_ptr->inDestructor) {
+ // Can potentially call item->boundingRect() (virtual function), that's why
+ // we only can call this function if the item is not in its destructor.
+ removeFromIndex(item);
+ } else if (item->d_ptr->index != -1) {
+ // Important: The index is useless until purgeRemovedItems() is called.
+ indexedItems[item->d_ptr->index] = (QGraphicsItem *)0;
+ if (!purgePending)
purgePending = true;
- q->update();
- }
removedItems << item;
} else {
// Recently added items are purged immediately. unindexedItems() never
// contains stale items.
unindexedItems.removeAll(item);
- q->update();
+ }
+
+ if (!item->d_ptr->inDestructor && item == tabFocusFirst) {
+ QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
+ widget->d_func()->fixFocusChainBeforeReparenting(0, 0);
+ }
+
+ item->d_func()->scene = 0;
+
+ // Remove from parent, or unregister from toplevels.
+ if (QGraphicsItem *parentItem = item->parentItem()) {
+ if (parentItem->scene()) {
+ Q_ASSERT_X(parentItem->scene() == q, "QGraphicsScene::removeItem",
+ "Parent item's scene is different from this item's scene");
+ item->d_ptr->setParentItemHelper(0);
+ }
+ } else {
+ unregisterTopLevelItem(item);
+ }
+
+ if (!item->d_ptr->inDestructor) {
+ // Remove from our item lists.
+ int index = item->d_func()->index;
+ if (index != -1) {
+ freeItemIndexes << index;
+ indexedItems[index] = 0;
+ } else {
+ unindexedItems.removeAll(item);
+ }
}
// Reset the mouse grabber and focus item data.
@@ -761,10 +788,10 @@ void QGraphicsScenePrivate::_q_removeItemLater(QGraphicsItem *item)
// Update selected & hovered item bookkeeping
selectedItems.remove(item);
hoverItems.removeAll(item);
- pendingUpdateItems.removeAll(item);
cachedItemsUnderMouse.removeAll(item);
unpolishedItems.removeAll(item);
- dirtyItems.removeAll(item);
+ pendingUpdateItems.removeAll(item);
+ resetDirtyItem(item);
//We remove all references of item from the sceneEventFilter arrays
QMultiMap<QGraphicsItem*, QGraphicsItem*>::iterator iterator = sceneEventFilters.begin();
@@ -775,20 +802,19 @@ void QGraphicsScenePrivate::_q_removeItemLater(QGraphicsItem *item)
++iterator;
}
- // Remove from scene transform cache
- int transformIndex = item->d_func()->sceneTransformIndex;
- if (transformIndex != -1) {
- validTransforms.setBit(transformIndex, 0);
- freeSceneTransformSlots.append(transformIndex);
+ if (!item->d_ptr->inDestructor) {
+ // Remove all children recursively
+ for (int i = 0; i < item->d_ptr->children.size(); ++i)
+ q->removeItem(item->d_ptr->children.at(i));
}
- // Reset the mouse grabber
+ // Reset the mouse grabber and focus item data.
if (mouseGrabberItems.contains(item))
- ungrabMouse(item, /* item is dying */ true);
+ ungrabMouse(item, /* item is dying */ item->d_ptr->inDestructor);
// Reset the keyboard grabber
if (keyboardGrabberItems.contains(item))
- ungrabKeyboard(item, /* item is dying */ true);
+ ungrabKeyboard(item, /* item is dying */ item->d_ptr->inDestructor);
// Reset the last mouse grabber item
if (item == lastMouseGrabberItem)
@@ -807,8 +833,6 @@ void QGraphicsScenePrivate::_q_removeItemLater(QGraphicsItem *item)
*/
void QGraphicsScenePrivate::purgeRemovedItems()
{
- Q_Q(QGraphicsScene);
-
if (!purgePending && removedItems.isEmpty())
return;
@@ -824,9 +848,6 @@ void QGraphicsScenePrivate::purgeRemovedItems()
freeItemIndexes << i;
}
purgePending = false;
-
- // No locality info for the items; update the whole scene.
- q->update();
}
/*!
@@ -834,13 +855,13 @@ void QGraphicsScenePrivate::purgeRemovedItems()
Starts or restarts the timer used for reindexing unindexed items.
*/
-void QGraphicsScenePrivate::startIndexTimer()
+void QGraphicsScenePrivate::startIndexTimer(int interval)
{
Q_Q(QGraphicsScene);
if (indexTimerId) {
restartIndexTimer = true;
} else {
- indexTimerId = q->startTimer(QGRAPHICSSCENE_INDEXTIMER_TIMEOUT);
+ indexTimerId = q->startTimer(interval);
}
}
@@ -1403,6 +1424,109 @@ QGraphicsWidget *QGraphicsScenePrivate::windowForItem(const QGraphicsItem *item)
return 0;
}
+void QGraphicsScenePrivate::recursive_items_helper(QGraphicsItem *item, QRectF rect,
+ QList<QGraphicsItem *> *items,
+ const QTransform &parentTransform,
+ const QTransform &viewTransform,
+ Qt::ItemSelectionMode mode, Qt::SortOrder order,
+ qreal parentOpacity) const
+{
+ // Calculate opacity.
+ qreal opacity;
+ if (item) {
+ if (!item->d_ptr->visible)
+ return;
+ QGraphicsItem *p = item->d_ptr->parent;
+ bool itemIgnoresParentOpacity = item->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity;
+ bool parentDoesntPropagateOpacity = (p && (p->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren));
+ if (!itemIgnoresParentOpacity && !parentDoesntPropagateOpacity) {
+ opacity = parentOpacity * item->opacity();
+ } else {
+ opacity = item->d_ptr->opacity;
+ }
+ if (opacity == 0.0 && !(item->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren))
+ return;
+ } else {
+ opacity = parentOpacity;
+ }
+
+ // Calculate the full transform for this item.
+ QTransform transform = parentTransform;
+ bool keep = false;
+ if (item) {
+ item->d_ptr->combineTransformFromParent(&transform, &viewTransform);
+
+ // ### This does not take the clip into account.
+ QRectF brect = item->boundingRect();
+ _q_adjustRect(&brect);
+
+ keep = true;
+ if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect)
+ keep = rect.contains(transform.mapRect(brect)) && rect != brect;
+ else
+ keep = rect.intersects(transform.mapRect(brect));
+
+ if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
+ QPainterPath rectPath;
+ rectPath.addRect(rect);
+ keep = itemCollidesWithPath(item, transform.inverted().map(rectPath), mode);
+ }
+ }
+
+ bool childClip = (item && (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape));
+ bool dontProcessItem = !item || !keep;
+ bool dontProcessChildren = item && dontProcessItem && childClip;
+
+ // Find and sort children.
+ QList<QGraphicsItem *> &children = item ? item->d_ptr->children : const_cast<QGraphicsScenePrivate *>(this)->topLevelItems;
+ if (!dontProcessChildren) {
+ if (item && item->d_ptr->needSortChildren) {
+ item->d_ptr->needSortChildren = 0;
+ qStableSort(children.begin(), children.end(), qt_notclosestLeaf);
+ } else if (!item && needSortTopLevelItems) {
+ const_cast<QGraphicsScenePrivate *>(this)->needSortTopLevelItems = false;
+ qStableSort(children.begin(), children.end(), qt_notclosestLeaf);
+ }
+ }
+
+ childClip &= !dontProcessChildren & !children.isEmpty();
+
+ // Clip.
+ if (childClip)
+ rect &= transform.map(item->shape()).controlPointRect();
+
+ // Process children behind
+ int i = 0;
+ if (!dontProcessChildren) {
+ for (i = 0; i < children.size(); ++i) {
+ QGraphicsItem *child = children.at(i);
+ if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent))
+ break;
+ recursive_items_helper(child, rect, items, transform, viewTransform,
+ mode, order, opacity);
+ }
+ }
+
+ // Process item
+ if (!dontProcessItem)
+ items->append(item);
+
+ // Process children in front
+ if (!dontProcessChildren) {
+ for (; i < children.size(); ++i)
+ recursive_items_helper(children.at(i), rect, items, transform, viewTransform,
+ mode, order, opacity);
+ }
+
+ if (!item && order == Qt::AscendingOrder) {
+ int n = items->size();
+ for (int i = 0; i < n / 2; ++i) {
+ QGraphicsItem *tmp = (*items)[n - i - 1];
+ (*items)[n - i - 1] = (*items)[i];
+ (*items)[i] = tmp;
+ }
+ }
+}
QList<QGraphicsItem *> QGraphicsScenePrivate::items_helper(const QPointF &pos) const
{
@@ -1638,7 +1762,7 @@ void QGraphicsScenePrivate::childItems_helper(QList<QGraphicsItem *> *items,
QList<QGraphicsItem *> &children = parent->d_ptr->children;
for (int i = 0; i < children.size(); ++i) {
QGraphicsItem *item = children.at(i);
- if (item->d_ptr->hasTransform && !item->transform().isInvertible())
+ if (item->d_ptr->transformData && !item->d_ptr->transformData->computedFullTransform().isInvertible())
continue;
// Skip invisible items and all their children.
@@ -1678,7 +1802,7 @@ void QGraphicsScenePrivate::childItems_helper(QList<QGraphicsItem *> *items,
QList<QGraphicsItem *> &children = parent->d_ptr->children;
for (int i = 0; i < children.size(); ++i) {
QGraphicsItem *item = children.at(i);
- if (item->d_ptr->hasTransform && !item->transform().isInvertible())
+ if (item->d_ptr->transformData && !item->d_ptr->transformData->computedFullTransform().isInvertible())
continue;
// Skip invisible items and all their children.
@@ -1714,7 +1838,7 @@ void QGraphicsScenePrivate::childItems_helper(QList<QGraphicsItem *> *items,
if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) {
// Recurse into children.
- if (!item->d_ptr->hasTransform || item->transform().type() <= QTransform::TxScale) {
+ if (!item->d_ptr->transformData || item->d_ptr->transformData->computedFullTransform().type() <= QTransform::TxScale) {
// Rect
childItems_helper(items, item, item->mapRectFromParent(rect), mode);
} else {
@@ -1744,7 +1868,7 @@ void QGraphicsScenePrivate::childItems_helper(QList<QGraphicsItem *> *items,
QList<QGraphicsItem *> &children = parent->d_ptr->children;
for (int i = 0; i < children.size(); ++i) {
QGraphicsItem *item = children.at(i);
- if (item->d_ptr->hasTransform && !item->transform().isInvertible())
+ if (item->d_ptr->transformData && !item->d_ptr->transformData->computedFullTransform().isInvertible())
continue;
// Skip invisible items.
@@ -1803,7 +1927,7 @@ void QGraphicsScenePrivate::childItems_helper(QList<QGraphicsItem *> *items,
QList<QGraphicsItem *> &children = parent->d_ptr->children;
for (int i = 0; i < children.size(); ++i) {
QGraphicsItem *item = children.at(i);
- if (item->d_ptr->hasTransform && !item->transform().isInvertible())
+ if (item->d_ptr->transformData && !item->d_ptr->transformData->computedFullTransform().isInvertible())
continue;
// Skip invisible items.
@@ -1867,7 +1991,12 @@ inline bool qt_closestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item
if (f1 != f2) return f2;
qreal z1 = d1->z;
qreal z2 = d2->z;
- return z1 != z2 ? z1 > z2 : d1->siblingIndex > d2->siblingIndex;
+ return z1 > z2;
+}
+
+static inline bool qt_notclosestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2)
+{
+ return qt_closestLeaf(item2, item1);
}
/*!
@@ -2480,7 +2609,6 @@ QList<QGraphicsItem *> QGraphicsScene::items(const QPointF &pos) const
return d->items_helper(pos);
}
-
/*!
\fn QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rectangle, Qt::ItemSelectionMode mode) const
@@ -2497,7 +2625,9 @@ QList<QGraphicsItem *> QGraphicsScene::items(const QPointF &pos) const
QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rect, Qt::ItemSelectionMode mode) const
{
Q_D(const QGraphicsScene);
- return d->items_helper(rect, mode, Qt::AscendingOrder);
+ QList<QGraphicsItem *> itemList;
+ d->recursive_items_helper(0, rect, &itemList, QTransform(), QTransform(), mode, Qt::AscendingOrder);
+ return itemList;
}
/*!
@@ -2896,7 +3026,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
// a temporary list and schedule an indexing for later.
d->unindexedItems << item;
item->d_func()->index = -1;
- d->startIndexTimer();
+ d->startIndexTimer(0);
// Add to list of toplevels if this item is a toplevel.
if (!item->d_ptr->parent)
@@ -3249,108 +3379,7 @@ void QGraphicsScene::removeItem(QGraphicsItem *item)
return;
}
- // If the item has focus, remove it (and any focusWidget reference).
- item->clearFocus();
-
- // Clear its background
- item->update();
-
- // Note: This will access item's sceneBoundingRect(), which (as this is
- // C++) is why we cannot call removeItem() from QGraphicsItem's
- // destructor.
- d->removeFromIndex(item);
-
- if (item == d->tabFocusFirst) {
- QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
- widget->d_func()->fixFocusChainBeforeReparenting(0, 0);
- }
- // Set the item's scene ptr to 0.
- item->d_func()->scene = 0;
-
- // Remove from parent, or unregister from toplevels.
- if (QGraphicsItem *parentItem = item->parentItem()) {
- if (parentItem->scene()) {
- Q_ASSERT_X(parentItem->scene() == this, "QGraphicsScene::removeItem",
- "Parent item's scene is different from this item's scene");
- item->setParentItem(0);
- }
- } else {
- d->unregisterTopLevelItem(item);
- }
-
- // Remove from our item lists.
- int index = item->d_func()->index;
- if (index != -1) {
- d->freeItemIndexes << index;
- d->indexedItems[index] = 0;
- } else {
- d->unindexedItems.removeAll(item);
- }
-
- // Remove from scene transform cache
- int transformIndex = item->d_func()->sceneTransformIndex;
- if (transformIndex != -1) {
- d->validTransforms.setBit(transformIndex, 0);
- d->freeSceneTransformSlots.append(transformIndex);
- item->d_func()->sceneTransformIndex = -1;
- }
-
- if (item == d->focusItem)
- d->focusItem = 0;
- if (item == d->lastFocusItem)
- d->lastFocusItem = 0;
- if (item == d->activeWindow) {
- // ### deactivate...
- d->activeWindow = 0;
- }
-
- // Disable selectionChanged() for individual items
- ++d->selectionChanging;
- int oldSelectedItemsSize = d->selectedItems.size();
-
- // Update selected & hovered item bookkeeping
- d->selectedItems.remove(item);
- d->hoverItems.removeAll(item);
- d->pendingUpdateItems.removeAll(item);
- d->cachedItemsUnderMouse.removeAll(item);
- d->unpolishedItems.removeAll(item);
- d->dirtyItems.removeAll(item);
-
- //We remove all references of item from the sceneEventFilter arrays
- QMultiMap<QGraphicsItem*, QGraphicsItem*>::iterator iterator = d->sceneEventFilters.begin();
- while (iterator != d->sceneEventFilters.end()) {
- if (iterator.value() == item || iterator.key() == item)
- iterator = d->sceneEventFilters.erase(iterator);
- else
- ++iterator;
- }
-
-
- //Ensure dirty flag have the correct default value so the next time it will be added it will receive updates
- item->d_func()->dirty = 0;
- item->d_func()->dirtyChildren = 0;
-
- // Remove all children recursively
- foreach (QGraphicsItem *child, item->children())
- removeItem(child);
-
- // Reset the mouse grabber and focus item data.
- if (d->mouseGrabberItems.contains(item))
- d->ungrabMouse(item);
-
- // Reset the keyboard grabber
- if (d->keyboardGrabberItems.contains(item))
- item->ungrabKeyboard();
-
- // Reset the last mouse grabber item
- if (item == d->lastMouseGrabberItem)
- d->lastMouseGrabberItem = 0;
-
- // Reenable selectionChanged() for individual items
- --d->selectionChanging;
-
- if (!d->selectionChanging && d->selectedItems.size() != oldSelectedItemsSize)
- emit selectionChanged();
+ d->removeItemHelper(item);
// Deliver post-change notification
item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant);
@@ -3653,7 +3682,7 @@ void QGraphicsScene::update(const QRectF &rect)
}
}
- if (!directUpdates && !d->calledEmitUpdated) {
+ if (!d->calledEmitUpdated) {
d->calledEmitUpdated = true;
QMetaObject::invokeMethod(this, "_q_emitUpdated", Qt::QueuedConnection);
}
@@ -3769,6 +3798,8 @@ bool QGraphicsScene::event(QEvent *event)
// items from inside event handlers, this list can quickly end up
// having stale pointers in it. We need to clear it before dispatching
// events that use it.
+ // ### this should only be cleared if we received a new mouse move event,
+ // which relies on us fixing the replay mechanism in QGraphicsView.
d->cachedItemsUnderMouse.clear();
default:
break;
@@ -4802,7 +4833,7 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
// Generate the item's exposedRect and map its list of expose
// rects to device coordinates.
- QStyleOptionGraphicsItem cacheOption = *option;
+ styleOptionTmp = *option;
QRegion pixmapExposed;
QRectF exposedRect;
if (!itemCache->allExposed) {
@@ -4814,11 +4845,11 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
} else {
exposedRect = brect;
}
- cacheOption.exposedRect = exposedRect;
+ styleOptionTmp.exposedRect = exposedRect;
// Render.
_q_paintIntoCache(&pix, item, pixmapExposed, itemToPixmap, painter->renderHints(),
- &cacheOption, painterStateProtection);
+ &styleOptionTmp, painterStateProtection);
// insert this pixmap into the cache.
itemCache->key = QPixmapCache::insert(pix);
@@ -4979,12 +5010,12 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
foreach (QRect r, scrollExposure.rects())
br |= pixmapToItem.mapRect(r);
}
- QStyleOptionGraphicsItem cacheOption = *option;
- cacheOption.exposedRect = br.adjusted(-1, -1, 1, 1);
+ styleOptionTmp = *option;
+ styleOptionTmp.exposedRect = br.adjusted(-1, -1, 1, 1);
// Render the exposed areas.
_q_paintIntoCache(&pix, item, pixmapExposed, itemToPixmap, painter->renderHints(),
- &cacheOption, painterStateProtection);
+ &styleOptionTmp, painterStateProtection);
// Reset expose data.
pixModified = true;
@@ -5013,6 +5044,392 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
}
}
+void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *painter,
+ const QTransform &viewTransform,
+ QRegion *exposedRegion, QWidget *widget,
+ QList<QGraphicsItem *> *topLevelItems,
+ qreal parentOpacity)
+{
+ // Calculate opacity.
+ qreal opacity;
+ bool invisibleButChildIgnoresParentOpacity = false;
+ if (item) {
+ if (!item->d_ptr->visible)
+ return;
+ QGraphicsItem *p = item->d_ptr->parent;
+ bool itemIgnoresParentOpacity = item->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity;
+ bool parentDoesntPropagateOpacity = (p && (p->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren));
+ if (!itemIgnoresParentOpacity && !parentDoesntPropagateOpacity) {
+ opacity = parentOpacity * item->opacity();
+ } else {
+ opacity = item->d_ptr->opacity;
+ }
+ if (opacity == 0.0 && !(item->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) {
+ invisibleButChildIgnoresParentOpacity = !item->d_ptr->childrenCombineOpacity();
+ if (!invisibleButChildIgnoresParentOpacity)
+ return;
+ }
+ } else {
+ opacity = parentOpacity;
+ }
+
+ // Calculate the full transform for this item.
+ QRect viewBoundingRect;
+ bool wasDirtyParentSceneTransform = false;
+ QTransform transform;
+ if (item) {
+ if (item->d_ptr->itemIsUntransformable()) {
+ transform = item->deviceTransform(viewTransform);
+ } else {
+ if (item->d_ptr->dirtySceneTransform) {
+ item->d_ptr->sceneTransform = item->d_ptr->parent ? item->d_ptr->parent->d_ptr->sceneTransform
+ : QTransform();
+ item->d_ptr->combineTransformFromParent(&item->d_ptr->sceneTransform);
+ item->d_ptr->dirtySceneTransform = 0;
+ wasDirtyParentSceneTransform = true;
+ }
+ transform = item->d_ptr->sceneTransform;
+ transform *= viewTransform;
+ }
+
+ QRectF brect = item->boundingRect();
+ // ### This does not take the clip into account.
+ _q_adjustRect(&brect);
+ viewBoundingRect = transform.mapRect(brect).toRect();
+ item->d_ptr->paintedViewBoundingRects.insert(widget, viewBoundingRect);
+ viewBoundingRect.adjust(-1, -1, 1, 1);
+ if (exposedRegion)
+ viewBoundingRect &= exposedRegion->boundingRect();
+ }
+
+ // Find and sort children.
+ QList<QGraphicsItem *> tmp;
+ QList<QGraphicsItem *> *children = 0;
+ if (item) {
+ children = &item->d_ptr->children;
+ } else if (topLevelItems) {
+ children = topLevelItems;
+ } else if (indexMethod == QGraphicsScene::NoIndex || !exposedRegion) {
+ children = &this->topLevelItems;
+ } else {
+ QRectF sceneRect = viewTransform.inverted().mapRect(QRectF(exposedRegion->boundingRect().adjusted(-1, -1, 1, 1)));
+ if (!largestUntransformableItem.isEmpty()) {
+ // ### Nuke this when we move the indexing code into a separate
+ // class. All the largestUntransformableItem code should then go
+ // away, and the estimate function should return untransformable
+ // items as well.
+ QRectF untr = largestUntransformableItem;
+ QRectF ltri = viewTransform.inverted().mapRect(untr);
+ ltri.adjust(-untr.width(), -untr.height(), untr.width(), untr.height());
+ sceneRect.adjust(-ltri.width(), -ltri.height(), ltri.width(), ltri.height());
+ }
+ tmp = estimateItemsInRect(sceneRect);
+
+ QList<QGraphicsItem *> tli;
+ for (int i = 0; i < tmp.size(); ++i)
+ tmp.at(i)->topLevelItem()->d_ptr->itemDiscovered = 1;
+
+ // Sort if the toplevel list is unsorted.
+ if (needSortTopLevelItems) {
+ needSortTopLevelItems = false;
+ qStableSort(this->topLevelItems.begin(),
+ this->topLevelItems.end(), qt_notclosestLeaf);
+ }
+
+ for (int i = 0; i < this->topLevelItems.size(); ++i) {
+ // ### Investigate smarter ways. Looping through all top level
+ // items is not optimal. If the BSP tree is to have maximum
+ // effect, it should be possible to sort the subset of items
+ // quickly. We must use this approach for now, as it's the only
+ // current way to keep the stable sorting order (insertion order).
+ QGraphicsItem *item = this->topLevelItems.at(i);
+ if (item->d_ptr->itemDiscovered) {
+ item->d_ptr->itemDiscovered = 0;
+ tli << item;
+ }
+ }
+
+ tmp = tli;
+ children = &tmp;
+ }
+
+ bool childClip = (item && (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape));
+ bool dontDrawItem = !item || viewBoundingRect.isEmpty();
+ bool dontDrawChildren = item && dontDrawItem && childClip;
+ childClip &= !dontDrawChildren && !children->isEmpty();
+ if (item && ((item->d_ptr->flags & QGraphicsItem::ItemHasNoContents) || invisibleButChildIgnoresParentOpacity))
+ dontDrawItem = true;
+
+ // Clip children.
+ if (childClip) {
+ painter->save();
+ painter->setWorldTransform(transform);
+ painter->setClipPath(item->shape(), Qt::IntersectClip);
+ }
+
+ if (!dontDrawChildren) {
+ if (item && item->d_ptr->needSortChildren) {
+ item->d_ptr->needSortChildren = 0;
+ qStableSort(children->begin(), children->end(), qt_notclosestLeaf);
+ } else if (!item && needSortTopLevelItems && children != &tmp) {
+ needSortTopLevelItems = false;
+ qStableSort(children->begin(), children->end(), qt_notclosestLeaf);
+ }
+ }
+
+ // Draw children behind
+ int i = 0;
+ if (!dontDrawChildren) {
+ // ### Don't visit children that don't ignore parent opacity if this
+ // item is invisible.
+ for (i = 0; i < children->size(); ++i) {
+ QGraphicsItem *child = children->at(i);
+ if (wasDirtyParentSceneTransform)
+ child->d_ptr->dirtySceneTransform = 1;
+ if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent))
+ break;
+ drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget,
+ 0, opacity);
+ }
+ }
+
+ // Draw item
+ if (!dontDrawItem) {
+ item->d_ptr->initStyleOption(&styleOptionTmp, transform, exposedRegion ? *exposedRegion : QRegion(), exposedRegion == 0);
+
+ bool clipsToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsToShape);
+ bool savePainter = clipsToShape || painterStateProtection;
+ if (savePainter)
+ painter->save();
+ if (!childClip)
+ painter->setWorldTransform(transform);
+ if (clipsToShape)
+ painter->setClipPath(item->shape(), Qt::IntersectClip);
+ painter->setOpacity(opacity);
+ drawItemHelper(item, painter, &styleOptionTmp, widget, painterStateProtection);
+
+ if (savePainter)
+ painter->restore();
+ }
+
+ // Draw children in front
+ if (!dontDrawChildren) {
+ // ### Don't visit children that don't ignore parent opacity if this
+ // item is invisible.
+ for (; i < children->size(); ++i) {
+ QGraphicsItem *child = children->at(i);
+ if (wasDirtyParentSceneTransform)
+ child->d_ptr->dirtySceneTransform = 1;
+ drawSubtreeRecursive(child, painter, viewTransform, exposedRegion,
+ widget, 0, opacity);
+ }
+ } else if (wasDirtyParentSceneTransform) {
+ item->d_ptr->invalidateChildrenSceneTransform();
+ }
+
+ // Restore child clip
+ if (childClip)
+ painter->restore();
+}
+
+void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, bool invalidateChildren,
+ bool maybeDirtyClipPath, bool force, bool ignoreOpacity,
+ bool removingItemFromScene)
+{
+ Q_ASSERT(item);
+ if (updateAll)
+ return;
+
+ if (item->d_ptr->discardUpdateRequest(/*ignoreClipping=*/maybeDirtyClipPath,
+ /*ignoreVisibleBit=*/force,
+ /*ignoreDirtyBit=*/removingItemFromScene || invalidateChildren,
+ /*ignoreOpacity=*/ignoreOpacity)) {
+ return;
+ }
+
+ const bool fullItemUpdate = rect.isNull();
+ if (!fullItemUpdate && rect.isEmpty())
+ return;
+
+ if (!processDirtyItemsEmitted) {
+ QMetaObject::invokeMethod(q_ptr, "_q_processDirtyItems", Qt::QueuedConnection);
+ processDirtyItemsEmitted = true;
+ }
+
+ if (removingItemFromScene) {
+ // Note that this function can be called from the item's destructor, so
+ // do NOT call any virtual functions on it within this block.
+ if ((connectedSignals & changedSignalMask) || views.isEmpty()) {
+ // This block of code is kept for compatibility. Since 4.5, by default
+ // QGraphicsView does not connect the signal and we use the below
+ // method of delivering updates.
+ q_func()->update();
+ return;
+ }
+
+ for (int i = 0; i < views.size(); ++i) {
+ QGraphicsViewPrivate *viewPrivate = views.at(i)->d_func();
+ viewPrivate->updateRect(item->d_ptr->paintedViewBoundingRects.value(viewPrivate->viewport));
+ }
+ return;
+ }
+
+ item->d_ptr->dirty = 1;
+ if (fullItemUpdate)
+ item->d_ptr->fullUpdatePending = 1;
+ else if (!item->d_ptr->fullUpdatePending)
+ item->d_ptr->needsRepaint |= rect;
+
+ if (invalidateChildren) {
+ item->d_ptr->allChildrenDirty = 1;
+ item->d_ptr->dirtyChildren = 1;
+ }
+
+ QGraphicsItem *p = item->d_ptr->parent;
+ while (p && !p->d_ptr->dirtyChildren) {
+ p->d_ptr->dirtyChildren = 1;
+ p = p->d_ptr->parent;
+ }
+}
+
+void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren)
+{
+ Q_Q(QGraphicsScene);
+
+ // Calculate the full scene transform for this item.
+ bool wasDirtyParentSceneTransform = false;
+ if (item && item->d_ptr->dirtySceneTransform && !item->d_ptr->itemIsUntransformable()) {
+ item->d_ptr->sceneTransform = item->d_ptr->parent ? item->d_ptr->parent->d_ptr->sceneTransform
+ : QTransform();
+ item->d_ptr->combineTransformFromParent(&item->d_ptr->sceneTransform);
+ item->d_ptr->dirtySceneTransform = 0;
+ wasDirtyParentSceneTransform = true;
+ }
+
+ // Process item.
+ bool wasDirtyParentViewBoundingRects = false;
+ if (item && (item->d_ptr->dirty || item->d_ptr->paintedViewBoundingRectsNeedRepaint)) {
+ const bool useCompatUpdate = views.isEmpty() || (connectedSignals & changedSignalMask);
+ const bool untransformableItem = item->d_ptr->itemIsUntransformable();
+ const QRectF itemBoundingRect = item->boundingRect();
+
+ if (item->d_ptr->geometryChanged) {
+ // Update growingItemsBoundingRect.
+ if (!hasSceneRect) {
+ QRectF itemSceneBoundingRect = item->d_ptr->sceneTransform.mapRect(itemBoundingRect);
+ _q_adjustRect(&itemSceneBoundingRect);
+ growingItemsBoundingRect |= itemSceneBoundingRect;
+ }
+ item->d_ptr->geometryChanged = 0;
+ }
+
+ if (useCompatUpdate && !untransformableItem && qFuzzyIsNull(item->boundingRegionGranularity())) {
+ // This block of code is kept for compatibility. Since 4.5, by default
+ // QGraphicsView does not connect the signal and we use the below
+ // method of delivering updates.
+ q->update(item->d_ptr->sceneTransform.mapRect(itemBoundingRect));
+ } else {
+ QRectF dirtyRect;
+ bool uninitializedDirtyRect = true;
+
+ for (int j = 0; j < views.size(); ++j) {
+ QGraphicsView *view = views.at(j);
+ QGraphicsViewPrivate *viewPrivate = view->d_func();
+ if (viewPrivate->fullUpdatePending)
+ continue;
+ switch (viewPrivate->viewportUpdateMode) {
+ case QGraphicsView::NoViewportUpdate:
+ continue;
+ case QGraphicsView::FullViewportUpdate:
+ view->viewport()->update();
+ viewPrivate->fullUpdatePending = 1;
+ continue;
+ default:
+ break;
+ }
+
+ if (item->d_ptr->paintedViewBoundingRectsNeedRepaint) {
+ wasDirtyParentViewBoundingRects = true;
+ viewPrivate->updateRect(item->d_ptr->paintedViewBoundingRects.value(viewPrivate->viewport));
+ }
+
+ if (!item->d_ptr->dirty)
+ continue;
+
+ if (uninitializedDirtyRect) {
+ dirtyRect = itemBoundingRect;
+ _q_adjustRect(&dirtyRect);
+ if (!item->d_ptr->fullUpdatePending) {
+ _q_adjustRect(&item->d_ptr->needsRepaint);
+ dirtyRect &= item->d_ptr->needsRepaint;
+ }
+ uninitializedDirtyRect = false;
+ }
+
+ if (dirtyRect.isEmpty())
+ continue; // Discard updates outside the bounding rect.
+
+ QTransform deviceTransform = item->d_ptr->sceneTransform;
+ if (view->isTransformed()) {
+ if (!untransformableItem)
+ deviceTransform *= view->viewportTransform();
+ else
+ deviceTransform = item->deviceTransform(view->viewportTransform());
+ }
+ if (item->d_ptr->hasBoundingRegionGranularity)
+ viewPrivate->updateRegion(deviceTransform.map(QRegion(dirtyRect.toRect())));
+ else
+ viewPrivate->updateRect(deviceTransform.mapRect(dirtyRect).toRect());
+ }
+ }
+ }
+
+ // Process root items / children.
+ if (!item || item->d_ptr->dirtyChildren) {
+ QList<QGraphicsItem *> *children = item ? &item->d_ptr->children : &topLevelItems;
+ const bool allChildrenDirty = item && item->d_ptr->allChildrenDirty;
+ if (!dirtyAncestorContainsChildren) {
+ dirtyAncestorContainsChildren = item && item->d_ptr->fullUpdatePending
+ && (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape);
+ }
+ for (int i = 0; i < children->size(); ++i) {
+ QGraphicsItem *child = children->at(i);
+ if (wasDirtyParentSceneTransform)
+ child->d_ptr->dirtySceneTransform = 1;
+ if (wasDirtyParentViewBoundingRects)
+ child->d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
+
+ if (allChildrenDirty) {
+ child->d_ptr->dirty = 1;
+ child->d_ptr->fullUpdatePending = 1;
+ child->d_ptr->dirtyChildren = 1;
+ child->d_ptr->allChildrenDirty = 1;
+ } else if (!child->d_ptr->dirty && !child->d_ptr->dirtyChildren) {
+ resetDirtyItem(child);
+ continue;
+ }
+
+ if (dirtyAncestorContainsChildren || updateAll) {
+ // No need to process this child's dirty rect, hence reset the dirty state.
+ // However, we have to continue the recursion because it might have a dirty
+ // view bounding rect that needs repaint. We also have to reset the dirty
+ // state of its descendants.
+ child->d_ptr->dirty = 0;
+ child->d_ptr->fullUpdatePending = 0;
+ if (updateAll)
+ child->d_ptr->paintedViewBoundingRectsNeedRepaint = 0;
+ }
+
+ processDirtyItemsRecursive(child, dirtyAncestorContainsChildren);
+ }
+ } else if (wasDirtyParentSceneTransform) {
+ item->d_ptr->invalidateChildrenSceneTransform();
+ }
+
+ if (item)
+ resetDirtyItem(item);
+}
+
/*!
Paints the given \a items using the provided \a painter, after the
background has been drawn, and before the foreground has been
@@ -5044,111 +5461,29 @@ void QGraphicsScene::drawItems(QPainter *painter,
const QStyleOptionGraphicsItem options[], QWidget *widget)
{
Q_D(QGraphicsScene);
-
- // Detect if painter state protection is disabled.
QTransform viewTransform = painter->worldTransform();
- QVarLengthArray<QGraphicsItem *, 16> childClippers;
-
- for (int i = 0; i < numItems; ++i) {
- QGraphicsItem *item = items[i];
- if (!(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) {
- if (!childClippers.isEmpty()) {
- // Item is not clipped to any ancestor: pop all current clippers.
- for (int i = 0; i < childClippers.size(); ++i)
- painter->restore();
- childClippers.clear();
- }
- } else {
- // Item is clipped to an ancestor, which may or may not be in our
- // child clipper list. Let's start by finding the item's closest
- // clipping ancestor.
- QGraphicsItem *clipParent = item->parentItem();
- while (clipParent && !(clipParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape))
- clipParent = clipParent->parentItem();
-
- // Pop any in-between clippers. If the clipper is unknown, pop
- // them all. ### QVarLengthArray::lastIndexOf().
- int index = -1;
- for (int n = childClippers.size() - 1; n >= 0; --n) {
- if (childClippers[n] == clipParent) {
- index = n;
- break;
- }
- }
- if (index != -1) {
- int toPop = childClippers.size() - index - 1;
- if (toPop > 0) {
- for (int i = 0; i < toPop; ++i)
- painter->restore();
- childClippers.resize(index + 1);
- }
- }
-
- // Sanity check
- if (!childClippers.isEmpty())
- Q_ASSERT(childClippers[childClippers.size() - 1] == clipParent);
-
- // If the clipper list is empty at this point, but we're still
- // clipped to an ancestor, then we need to build the clip chain
- // ourselves. There is only one case that can produce this issue:
- // This item is stacked behind an ancestor:
- // ItemStacksBehindParent.
- if (childClippers.isEmpty()) {
- Q_ASSERT(clipParent != 0);
- // Build a stack of clippers.
- QVarLengthArray<QGraphicsItem *, 16> clippers;
- QGraphicsItem *p = clipParent;
- do {
- if (p->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)
- clippers.append(p);
- } while ((p = p->parentItem()) && (p->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren));
-
- // ### This code path can also use the itemTransform
- // optimization, but it's hit very rarely.
- for (int i = clippers.size() - 1; i >= 0; --i) {
- QGraphicsItem *clipper = clippers[i];
- painter->setWorldTransform(clipper->deviceTransform(viewTransform), false);
-
- childClippers.append(clipper);
- painter->save();
- painter->setClipPath(clipper->shape(), Qt::IntersectClip);
- }
- Q_ASSERT(childClippers[childClippers.size() - 1] == clipParent);
- }
- }
-
- // Set up the painter transform
- painter->setWorldTransform(item->deviceTransform(viewTransform), false);
+ Q_UNUSED(options);
- // Save painter
- bool saveState = (d->painterStateProtection || (item->flags() & QGraphicsItem::ItemClipsToShape));
- if (saveState)
- painter->save();
-
- // Set local clip
- if (item->flags() & QGraphicsItem::ItemClipsToShape)
- painter->setClipPath(item->shape(), Qt::IntersectClip);
-
- // Setup opacity
- painter->setOpacity(item->effectiveOpacity());
-
- // Draw the item
- d->drawItemHelper(item, painter, &options[i], widget, d->painterStateProtection);
-
- if (saveState)
- painter->restore();
+ // Determine view, expose and flags.
+ QGraphicsView *view = widget ? qobject_cast<QGraphicsView *>(widget->parentWidget()) : 0;
+ QRegion *expose = 0;
+ if (view)
+ expose = &view->d_func()->exposedRegion;
- if (item->flags() & QGraphicsItem::ItemClipsChildrenToShape) {
- // Clip descendents to this item's shape, and keep the painter
- // saved.
- childClippers.append(item);
- painter->save();
- painter->setClipPath(item->shape(), Qt::IntersectClip);
+ // Find all toplevels, they are already sorted.
+ QList<QGraphicsItem *> topLevelItems;
+ for (int i = 0; i < numItems; ++i) {
+ QGraphicsItem *item = items[i]->topLevelItem();
+ if (!item->d_ptr->itemDiscovered) {
+ topLevelItems << item;
+ item->d_ptr->itemDiscovered = 1;
+ d->drawSubtreeRecursive(item, painter, viewTransform, expose, widget);
}
}
- for (int i = 0; i < childClippers.size(); ++i)
- painter->restore();
+ // Reset discovery bits.
+ for (int i = 0; i < topLevelItems.size(); ++i)
+ topLevelItems.at(i)->d_ptr->itemDiscovered = 0;
painter->setWorldTransform(viewTransform);
}
@@ -5260,73 +5595,6 @@ bool QGraphicsScene::focusNextPrevChild(bool next)
*/
/*!
- \internal
-
- This private function is called by QGraphicsItem, which is a friend of
- QGraphicsScene. It is used by QGraphicsScene to record the rectangles that
- need updating. It also launches a single-shot timer to ensure that
- updated() will be emitted later.
-
- The \a item parameter is the item that changed, and \a rect is the
- area of the item that changed given in item coordinates.
-*/
-void QGraphicsScene::itemUpdated(QGraphicsItem *item, const QRectF &rect)
-{
- Q_D(QGraphicsScene);
- // Deliver the actual update.
- if (!d->updateAll) {
- if (d->views.isEmpty() || ((d->connectedSignals & d->changedSignalMask) && !item->d_ptr->itemIsUntransformable()
- && qFuzzyIsNull(item->boundingRegionGranularity()))) {
- // This block of code is kept for compatibility. Since 4.5, by default
- // QGraphicsView does not connect the signal and we use the below
- // method of delivering updates.
- update(item->sceneBoundingRect());
- } else {
- // ### Remove _q_adjustedRects().
- QRectF boundingRect(adjustedItemBoundingRect(item));
- if (!rect.isNull()) {
- QRectF adjustedRect(rect);
- _q_adjustRect(&adjustedRect);
- boundingRect &= adjustedRect;
- }
-
- // Update each view directly.
- for (int i = 0; i < d->views.size(); ++i)
- d->views.at(i)->d_func()->itemUpdated(item, boundingRect);
- }
- }
- if (item->d_ptr->dirty) {
- d->dirtyItems << item;
- d->resetDirtyItemsLater();
- }
-
- if (!item->isVisible())
- return; // Hiding an item won't effect the largestUntransformableItem/sceneRect.
-
- // Update d->largestUntransformableItem by mapping this item's bounding
- // rect back to the topmost untransformable item's untransformed
- // coordinate system (which sort of equals the 1:1 coordinate system of an
- // untransformed view).
- if (item->d_ptr->itemIsUntransformable()) {
- QGraphicsItem *parent = item;
- while (parent && (parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorIgnoresTransformations))
- parent = parent->parentItem();
- d->largestUntransformableItem |= item->mapToItem(parent, item->boundingRect()).boundingRect();
- }
-
- // Only track the automatically growing scene rect if the scene has no
- // defined scene rect.
- if (!d->hasSceneRect) {
- QRectF oldGrowingItemsBoundingRect = d->growingItemsBoundingRect;
- QRectF adjustedItemSceneBoundingRect(item->sceneBoundingRect());
- _q_adjustRect(&adjustedItemSceneBoundingRect);
- d->growingItemsBoundingRect |= adjustedItemSceneBoundingRect;
- if (d->growingItemsBoundingRect != oldGrowingItemsBoundingRect)
- emit sceneRectChanged(d->growingItemsBoundingRect);
- }
-}
-
-/*!
\since 4.4
Returns the scene's style, or the same as QApplication::style() if the
diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h
index 9802f87..c4c9f9c 100644
--- a/src/gui/graphicsview/qgraphicsscene.h
+++ b/src/gui/graphicsview/qgraphicsscene.h
@@ -271,17 +271,14 @@ Q_SIGNALS:
void selectionChanged();
private:
- void itemUpdated(QGraphicsItem *item, const QRectF &rect);
-
Q_DECLARE_PRIVATE(QGraphicsScene)
Q_DISABLE_COPY(QGraphicsScene)
Q_PRIVATE_SLOT(d_func(), void _q_updateIndex())
Q_PRIVATE_SLOT(d_func(), void _q_emitUpdated())
- Q_PRIVATE_SLOT(d_func(), void _q_removeItemLater(QGraphicsItem *item))
Q_PRIVATE_SLOT(d_func(), void _q_updateLater())
Q_PRIVATE_SLOT(d_func(), void _q_polishItems())
Q_PRIVATE_SLOT(d_func(), void _q_updateSortCache())
- Q_PRIVATE_SLOT(d_func(), void _q_resetDirtyItems())
+ Q_PRIVATE_SLOT(d_func(), void _q_processDirtyItems())
friend class QGraphicsItem;
friend class QGraphicsItemPrivate;
friend class QGraphicsView;
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
index 9ace725..11e9b64 100644
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_p.h
@@ -57,6 +57,7 @@
#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+#include "qgraphicsview.h"
#include "qgraphicsscene_bsp_p.h"
#include "qgraphicsitem_p.h"
@@ -68,6 +69,9 @@
#include <QtGui/qfont.h>
#include <QtGui/qpalette.h>
#include <QtGui/qstyle.h>
+#include <QtGui/qstyleoption.h>
+
+static const int QGRAPHICSSCENE_INDEXTIMER_TIMEOUT = 2000;
QT_BEGIN_NAMESPACE
@@ -104,31 +108,30 @@ public:
QList<QRectF> updatedRects;
bool updateAll;
bool calledEmitUpdated;
+ bool processDirtyItemsEmitted;
QPainterPath selectionArea;
int selectionChanging;
QSet<QGraphicsItem *> selectedItems;
QList<QGraphicsItem *> unindexedItems;
QList<QGraphicsItem *> indexedItems;
- QList<QGraphicsItem *> dirtyItems;
QList<QGraphicsItem *> pendingUpdateItems;
QList<QGraphicsItem *> unpolishedItems;
QList<QGraphicsItem *> topLevelItems;
+ bool needSortTopLevelItems;
QMap<QGraphicsItem *, QPointF> movingItemsInitialPositions;
void registerTopLevelItem(QGraphicsItem *item);
void unregisterTopLevelItem(QGraphicsItem *item);
void _q_updateLater();
void _q_polishItems();
- void _q_resetDirtyItems();
- void resetDirtyItemsLater();
- bool dirtyItemResetPending;
+ void _q_processDirtyItems();
QList<int> freeItemIndexes;
bool regenerateIndex;
bool purgePending;
- void _q_removeItemLater(QGraphicsItem *item);
+ void removeItemHelper(QGraphicsItem *item);
QSet<QGraphicsItem *> removedItems;
void purgeRemovedItems();
@@ -137,7 +140,7 @@ public:
int indexTimerId;
bool restartIndexTimer;
- void startIndexTimer();
+ void startIndexTimer(int interval = QGRAPHICSSCENE_INDEXTIMER_TIMEOUT);
bool stickyFocus;
bool hasFocus;
@@ -203,6 +206,10 @@ public:
void mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent);
QGraphicsWidget *windowForItem(const QGraphicsItem *item) const;
+ void recursive_items_helper(QGraphicsItem *item, QRectF rect, QList<QGraphicsItem *> *items,
+ const QTransform &parentTransform, const QTransform &viewTransform,
+ Qt::ItemSelectionMode mode, Qt::SortOrder order, qreal parentOpacity = 1.0) const;
+
QList<QGraphicsItem *> items_helper(const QPointF &pos) const;
QList<QGraphicsItem *> items_helper(const QRectF &rect,
Qt::ItemSelectionMode mode,
@@ -253,6 +260,26 @@ public:
const QStyleOptionGraphicsItem *option, QWidget *widget,
bool painterStateProtection);
+ void drawSubtreeRecursive(QGraphicsItem *item, QPainter *painter, const QTransform &viewTransform,
+ QRegion *exposedRegion, QWidget *widget,
+ QList<QGraphicsItem *> *topLevelItems = 0, qreal parentOpacity = qreal(1.0));
+ void markDirty(QGraphicsItem *item, const QRectF &rect = QRectF(), bool invalidateChildren = false,
+ bool maybeDirtyClipPath = false, bool force = false, bool ignoreOpacity = false,
+ bool removingItemFromScene = false);
+ void processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren = false);
+
+ inline void resetDirtyItem(QGraphicsItem *item)
+ {
+ Q_ASSERT(item);
+ item->d_ptr->dirty = 0;
+ item->d_ptr->paintedViewBoundingRectsNeedRepaint = 0;
+ item->d_ptr->geometryChanged = 0;
+ item->d_ptr->dirtyChildren = 0;
+ item->d_ptr->needsRepaint = QRectF();
+ item->d_ptr->allChildrenDirty = 0;
+ item->d_ptr->fullUpdatePending = 0;
+ }
+
QStyle *style;
QFont font;
void setFont_helper(const QFont &font);
@@ -263,9 +290,7 @@ public:
void resolvePalette();
void updatePalette(const QPalette &palette);
- mutable QVector<QTransform> sceneTransformCache;
- mutable QBitArray validTransforms;
- mutable QVector<int> freeSceneTransformSlots;
+ QStyleOptionGraphicsItem styleOptionTmp;
};
QT_END_NAMESPACE
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index 10b837a..4891e81 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -39,8 +39,6 @@
**
****************************************************************************/
-//#define QGRAPHICSVIEW_DEBUG
-
static const int QGRAPHICSVIEW_REGION_RECT_THRESHOLD = 50;
static const int QGRAPHICSVIEW_PREALLOC_STYLE_OPTIONS = 503; // largest prime < 2^9
@@ -329,8 +327,6 @@ QGraphicsViewPrivate::QGraphicsViewPrivate()
#endif
lastDragDropEvent(0),
fullUpdatePending(true),
- dirtyRectCount(0),
- updatingLater(false),
updateSceneSlotReimplementedChecked(false)
{
styleOptions.reserve(QGRAPHICSVIEW_PREALLOC_STYLE_OPTIONS);
@@ -750,12 +746,13 @@ QRect QGraphicsViewPrivate::mapToViewRect(const QGraphicsItem *item, const QRect
}
// Translate-only
+ // COMBINE
QPointF offset;
const QGraphicsItem *parentItem = item;
const QGraphicsItemPrivate *itemd;
do {
itemd = parentItem->d_ptr;
- if (itemd->hasTransform)
+ if (itemd->transformData)
break;
offset += itemd->pos;
} while ((parentItem = itemd->parent));
@@ -787,7 +784,7 @@ QRegion QGraphicsViewPrivate::mapToViewRegion(const QGraphicsItem *item, const Q
const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
// Accurate bounding region
- QTransform itv = item->sceneTransform() * q->viewportTransform();
+ QTransform itv = item->deviceTransform(q->viewportTransform());
return item->boundingRegion(itv) & itv.mapRect(rect).toAlignedRect();
}
@@ -804,125 +801,28 @@ static inline QRectF adjustedItemBoundingRect(const QGraphicsItem *item)
return boundingRect;
}
-/*!
- \internal
-*/
-void QGraphicsViewPrivate::itemUpdated(QGraphicsItem *item, const QRectF &rect)
-{
- if (fullUpdatePending || viewportUpdateMode == QGraphicsView::NoViewportUpdate)
- return;
- if (item->d_ptr->dirty)
- updateLater();
-
- QRectF updateRect = rect;
- if ((item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape) || item->d_ptr->children.isEmpty()) {
- updateRect &= adjustedItemBoundingRect(item);
- if (updateRect.isEmpty())
- return;
- }
-
- QGraphicsItem *clipItem = item;
- if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
- // Minimize unnecessary redraw.
- QGraphicsItem *parent = item;
- while ((parent = parent->d_ptr->parent)) {
- if (parent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape) {
- // Map update rect to the current parent and itersect with its bounding rect.
- updateRect = clipItem->itemTransform(parent).mapRect(updateRect)
- & adjustedItemBoundingRect(parent);
- if (updateRect.isEmpty())
- return;
- clipItem = parent;
- }
-
- if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren))
- break;
- }
- }
-
- // Map update rect from clipItem coordinates to view coordinates.
- Q_ASSERT(clipItem);
- if (!item->d_ptr->hasBoundingRegionGranularity)
- this->updateRect(mapToViewRect(clipItem, updateRect) & viewport->rect());
- else
- updateRegion(mapToViewRegion(clipItem, updateRect) & viewport->rect());
-}
-
-void QGraphicsViewPrivate::updateLater()
-{
- Q_Q(QGraphicsView);
- if (updatingLater)
- return;
- updatingLater = true;
- QMetaObject::invokeMethod(q, "_q_updateLaterSlot", Qt::QueuedConnection);
-}
-
-void QGraphicsViewPrivate::_q_updateLaterSlot()
+void QGraphicsViewPrivate::processPendingUpdates()
{
- Q_Q(QGraphicsView);
if (!scene)
return;
- QRect vr = viewport->rect();
- QTransform viewTransform = q->viewportTransform();
- const QList<QGraphicsItem *> &dirtyItems = scene->d_func()->dirtyItems;
- for (int i = 0; i < dirtyItems.size(); ++i) {
- const QGraphicsItem *item = dirtyItems.at(i);
- if (item->d_ptr->discardUpdateRequest(/*ignoreClipping=*/false,
- /*ignoreVisibleBit=*/false,
- /*ignoreDirtyBit=*/true)) {
- continue;
- }
- QTransform x = item->sceneTransform() * viewTransform;
- updateRect(x.mapRect(item->boundingRect()).toAlignedRect() & vr);
+ if (fullUpdatePending) { // We have already called viewport->update()
+ dirtyBoundingRect = QRect();
+ dirtyRegion = QRegion();
+ return;
}
- dirtyRectCount += dirtyRects.size();
-
- bool noUpdate = !fullUpdatePending && viewportUpdateMode == QGraphicsView::FullViewportUpdate;
- if ((dirtyRectCount > 0 || !dirtyBoundingRect.isEmpty()) && !fullUpdatePending && !noUpdate) {
- if (viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate
- || (viewportUpdateMode == QGraphicsView::SmartViewportUpdate
- && dirtyRectCount >= QGRAPHICSVIEW_REGION_RECT_THRESHOLD)) {
- if (!(optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)) {
- viewport->update(dirtyBoundingRect.adjusted(-2, -2, 2, 2));
- } else {
- viewport->update(dirtyBoundingRect);
- }
- } else {
- // ### Improve this block, which is very slow for complex regions. We
- // need to strike the balance between having an accurate update
- // region, and running fast. The below approach is the simplest way to
- // create a region from a bunch of rects, but we might want to use
- // other approaches; e.g., a grid of a fixed size representing
- // quadrants of the viewport, which we mark as dirty depending on the
- // rectangles in the list. Perhaps this should go into a
- // QRegion::fromRects(rects, how) function.
- QRegion region;
- if (!(optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)) {
- for (int i = 0; i < dirtyRegions.size(); ++i) {
- QVector<QRect> rects = dirtyRegions.at(i).rects();
- for (int j = 0; j < rects.size(); ++j)
- region += rects.at(j).adjusted(-2, -2, 2, 2);
- }
- for (int i = 0; i < dirtyRects.size(); ++i)
- region += dirtyRects.at(i).adjusted(-2, -2, 2, 2);
- } else {
- for (int i = 0; i < dirtyRegions.size(); ++i)
- region += dirtyRegions.at(i);
- for (int i = 0; i < dirtyRects.size(); ++i)
- region += dirtyRects.at(i);
- }
-
- viewport->update(region);
- }
+ if (viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate) {
+ if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
+ viewport->update(dirtyBoundingRect);
+ else
+ viewport->update(dirtyBoundingRect.adjusted(-2, -2, 2, 2));
+ } else {
+ viewport->update(dirtyRegion); // Already adjusted in updateRect/Region.
}
- dirtyRegions.clear();
- dirtyRects.clear();
- dirtyRectCount = 0;
dirtyBoundingRect = QRect();
- updatingLater = false;
+ dirtyRegion = QRegion();
}
void QGraphicsViewPrivate::updateAll()
@@ -930,14 +830,13 @@ void QGraphicsViewPrivate::updateAll()
Q_Q(QGraphicsView);
q->viewport()->update();
fullUpdatePending = true;
- dirtyRectCount = 0;
dirtyBoundingRect = QRect();
- updatingLater = false;
+ dirtyRegion = QRegion();
}
void QGraphicsViewPrivate::updateRegion(const QRegion &r)
{
- if (r.isEmpty())
+ if (r.isEmpty() || fullUpdatePending)
return;
Q_Q(QGraphicsView);
@@ -950,45 +849,30 @@ void QGraphicsViewPrivate::updateRegion(const QRegion &r)
break;
case QGraphicsView::BoundingRectViewportUpdate:
dirtyBoundingRect |= r.boundingRect();
- if (dirtyBoundingRect == q->viewport()->rect()) {
+ if (dirtyBoundingRect.contains(q->viewport()->rect())) {
fullUpdatePending = true;
q->viewport()->update();
- } else {
- updateLater();
}
break;
- case QGraphicsView::SmartViewportUpdate:
- dirtyBoundingRect |= r.boundingRect();
- if ((dirtyRectCount + r.numRects()) < QGRAPHICSVIEW_REGION_RECT_THRESHOLD)
- dirtyRegions << r;
- dirtyRectCount += r.numRects();
- updateLater();
- break;
+ case QGraphicsView::SmartViewportUpdate: // ### DEPRECATE
case QGraphicsView::MinimalViewportUpdate:
- dirtyRegions << r;
- dirtyRectCount += r.numRects();
- updateLater();
+ if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing) {
+ dirtyRegion += r;
+ } else {
+ const QVector<QRect> &rects = r.rects();
+ for (int i = 0; i < rects.size(); ++i)
+ dirtyRegion += rects.at(i).adjusted(-2, -2, 2, 2);
+ }
break;
case QGraphicsView::NoViewportUpdate:
// Unreachable
break;
}
-
- // Compress the regions...
- if (dirtyRectCount > QGRAPHICSVIEW_REGION_RECT_THRESHOLD && dirtyRegions.size() > 1) {
- QRegion masterRegion;
- for (int i=0; i<dirtyRegions.size(); ++i) {
- masterRegion |= dirtyRegions.at(i);
- }
- dirtyRectCount = masterRegion.numRects();
- dirtyRegions.clear();
- dirtyRegions << masterRegion;
- }
}
void QGraphicsViewPrivate::updateRect(const QRect &r)
{
- if (r.isEmpty())
+ if (r.isEmpty() || fullUpdatePending)
return;
Q_Q(QGraphicsView);
@@ -1001,22 +885,17 @@ void QGraphicsViewPrivate::updateRect(const QRect &r)
break;
case QGraphicsView::BoundingRectViewportUpdate:
dirtyBoundingRect |= r;
- if (dirtyBoundingRect == q->viewport()->rect()) {
+ if (dirtyBoundingRect.contains(q->viewport()->rect())) {
fullUpdatePending = true;
q->viewport()->update();
- } else {
- updateLater();
}
break;
- case QGraphicsView::SmartViewportUpdate:
- dirtyBoundingRect |= r;
- if ((dirtyRectCount + dirtyRects.size()) < QGRAPHICSVIEW_REGION_RECT_THRESHOLD)
- dirtyRects << r;
- updateLater();
- break;
+ case QGraphicsView::SmartViewportUpdate: // ### DEPRECATE
case QGraphicsView::MinimalViewportUpdate:
- dirtyRects << r;
- updateLater();
+ if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
+ dirtyRegion += r;
+ else
+ dirtyRegion += r.adjusted(-2, -2, 2, 2);
break;
case QGraphicsView::NoViewportUpdate:
// Unreachable
@@ -2613,9 +2492,11 @@ void QGraphicsView::updateScene(const QList<QRectF> &rects)
// Extract and reset dirty scene rect info.
QVector<QRect> dirtyViewportRects;
- for (int i = 0; i < d->dirtyRegions.size(); ++i)
- dirtyViewportRects += d->dirtyRegions.at(i).rects();
- d->dirtyRegions.clear();
+ const QVector<QRect> &dirtyRects = d->dirtyRegion.rects();
+ for (int i = 0; i < dirtyRects.size(); ++i)
+ dirtyViewportRects += dirtyRects.at(i);
+ d->dirtyRegion = QRegion();
+ d->dirtyBoundingRect = QRect();
bool fullUpdate = !d->accelerateScrolling || d->viewportUpdateMode == QGraphicsView::FullViewportUpdate;
bool boundingRectUpdate = (d->viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate)
@@ -3355,12 +3236,12 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
d->scene->d_func()->painterStateProtection = !(d->optimizationFlags & DontSavePainterState);
// Determine the exposed region
- QRegion exposedRegion = event->region();
+ d->exposedRegion = event->region();
if (!d->accelerateScrolling)
- exposedRegion = viewport()->rect();
+ d->exposedRegion = viewport()->rect();
else if (d->viewportUpdateMode == BoundingRectViewportUpdate)
- exposedRegion = event->rect();
- QRectF exposedSceneRect = mapToScene(exposedRegion.boundingRect()).boundingRect();
+ d->exposedRegion = event->rect();
+ QRectF exposedSceneRect = mapToScene(d->exposedRegion.boundingRect()).boundingRect();
// Set up the painter
QPainter painter(viewport());
@@ -3377,20 +3258,7 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
const QTransform viewTransform = viewportTransform();
painter.setTransform(viewTransform, true);
-#ifdef QGRAPHICSVIEW_DEBUG
- QTime stopWatch;
- stopWatch.start();
- qDebug() << "QGraphicsView::paintEvent(" << exposedRegion << ')';
-#endif
-
- // Find all exposed items
- bool allItems = false;
- QList<QGraphicsItem *> itemList = d->findItems(exposedRegion, &allItems);
-
-#ifdef QGRAPHICSVIEW_DEBUG
- int exposedTime = stopWatch.elapsed();
-#endif
-
+ // Draw background
if ((d->cacheMode & CacheBackground)
#ifdef Q_WS_X11
&& X11->use_xrender
@@ -3432,33 +3300,31 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
painter.restore();
}
-#ifdef QGRAPHICSVIEW_DEBUG
- int backgroundTime = stopWatch.elapsed() - exposedTime;
-#endif
-
- if (!itemList.isEmpty()) {
- // Generate the style options.
- const int numItems = itemList.size();
- QGraphicsItem **itemArray = &itemList[0]; // Relies on QList internals, but is perfectly valid.
- QStyleOptionGraphicsItem *styleOptionArray = d->allocStyleOptionsArray(numItems);
- for (int i = 0; i < numItems; ++i)
- itemArray[i]->d_ptr->initStyleOption(&styleOptionArray[i], viewTransform, exposedRegion, allItems);
- // Draw the items.
- drawItems(&painter, numItems, itemArray, styleOptionArray);
- d->freeStyleOptionsArray(styleOptionArray);
+ // Items
+ if (!(d->optimizationFlags & IndirectPainting)) {
+ d->scene->d_func()->drawSubtreeRecursive(0, &painter, viewTransform, &d->exposedRegion,
+ viewport(), 0);
+ } else {
+ // Find all exposed items
+ bool allItems = false;
+ QList<QGraphicsItem *> itemList = d->findItems(d->exposedRegion, &allItems);
+
+ if (!itemList.isEmpty()) {
+ // Generate the style options.
+ const int numItems = itemList.size();
+ QGraphicsItem **itemArray = &itemList[0]; // Relies on QList internals, but is perfectly valid.
+ QStyleOptionGraphicsItem *styleOptionArray = d->allocStyleOptionsArray(numItems);
+ for (int i = 0; i < numItems; ++i)
+ itemArray[i]->d_ptr->initStyleOption(&styleOptionArray[i], viewTransform, d->exposedRegion, allItems);
+ // Draw the items.
+ drawItems(&painter, numItems, itemArray, styleOptionArray);
+ d->freeStyleOptionsArray(styleOptionArray);
+ }
}
-#ifdef QGRAPHICSVIEW_DEBUG
- int itemsTime = stopWatch.elapsed() - exposedTime - backgroundTime;
-#endif
-
// Foreground
drawForeground(&painter, exposedSceneRect);
-#ifdef QGRAPHICSVIEW_DEBUG
- int foregroundTime = stopWatch.elapsed() - exposedTime - backgroundTime - itemsTime;
-#endif
-
#ifndef QT_NO_RUBBERBAND
// Rubberband
if (d->rubberBanding && !d->rubberBandRect.isEmpty()) {
@@ -3480,17 +3346,6 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
painter.end();
-#ifdef QGRAPHICSVIEW_DEBUG
- qDebug() << "\tItem discovery....... " << exposedTime << "msecs (" << itemList.size() << "items,"
- << (exposedTime > 0 ? (itemList.size() * 1000.0 / exposedTime) : -1) << "/ sec )";
- qDebug() << "\tDrawing background... " << backgroundTime << "msecs (" << exposedRegion.numRects() << "segments )";
- qDebug() << "\tDrawing items........ " << itemsTime << "msecs ("
- << (itemsTime > 0 ? (itemList.size() * 1000.0 / itemsTime) : -1) << "/ sec )";
- qDebug() << "\tDrawing foreground... " << foregroundTime << "msecs (" << exposedRegion.numRects() << "segments )";
- qDebug() << "\tTotal rendering time: " << stopWatch.elapsed() << "msecs ("
- << (stopWatch.elapsed() > 0 ? (1000.0 / stopWatch.elapsed()) : -1.0) << "fps )";
-#endif
-
// Restore painter state protection.
d->scene->d_func()->painterStateProtection = true;
}
@@ -3537,10 +3392,7 @@ void QGraphicsView::scrollContentsBy(int dx, int dy)
if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate) {
if (d->viewportUpdateMode != QGraphicsView::FullViewportUpdate) {
- for (int i = 0; i < d->dirtyRects.size(); ++i)
- d->dirtyRects[i].translate(dx, dy);
- for (int i = 0; i < d->dirtyRegions.size(); ++i)
- d->dirtyRegions[i].translate(dx, dy);
+ d->dirtyRegion.translate(dx, dy);
if (d->accelerateScrolling) {
#ifndef QT_NO_RUBBERBAND
// Update new and old rubberband regions
@@ -3674,8 +3526,10 @@ void QGraphicsView::drawItems(QPainter *painter, int numItems,
const QStyleOptionGraphicsItem options[])
{
Q_D(QGraphicsView);
- if (d->scene)
- d->scene->drawItems(painter, numItems, items, options, viewport());
+ if (d->scene) {
+ QWidget *widget = painter->device() == viewport() ? viewport() : 0;
+ d->scene->drawItems(painter, numItems, items, options, widget);
+ }
}
/*!
@@ -3704,6 +3558,18 @@ QTransform QGraphicsView::viewportTransform() const
}
/*!
+ Returns true if the view is transformed (i.e., a non-identity transform
+ has been assigned, or the scrollbars are adjusted).
+
+ \sa setTransform(), horizontalScrollBar(), verticalScrollBar()
+*/
+bool QGraphicsView::isTransformed() const
+{
+ Q_D(const QGraphicsView);
+ return !d->identityMatrix || d->horizontalScroll() || d->verticalScroll();
+}
+
+/*!
Sets the view's current transformation matrix to \a matrix.
If \a combine is true, then \a matrix is combined with the current matrix;
diff --git a/src/gui/graphicsview/qgraphicsview.h b/src/gui/graphicsview/qgraphicsview.h
index c3ea6e5..387fa01 100644
--- a/src/gui/graphicsview/qgraphicsview.h
+++ b/src/gui/graphicsview/qgraphicsview.h
@@ -112,7 +112,8 @@ public:
enum OptimizationFlag {
DontClipPainter = 0x1, // obsolete
DontSavePainterState = 0x2,
- DontAdjustForAntialiasing = 0x4
+ DontAdjustForAntialiasing = 0x4,
+ IndirectPainting = 0x8
};
Q_DECLARE_FLAGS(OptimizationFlags, OptimizationFlag)
@@ -169,6 +170,7 @@ public:
void resetMatrix();
QTransform transform() const;
QTransform viewportTransform() const;
+ bool isTransformed() const;
void setTransform(const QTransform &matrix, bool combine = false);
void resetTransform();
void rotate(qreal angle);
@@ -273,7 +275,6 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_setViewportCursor(const QCursor &))
Q_PRIVATE_SLOT(d_func(), void _q_unsetViewportCursor())
#endif
- Q_PRIVATE_SLOT(d_func(), void _q_updateLaterSlot())
friend class QGraphicsSceneWidget;
friend class QGraphicsScene;
friend class QGraphicsScenePrivate;
diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h
index c18f85d..814e476 100644
--- a/src/gui/graphicsview/qgraphicsview_p.h
+++ b/src/gui/graphicsview/qgraphicsview_p.h
@@ -159,19 +159,15 @@ public:
QRect mapToViewRect(const QGraphicsItem *item, const QRectF &rect) const;
QRegion mapToViewRegion(const QGraphicsItem *item, const QRectF &rect) const;
- void itemUpdated(QGraphicsItem *item, const QRectF &rect);
bool fullUpdatePending;
- QList<QRect> dirtyRects;
- QList<QRegion> dirtyRegions;
- int dirtyRectCount;
+ QRegion dirtyRegion;
QRect dirtyBoundingRect;
- void updateLater();
- bool updatingLater;
- void _q_updateLaterSlot();
+ void processPendingUpdates();
void updateAll();
void updateRect(const QRect &rect);
void updateRegion(const QRegion &region);
bool updateSceneSlotReimplementedChecked;
+ QRegion exposedRegion;
QList<QGraphicsItem *> findItems(const QRegion &exposedRegion, bool *allItems) const;
};
diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp
index 8d6d880..4d0da2f 100644
--- a/src/gui/graphicsview/qgraphicswidget.cpp
+++ b/src/gui/graphicsview/qgraphicswidget.cpp
@@ -1099,6 +1099,9 @@ void QGraphicsWidget::updateGeometry()
ItemParentChange both to deliver \l ParentChange events, and for managing
the focus chain.
+ QGraphicsWidget enables the ItemSendsGeometryChanges flag by default in
+ order to track position changes.
+
\sa propertyChange()
*/
QVariant QGraphicsWidget::itemChange(GraphicsItemChange change, const QVariant &value)
diff --git a/src/gui/graphicsview/qgraphicswidget_p.cpp b/src/gui/graphicsview/qgraphicswidget_p.cpp
index a435758..557b883 100644
--- a/src/gui/graphicsview/qgraphicswidget_p.cpp
+++ b/src/gui/graphicsview/qgraphicswidget_p.cpp
@@ -77,7 +77,9 @@ void QGraphicsWidgetPrivate::init(QGraphicsItem *parentItem, Qt::WindowFlags wFl
resolveLayoutDirection();
q->unsetWindowFrameMargins();
q->setFlag(QGraphicsItem::ItemUsesExtendedStyleOption);
+ q->setFlag(QGraphicsItem::ItemSendsGeometryChanges);
}
+
qreal QGraphicsWidgetPrivate::titleBarHeight(const QStyleOptionTitleBar &options) const
{
Q_Q(const QGraphicsWidget);
diff --git a/src/gui/image/qpicture_p.h b/src/gui/image/qpicture_p.h
index a3fd34f..3e8391f 100644
--- a/src/gui/image/qpicture_p.h
+++ b/src/gui/image/qpicture_p.h
@@ -69,7 +69,7 @@ class QPaintEngine;
extern const char *qt_mfhdr_tag;
-class Q_GUI_EXPORT QPicturePrivate
+class QPicturePrivate
{
Q_DECLARE_PUBLIC(QPicture)
friend class QPicturePaintEngine;
diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp
index c90216b..d353c2d 100644
--- a/src/gui/itemviews/qabstractitemview.cpp
+++ b/src/gui/itemviews/qabstractitemview.cpp
@@ -2398,8 +2398,8 @@ void QAbstractItemView::updateEditorGeometries()
//we release the editor outside of the loop because it might change the focus and try
//to change the d->editors list.
- foreach(QWidget *editor, editorsToRelease) {
- d->releaseEditor(editor);
+ for (int i = 0; i < editorsToRelease.count(); ++i) {
+ d->releaseEditor(editorsToRelease.at(i));
}
}
diff --git a/src/gui/itemviews/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp
index d28c08a..7ad825a 100644
--- a/src/gui/itemviews/qheaderview.cpp
+++ b/src/gui/itemviews/qheaderview.cpp
@@ -1153,7 +1153,8 @@ void QHeaderView::setResizeMode(ResizeMode mode)
\overload
Sets the constraints on how the section specified by \a logicalIndex in
- the header can be resized to those described by the given \a mode.
+ the header can be resized to those described by the given \a mode. The logical
+ index should exist at the time this function is called.
\note This setting will be ignored for the last section if the stretchLastSection
property is set to true. This is the default for the horizontal headers provided
diff --git a/src/gui/itemviews/qlistwidget.cpp b/src/gui/itemviews/qlistwidget.cpp
index e1e509d..504908f 100644
--- a/src/gui/itemviews/qlistwidget.cpp
+++ b/src/gui/itemviews/qlistwidget.cpp
@@ -687,7 +687,10 @@ QVariant QListWidgetItem::data(int role) const
*/
bool QListWidgetItem::operator<(const QListWidgetItem &other) const
{
- return text() < other.text();
+ const QVariant v1 = data(Qt::DisplayRole), v2 = other.data(Qt::DisplayRole);
+ if (QAbstractItemModelPrivate::canConvertToDouble(v1) && QAbstractItemModelPrivate::canConvertToDouble(v2))
+ return v1.toDouble() < v2.toDouble();
+ return v1.toString() < v2.toString();
}
#ifndef QT_NO_DATASTREAM
diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp
index 96eb6f0..4021c83 100644
--- a/src/gui/itemviews/qsortfilterproxymodel.cpp
+++ b/src/gui/itemviews/qsortfilterproxymodel.cpp
@@ -884,8 +884,8 @@ void QSortFilterProxyModelPrivate::proxy_item_range(
{
proxy_low = INT_MAX;
proxy_high = INT_MIN;
- foreach (int source_item, source_items) {
- int proxy_item = source_to_proxy.at(source_item);
+ for (int i = 0; i < source_items.count(); ++i) {
+ int proxy_item = source_to_proxy.at(source_items.at(i));
Q_ASSERT(proxy_item != -1);
if (proxy_item < proxy_low)
proxy_low = proxy_item;
@@ -985,7 +985,8 @@ QSet<int> QSortFilterProxyModelPrivate::handle_filter_changed(
Q_Q(QSortFilterProxyModel);
// Figure out which mapped items to remove
QVector<int> source_items_remove;
- foreach (int source_item, proxy_to_source) {
+ for (int i = 0; i < proxy_to_source.count(); ++i) {
+ const int source_item = proxy_to_source.at(i);
if ((orient == Qt::Vertical)
? !q->filterAcceptsRow(source_item, source_parent)
: !q->filterAcceptsColumn(source_item, source_parent)) {
diff --git a/src/gui/itemviews/qstandarditemmodel.cpp b/src/gui/itemviews/qstandarditemmodel.cpp
index d8adbd2..9d0f796 100644
--- a/src/gui/itemviews/qstandarditemmodel.cpp
+++ b/src/gui/itemviews/qstandarditemmodel.cpp
@@ -2907,8 +2907,8 @@ QMimeData *QStandardItemModel::mimeData(const QModelIndexList &indexes) const
QStack<QStandardItem*> stack;
itemsSet.reserve(indexes.count());
stack.reserve(indexes.count());
- foreach (const QModelIndex &index, indexes) {
- QStandardItem *item = itemFromIndex(index);
+ for (int i = 0; i < indexes.count(); ++i) {
+ QStandardItem *item = itemFromIndex(indexes.at(i));
itemsSet << item;
stack.push(item);
}
diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp
index 0bded54..454b1f5 100644
--- a/src/gui/itemviews/qtableview.cpp
+++ b/src/gui/itemviews/qtableview.cpp
@@ -1844,14 +1844,14 @@ void QTableView::setSortingEnabled(bool enable)
disconnect(horizontalHeader(), SIGNAL(sectionPressed(int)),
this, SLOT(selectColumn(int)));
connect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
- this, SLOT(sortByColumn(int)));
+ this, SLOT(sortByColumn(int)), Qt::UniqueConnection);
sortByColumn(horizontalHeader()->sortIndicatorSection(),
horizontalHeader()->sortIndicatorOrder());
} else {
connect(d->horizontalHeader, SIGNAL(sectionEntered(int)),
- this, SLOT(_q_selectColumn(int)));
+ this, SLOT(_q_selectColumn(int)), Qt::UniqueConnection);
connect(horizontalHeader(), SIGNAL(sectionPressed(int)),
- this, SLOT(selectColumn(int)));
+ this, SLOT(selectColumn(int)), Qt::UniqueConnection);
disconnect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
this, SLOT(sortByColumn(int)));
}
diff --git a/src/gui/itemviews/qtablewidget.cpp b/src/gui/itemviews/qtablewidget.cpp
index 8cb2e55..072e435 100644
--- a/src/gui/itemviews/qtablewidget.cpp
+++ b/src/gui/itemviews/qtablewidget.cpp
@@ -530,24 +530,6 @@ void QTableModel::sort(int column, Qt::SortOrder order)
emit layoutChanged();
}
-bool QTableModel::canConvertToDouble(const QVariant &value)
-{
- switch (value.type()) {
- case QVariant::Bool:
- case QVariant::Int:
- case QVariant::UInt:
- case QVariant::LongLong:
- case QVariant::ULongLong:
- case QVariant::Double:
- case QVariant::Char:
- return true;
- default:
- return false;
- }
- return false;
-}
-
-
/*
\internal
@@ -1410,7 +1392,7 @@ QVariant QTableWidgetItem::data(int role) const
bool QTableWidgetItem::operator<(const QTableWidgetItem &other) const
{
const QVariant v1 = data(Qt::DisplayRole), v2 = other.data(Qt::DisplayRole);
- if (QTableModel::canConvertToDouble(v1) && QTableModel::canConvertToDouble(v2))
+ if (QAbstractItemModelPrivate::canConvertToDouble(v1) && QAbstractItemModelPrivate::canConvertToDouble(v2))
return v1.toDouble() < v2.toDouble();
return v1.toString() < v2.toString();
}
diff --git a/src/gui/itemviews/qtablewidget_p.h b/src/gui/itemviews/qtablewidget_p.h
index 2e1dab6..d8bfcc5 100644
--- a/src/gui/itemviews/qtablewidget_p.h
+++ b/src/gui/itemviews/qtablewidget_p.h
@@ -144,7 +144,6 @@ public:
const QPair<QTableWidgetItem*,int> &right);
static bool itemGreaterThan(const QPair<QTableWidgetItem*,int> &left,
const QPair<QTableWidgetItem*,int> &right);
- static bool canConvertToDouble(const QVariant &value);
void ensureSorted(int column, Qt::SortOrder order, int start, int end);
QVector<QTableWidgetItem*> columnItems(int column) const;
diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp
index 7837700..9910118 100644
--- a/src/gui/itemviews/qtreeview.cpp
+++ b/src/gui/itemviews/qtreeview.cpp
@@ -238,11 +238,6 @@ void QTreeView::setModel(QAbstractItemModel *model)
connect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
this, SLOT(rowsRemoved(QModelIndex,int,int)));
- connect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
- this, SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int)));
- connect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
- this, SLOT(_q_columnsRemoved(QModelIndex,int,int)));
-
connect(d->model, SIGNAL(modelAboutToBeReset()), SLOT(_q_modelAboutToBeReset()));
if (d->sortingEnabled)
@@ -2072,7 +2067,8 @@ QModelIndex QTreeView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie
const bool useTopIndex = (cursorAction == MoveUp || cursorAction == MovePrevious);
int index = useTopIndex ? INT_MAX : INT_MIN;
const QItemSelection selection = d->selectionModel->selection();
- foreach (const QItemSelectionRange &range, selection) {
+ for (int i = 0; i < selection.count(); ++i) {
+ const QItemSelectionRange &range = selection.at(i);
int candidate = d->viewIndex(useTopIndex ? range.topLeft() : range.bottomRight());
if (candidate >= 0)
index = useTopIndex ? qMin(index, candidate) : qMax(index, candidate);
@@ -3071,16 +3067,16 @@ void QTreeViewPrivate::_q_modelAboutToBeReset()
void QTreeViewPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
{
- Q_UNUSED(parent);
if (start <= 0 && 0 <= end)
viewItems.clear();
+ QAbstractItemViewPrivate::_q_columnsAboutToBeRemoved(parent, start, end);
}
void QTreeViewPrivate::_q_columnsRemoved(const QModelIndex &parent, int start, int end)
{
- Q_UNUSED(parent);
if (start <= 0 && 0 <= end)
doDelayedItemsLayout();
+ QAbstractItemViewPrivate::_q_columnsRemoved(parent, start, end);
}
void QTreeViewPrivate::layout(int i)
@@ -3558,7 +3554,8 @@ QList<QPair<int, int> > QTreeViewPrivate::columnRanges(const QModelIndex &topInd
QPair<int, int> current;
current.first = -2; // -1 is not enough because -1+1 = 0
current.second = -2;
- foreach (int logicalColumn, logicalIndexes) {
+ for(int i = 0; i < logicalIndexes.count(); ++i) {
+ const int logicalColumn = logicalIndexes.at(i);
if (current.second + 1 != logicalColumn) {
if (current.first != -2) {
//let's save the current one
diff --git a/src/gui/itemviews/qtreewidget.cpp b/src/gui/itemviews/qtreewidget.cpp
index 1c87580..5604f8d 100644
--- a/src/gui/itemviews/qtreewidget.cpp
+++ b/src/gui/itemviews/qtreewidget.cpp
@@ -695,29 +695,6 @@ bool QTreeModel::itemGreaterThan(const QPair<QTreeWidgetItem*,int> &left,
}
/*!
- \internal
-
- Returns true if the type of the variant \a value
- can be casted as double.
-*/
-bool QTreeModel::canConvertToDouble(const QVariant &value)
-{
- switch (value.type()) {
- case QVariant::Bool:
- case QVariant::Int:
- case QVariant::UInt:
- case QVariant::LongLong:
- case QVariant::ULongLong:
- case QVariant::Double:
- case QVariant::Char:
- return true;
- default:
- return false;
- }
- return false;
-}
-
-/*!
\internal
*/
QList<QTreeWidgetItem*>::iterator QTreeModel::sortedInsertionIterator(
@@ -1812,7 +1789,7 @@ bool QTreeWidgetItem::operator<(const QTreeWidgetItem &other) const
int column = view ? view->sortColumn() : 0;
const QVariant v1 = data(column, Qt::DisplayRole);
const QVariant v2 = other.data(column, Qt::DisplayRole);
- if (QTreeModel::canConvertToDouble(v1) && QTreeModel::canConvertToDouble(v2))
+ if (QAbstractItemModelPrivate::canConvertToDouble(v1) && QAbstractItemModelPrivate::canConvertToDouble(v2))
return v1.toDouble() < v2.toDouble();
return v1.toString() < v2.toString();
}
diff --git a/src/gui/itemviews/qtreewidget_p.h b/src/gui/itemviews/qtreewidget_p.h
index 96f734d..a089cf5 100644
--- a/src/gui/itemviews/qtreewidget_p.h
+++ b/src/gui/itemviews/qtreewidget_p.h
@@ -116,7 +116,6 @@ public:
const QPair<QTreeWidgetItem*,int> &right);
static bool itemGreaterThan(const QPair<QTreeWidgetItem*,int> &left,
const QPair<QTreeWidgetItem*,int> &right);
- static bool canConvertToDouble(const QVariant &value);
static QList<QTreeWidgetItem*>::iterator sortedInsertionIterator(
const QList<QTreeWidgetItem*>::iterator &begin,
const QList<QTreeWidgetItem*>::iterator &end,
diff --git a/src/gui/kernel/qaction.cpp b/src/gui/kernel/qaction.cpp
index 051b6a6..f44d207 100644
--- a/src/gui/kernel/qaction.cpp
+++ b/src/gui/kernel/qaction.cpp
@@ -136,25 +136,31 @@ void QActionPrivate::redoGrab(QShortcutMap &map)
void QActionPrivate::redoGrabAlternate(QShortcutMap &map)
{
Q_Q(QAction);
- foreach (int id, alternateShortcutIds)
- if (id)
+ for(int i = 0; i < alternateShortcutIds.count(); ++i) {
+ if (const int id = alternateShortcutIds.at(i))
map.removeShortcut(id, q);
+ }
alternateShortcutIds.clear();
if (alternateShortcuts.isEmpty())
return;
- foreach (const QKeySequence& alternate, alternateShortcuts) {
+ for(int i = 0; i < alternateShortcuts.count(); ++i) {
+ const QKeySequence& alternate = alternateShortcuts.at(i);
if (!alternate.isEmpty())
alternateShortcutIds.append(map.addShortcut(q, alternate, shortcutContext));
else
alternateShortcutIds.append(0);
}
if (!enabled) {
- foreach (int id, alternateShortcutIds)
+ for(int i = 0; i < alternateShortcutIds.count(); ++i) {
+ const int id = alternateShortcutIds.at(i);
map.setShortcutEnabled(false, id, q);
+ }
}
if (!autorepeat) {
- foreach (int id, alternateShortcutIds)
+ for(int i = 0; i < alternateShortcutIds.count(); ++i) {
+ const int id = alternateShortcutIds.at(i);
map.setShortcutAutoRepeat(false, id, q);
+ }
}
}
@@ -163,9 +169,10 @@ void QActionPrivate::setShortcutEnabled(bool enable, QShortcutMap &map)
Q_Q(QAction);
if (shortcutId)
map.setShortcutEnabled(enable, shortcutId, q);
- foreach (int id, alternateShortcutIds)
- if (id)
+ for(int i = 0; i < alternateShortcutIds.count(); ++i) {
+ if (const int id = alternateShortcutIds.at(i))
map.setShortcutEnabled(enable, id, q);
+ }
}
#endif // QT_NO_SHORTCUT
@@ -615,8 +622,10 @@ QAction::~QAction()
#ifndef QT_NO_SHORTCUT
if (d->shortcutId && qApp) {
qApp->d_func()->shortcutMap.removeShortcut(d->shortcutId, this);
- foreach (int id, d->alternateShortcutIds)
+ for(int i = 0; i < d->alternateShortcutIds.count(); ++i) {
+ const int id = d->alternateShortcutIds.at(i);
qApp->d_func()->shortcutMap.removeShortcut(id, this);
+ }
}
#endif
}
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
index 1473421..8ebea19 100644
--- a/src/gui/kernel/qapplication_x11.cpp
+++ b/src/gui/kernel/qapplication_x11.cpp
@@ -157,6 +157,8 @@ static const char * x11_atomnames = {
"WM_TAKE_FOCUS\0"
"_NET_WM_PING\0"
"_NET_WM_CONTEXT_HELP\0"
+ "_NET_WM_SYNC_REQUEST\0"
+ "_NET_WM_SYNC_REQUEST_COUNTER\0"
// ICCCM window state
"WM_STATE\0"
@@ -508,6 +510,7 @@ static Bool qt_xfixes_scanner(Display*, XEvent *event, XPointer arg)
class QETWidget : public QWidget // event translator widget
{
public:
+ QWidgetPrivate* d_func() { return QWidget::d_func(); }
bool translateMouseEvent(const XEvent *);
void translatePaintEvent(const XEvent *);
bool translateConfigEvent(const XEvent *);
@@ -718,6 +721,44 @@ static int qt_xio_errhandler(Display *)
}
#endif
+#ifndef QT_NO_XSYNC
+struct qt_sync_request_event_data
+{
+ WId window;
+};
+
+#if defined(Q_C_CALLBACKS)
+extern "C" {
+#endif
+
+static Bool qt_sync_request_scanner(Display*, XEvent *event, XPointer arg)
+{
+ qt_sync_request_event_data *data =
+ reinterpret_cast<qt_sync_request_event_data*>(arg);
+ if (event->type == ClientMessage &&
+ event->xany.window == data->window &&
+ event->xclient.message_type == ATOM(WM_PROTOCOLS) &&
+ (Atom)event->xclient.data.l[0] == ATOM(_NET_WM_SYNC_REQUEST)) {
+ QWidget *w = QWidget::find(event->xany.window);
+ if (QTLWExtra *tlw = ((QETWidget*)w)->d_func()->maybeTopData()) {
+ const ulong timestamp = (const ulong) event->xclient.data.l[1];
+ if (timestamp > X11->time)
+ X11->time = timestamp;
+ if (timestamp == CurrentTime || timestamp > tlw->syncRequestTimestamp) {
+ tlw->syncRequestTimestamp = timestamp;
+ tlw->newCounterValueLo = event->xclient.data.l[2];
+ tlw->newCounterValueHi = event->xclient.data.l[3];
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+#if defined(Q_C_CALLBACKS)
+}
+#endif
+#endif // QT_NO_XSYNC
static void qt_x11_create_intern_atoms()
{
@@ -2090,6 +2131,13 @@ void qt_init(QApplicationPrivate *priv, int,
#endif // QT_RUNTIME_XCURSOR
#endif // QT_NO_XCURSOR
+#ifndef QT_NO_XSYNC
+ int xsync_evbase, xsync_errbase;
+ int major, minor;
+ if (XSyncQueryExtension(X11->display, &xsync_evbase, &xsync_errbase))
+ XSyncInitialize(X11->display, &major, &minor);
+#endif // QT_NO_XSYNC
+
#ifndef QT_NO_XINERAMA
#ifdef QT_RUNTIME_XINERAMA
X11->ptrXineramaQueryExtension = 0;
@@ -3116,6 +3164,19 @@ int QApplication::x11ClientMessage(QWidget* w, XEvent* event, bool passive_only)
XSendEvent(event->xclient.display, event->xclient.window,
False, SubstructureNotifyMask|SubstructureRedirectMask, event);
}
+#ifndef QT_NO_XSYNC
+ } else if (a == ATOM(_NET_WM_SYNC_REQUEST)) {
+ const ulong timestamp = (const ulong) event->xclient.data.l[1];
+ if (timestamp > X11->time)
+ X11->time = timestamp;
+ if (QTLWExtra *tlw = w->d_func()->maybeTopData()) {
+ if (timestamp == CurrentTime || timestamp > tlw->syncRequestTimestamp) {
+ tlw->syncRequestTimestamp = timestamp;
+ tlw->newCounterValueLo = event->xclient.data.l[2];
+ tlw->newCounterValueHi = event->xclient.data.l[3];
+ }
+ }
+#endif
}
} else if (event->xclient.message_type == ATOM(_QT_SCROLL_DONE)) {
widget->translateScrollDoneEvent(event);
@@ -4144,7 +4205,9 @@ bool QETWidget::translateMouseEvent(const XEvent *event)
|| ((nextEvent.type == EnterNotify || nextEvent.type == LeaveNotify)
&& qt_button_down == this)
|| (nextEvent.type == ClientMessage
- && nextEvent.xclient.message_type == ATOM(_QT_SCROLL_DONE))) {
+ && (nextEvent.xclient.message_type == ATOM(_QT_SCROLL_DONE) ||
+ (nextEvent.xclient.message_type == ATOM(WM_PROTOCOLS) &&
+ (Atom)nextEvent.xclient.data.l[0] == ATOM(_NET_WM_SYNC_REQUEST))))) {
qApp->x11ProcessEvent(&nextEvent);
continue;
} else if (nextEvent.type != MotionNotify ||
@@ -5200,6 +5263,14 @@ bool QETWidget::translateConfigEvent(const XEvent *event)
otherEvent.xconfigure.border_width;
}
}
+#ifndef QT_NO_XSYNC
+ qt_sync_request_event_data sync_event;
+ sync_event.window = internalWinId();
+ for (XEvent ev;;) {
+ if (!XCheckIfEvent(X11->display, &ev, &qt_sync_request_scanner, (XPointer)&sync_event))
+ break;
+ }
+#endif // QT_NO_XSYNC
}
QRect cr (geometry());
@@ -5285,6 +5356,20 @@ bool QETWidget::translateConfigEvent(const XEvent *event)
if (d->extra && d->extra->topextra)
d->extra->topextra->inTopLevelResize = false;
}
+#ifndef QT_NO_XSYNC
+ if (QTLWExtra *tlwExtra = d->maybeTopData()) {
+ if (tlwExtra->newCounterValueLo != 0 || tlwExtra->newCounterValueHi != 0) {
+ XSyncValue value;
+ XSyncIntsToValue(&value,
+ tlwExtra->newCounterValueLo,
+ tlwExtra->newCounterValueHi);
+
+ XSyncSetCounter(X11->display, tlwExtra->syncUpdateCounter, value);
+ tlwExtra->newCounterValueHi = 0;
+ tlwExtra->newCounterValueLo = 0;
+ }
+ }
+#endif
return true;
}
diff --git a/src/gui/kernel/qt_x11_p.h b/src/gui/kernel/qt_x11_p.h
index b9ace9d..21bb550 100644
--- a/src/gui/kernel/qt_x11_p.h
+++ b/src/gui/kernel/qt_x11_p.h
@@ -154,6 +154,10 @@ extern "C" {
# include <X11/extensions/Xrender.h>
#endif // QT_NO_XRENDER
+#ifndef QT_NO_XSYNC
+# include "X11/extensions/sync.h"
+#endif
+
// #define QT_NO_XKB
#ifndef QT_NO_XKB
# include <X11/XKBlib.h>
@@ -514,6 +518,8 @@ struct QX11Data
WM_TAKE_FOCUS,
_NET_WM_PING,
_NET_WM_CONTEXT_HELP,
+ _NET_WM_SYNC_REQUEST,
+ _NET_WM_SYNC_REQUEST_COUNTER,
// ICCCM window state
WM_STATE,
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index bf4f091..ff194f7 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -131,6 +131,10 @@ struct QTLWExtra {
uint embedded : 1;
// *************************** Platform specific values (bit fields first) **********
+#ifndef QT_NO_XSYNC
+ int newCounterValueHi : 32;
+ uint newCounterValueLo : 32;
+#endif
#if defined(Q_WS_X11) // <----------------------------------------------------------- X11
uint spont_unmapped: 1; // window was spontaneously unmapped
uint dnd : 1; // DND properties installed
@@ -156,6 +160,10 @@ struct QTLWExtra {
QWSManager *qwsManager;
#endif
#endif
+#ifndef QT_NO_XSYNC
+ WId syncUpdateCounter;
+ ulong syncRequestTimestamp;
+#endif
};
struct QWExtra {
diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp
index 4e34045..8159f8e 100644
--- a/src/gui/kernel/qwidget_x11.cpp
+++ b/src/gui/kernel/qwidget_x11.cpp
@@ -754,11 +754,14 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
qBound(1, data.crect.width(), XCOORD_MAX),
qBound(1, data.crect.height(), XCOORD_MAX));
XStoreName(dpy, id, appName.data());
- Atom protocols[4];
+ Atom protocols[5];
int n = 0;
protocols[n++] = ATOM(WM_DELETE_WINDOW); // support del window protocol
protocols[n++] = ATOM(WM_TAKE_FOCUS); // support take focus window protocol
protocols[n++] = ATOM(_NET_WM_PING); // support _NET_WM_PING protocol
+#ifndef QT_NO_XSYNC
+ protocols[n++] = ATOM(_NET_WM_SYNC_REQUEST); // support _NET_WM_SYNC_REQUEST protocol
+#endif // QT_NO_XSYNC
if (flags & Qt::WindowContextHelpButtonHint)
protocols[n++] = ATOM(_NET_WM_CONTEXT_HELP);
XSetWMProtocols(dpy, id, protocols, n);
@@ -1877,6 +1880,23 @@ void QWidgetPrivate::show_sys()
if (setUserTime)
qt_net_update_user_time(q, userTime);
+#ifndef QT_NO_XSYNC
+ if (!topData()->syncUpdateCounter) {
+ XSyncValue value;
+ XSyncIntToValue(&value, 0);
+ topData()->syncUpdateCounter = XSyncCreateCounter(X11->display, value);
+
+ XChangeProperty(X11->display, q->internalWinId(),
+ ATOM(_NET_WM_SYNC_REQUEST_COUNTER),
+ XA_CARDINAL,
+ 32, PropModeReplace,
+ (uchar *) &topData()->syncUpdateCounter, 1);
+
+ topData()->newCounterValueHi = 0;
+ topData()->newCounterValueLo = 0;
+ }
+#endif
+
if (!topData()->embedded
&& (topData()->validWMState || topData()->waitingForMapNotify)
&& !q->isMinimized()) {
@@ -2687,6 +2707,12 @@ void QWidgetPrivate::createTLSysExtra()
extra->topextra->waitingForMapNotify = 0;
extra->topextra->parentWinId = 0;
extra->topextra->userTimeWindow = 0;
+#ifndef QT_NO_XSYNC
+ extra->topextra->syncUpdateCounter = 0;
+ extra->topextra->syncRequestTimestamp = 0;
+ extra->topextra->newCounterValueHi = 0;
+ extra->topextra->newCounterValueLo = 0;
+#endif
}
void QWidgetPrivate::deleteTLSysExtra()
diff --git a/src/gui/kernel/qwidgetaction.cpp b/src/gui/kernel/qwidgetaction.cpp
index efdde5e..cd12029 100644
--- a/src/gui/kernel/qwidgetaction.cpp
+++ b/src/gui/kernel/qwidgetaction.cpp
@@ -228,8 +228,8 @@ bool QWidgetAction::event(QEvent *event)
if (event->type() == QEvent::ActionChanged) {
if (d->defaultWidget)
d->defaultWidget->setEnabled(isEnabled());
- foreach (QWidget *w, d->createdWidgets)
- w->setEnabled(isEnabled());
+ for (int i = 0; i < d->createdWidgets.count(); ++i)
+ d->createdWidgets.at(i)->setEnabled(isEnabled());
}
return QAction::event(event);
}
diff --git a/src/gui/math3d/qgenericmatrix.cpp b/src/gui/math3d/qgenericmatrix.cpp
index 61df367..82be256 100644
--- a/src/gui/math3d/qgenericmatrix.cpp
+++ b/src/gui/math3d/qgenericmatrix.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the $MODULE$ of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/math3d/qgenericmatrix.h b/src/gui/math3d/qgenericmatrix.h
index b4d3707..330ded2 100644
--- a/src/gui/math3d/qgenericmatrix.h
+++ b/src/gui/math3d/qgenericmatrix.h
@@ -3,7 +3,7 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the $MODULE$ of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp
index 8ef4da3..a69b9df 100644
--- a/src/gui/math3d/qmatrix4x4.cpp
+++ b/src/gui/math3d/qmatrix4x4.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the $MODULE$ of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/math3d/qmatrix4x4.h b/src/gui/math3d/qmatrix4x4.h
index ba7f67f..da1bcba 100644
--- a/src/gui/math3d/qmatrix4x4.h
+++ b/src/gui/math3d/qmatrix4x4.h
@@ -3,7 +3,7 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the $MODULE$ of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp
index 96659ea..03f626a 100644
--- a/src/gui/math3d/qquaternion.cpp
+++ b/src/gui/math3d/qquaternion.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the $MODULE$ of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h
index c05c641..b17cf73 100644
--- a/src/gui/math3d/qquaternion.h
+++ b/src/gui/math3d/qquaternion.h
@@ -3,7 +3,7 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the $MODULE$ of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/math3d/qvector2d.cpp b/src/gui/math3d/qvector2d.cpp
index c3aaa42..df2519d 100644
--- a/src/gui/math3d/qvector2d.cpp
+++ b/src/gui/math3d/qvector2d.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the $MODULE$ of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/math3d/qvector2d.h b/src/gui/math3d/qvector2d.h
index b027df4..2be0a11 100644
--- a/src/gui/math3d/qvector2d.h
+++ b/src/gui/math3d/qvector2d.h
@@ -3,7 +3,7 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the $MODULE$ of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/math3d/qvector3d.cpp b/src/gui/math3d/qvector3d.cpp
index c83cd60..a5f5c5b 100644
--- a/src/gui/math3d/qvector3d.cpp
+++ b/src/gui/math3d/qvector3d.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the $MODULE$ of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/math3d/qvector3d.h b/src/gui/math3d/qvector3d.h
index 02873f2..480667a 100644
--- a/src/gui/math3d/qvector3d.h
+++ b/src/gui/math3d/qvector3d.h
@@ -3,7 +3,7 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the $MODULE$ of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/math3d/qvector4d.cpp b/src/gui/math3d/qvector4d.cpp
index 010fa53..c5124e2 100644
--- a/src/gui/math3d/qvector4d.cpp
+++ b/src/gui/math3d/qvector4d.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the $MODULE$ of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/math3d/qvector4d.h b/src/gui/math3d/qvector4d.h
index 8e673f3..e38f4e5 100644
--- a/src/gui/math3d/qvector4d.h
+++ b/src/gui/math3d/qvector4d.h
@@ -3,7 +3,7 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the $MODULE$ of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 0810bb9..7ed2dfd 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -4311,7 +4311,7 @@ QClipData::QClipData(int height)
clipSpanHeight = height;
m_clipLines = 0;
- allocated = height;
+ allocated = 0;
m_spans = 0;
xmin = xmax = ymin = ymax = 0;
count = 0;
@@ -4479,7 +4479,7 @@ void QClipData::fixup()
*/
void QClipData::setClipRect(const QRect &rect)
{
- if (rect == clipRect)
+ if (hasRectClip && rect == clipRect)
return;
// qDebug() << "setClipRect" << clipSpanHeight << count << allocated << rect;
diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
index 28f9220..8eaad60 100644
--- a/src/gui/painting/qpaintengineex.cpp
+++ b/src/gui/painting/qpaintengineex.cpp
@@ -105,7 +105,7 @@ QDebug Q_GUI_EXPORT &operator<<(QDebug &s, const QVectorPath &path)
vectorPathBounds.x2 - vectorPathBounds.x1, vectorPathBounds.y2 - vectorPathBounds.y1);
s << "QVectorPath(size:" << path.elementCount()
<< " hints:" << hex << path.hints()
- << rf << ')';
+ << rf << ")";
return s;
}
#endif
@@ -778,7 +778,7 @@ void QPaintEngineEx::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, con
{
QBrush brush(state()->pen.color(), pixmap);
QTransform xform;
- xform.translate(r.x() - s.x(), r.y() - s.y());
+ xform.translate(-s.x(), -s.y());
brush.setTransform(xform);
qreal pts[] = { r.x(), r.y(),
diff --git a/src/gui/painting/qpaintengineex_p.h b/src/gui/painting/qpaintengineex_p.h
index 1c55242..593726c 100644
--- a/src/gui/painting/qpaintengineex_p.h
+++ b/src/gui/painting/qpaintengineex_p.h
@@ -216,8 +216,6 @@ public:
inline QPainterState *state() { return static_cast<QPainterState *>(QPaintEngine::state); }
inline const QPainterState *state() const { return static_cast<const QPainterState *>(QPaintEngine::state); }
- virtual void sync() {}
-
virtual QPixmapFilter *createPixmapFilter(int /*type*/) const { return 0; }
protected:
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 4744f14..cc48d24 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -6082,22 +6082,22 @@ void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti)
const QTransform &m = d->state->matrix;
if (d->state->matrix.type() < QTransform::TxShear) {
bool isPlain90DegreeRotation =
- (qFuzzyIsNull(m.m11())
- && qFuzzyIsNull(m.m12() - qreal(1))
- && qFuzzyIsNull(m.m21() + qreal(1))
- && qFuzzyIsNull(m.m22())
+ (qFuzzyCompare(m.m11() + 1, qreal(1))
+ && qFuzzyCompare(m.m12(), qreal(1))
+ && qFuzzyCompare(m.m21(), qreal(-1))
+ && qFuzzyCompare(m.m22() + 1, qreal(1))
)
||
- (qFuzzyIsNull(m.m11() + qreal(1))
- && qFuzzyIsNull(m.m12())
- && qFuzzyIsNull(m.m21())
- && qFuzzyIsNull(m.m22() + qreal(1))
+ (qFuzzyCompare(m.m11(), qreal(-1))
+ && qFuzzyCompare(m.m12() + 1, qreal(1))
+ && qFuzzyCompare(m.m21() + 1, qreal(1))
+ && qFuzzyCompare(m.m22(), qreal(-1))
)
||
- (qFuzzyIsNull(m.m11())
- && qFuzzyIsNull(m.m12() + qreal(1))
- && qFuzzyIsNull(m.m21() - qreal(1))
- && qFuzzyIsNull(m.m22())
+ (qFuzzyCompare(m.m11() + 1, qreal(1))
+ && qFuzzyCompare(m.m12(), qreal(-1))
+ && qFuzzyCompare(m.m21(), qreal(1))
+ && qFuzzyCompare(m.m22() + 1, qreal(1))
)
;
aa = !isPlain90DegreeRotation;
diff --git a/src/gui/painting/qpainter_p.h b/src/gui/painting/qpainter_p.h
index 6c8821a..258b25a 100644
--- a/src/gui/painting/qpainter_p.h
+++ b/src/gui/painting/qpainter_p.h
@@ -92,8 +92,8 @@ inline Qt::PenJoinStyle qpen_joinStyle(const QPen &p) { return data_ptr(p)->join
// QBrush inline functions...
inline QBrush::DataPtr &data_ptr(const QBrush &p) { return const_cast<QBrush &>(p).data_ptr(); }
inline bool qbrush_fast_equals(const QBrush &a, const QBrush &b) { return data_ptr(a) == data_ptr(b); }
-inline Qt::BrushStyle qbrush_style(const QBrush &b) { return data_ptr(b)->style; }
-inline const QColor &qbrush_color(const QBrush &b) { return data_ptr(b)->color; }
+inline Qt::BrushStyle qbrush_style(const QBrush &b) { return data_ptr(b)->style; };
+inline const QColor &qbrush_color(const QBrush &b) { return data_ptr(b)->color; };
inline bool qbrush_has_transform(const QBrush &b) { return data_ptr(b)->transform.type() > QTransform::TxNone; }
class QPainterClipInfo
diff --git a/src/gui/painting/qprinter.cpp b/src/gui/painting/qprinter.cpp
index ba208fd..ce33893 100644
--- a/src/gui/painting/qprinter.cpp
+++ b/src/gui/painting/qprinter.cpp
@@ -1308,6 +1308,9 @@ void QPrinter::setNumCopies(int numCopies)
Returns true if collation is turned on when multiple copies is selected.
Returns false if it is turned off when multiple copies is selected.
+ When collating is turned off the printing of each individual page will be repeated
+ the numCopies() amount before the next page is started. With collating turned on
+ all pages are printed before the next copy of those pages is started.
\sa setCollateCopies()
*/
diff --git a/src/gui/painting/qtextureglyphcache_p.h b/src/gui/painting/qtextureglyphcache_p.h
index cb5be75..689c091 100644
--- a/src/gui/painting/qtextureglyphcache_p.h
+++ b/src/gui/painting/qtextureglyphcache_p.h
@@ -121,7 +121,7 @@ protected:
};
-class Q_GUI_EXPORT QImageTextureGlyphCache : public QTextureGlyphCache
+class QImageTextureGlyphCache : public QTextureGlyphCache
{
public:
QImageTextureGlyphCache(QFontEngineGlyphCache::Type type, const QTransform &matrix)
diff --git a/src/gui/styles/qcleanlooksstyle.cpp b/src/gui/styles/qcleanlooksstyle.cpp
index b33dfc1..805cd05 100644
--- a/src/gui/styles/qcleanlooksstyle.cpp
+++ b/src/gui/styles/qcleanlooksstyle.cpp
@@ -3305,7 +3305,8 @@ void QCleanlooksStyle::drawComplexControl(ComplexControl control, const QStyleOp
}
}
// Draw the focus rect
- if ((focus && (option->state & State_KeyboardFocusChange)) && !comboBox->editable) {
+ if (focus && !comboBox->editable
+ && ((option->state & State_KeyboardFocusChange) || styleHint(SH_UnderlineShortcut, option, widget))) {
QStyleOptionFocusRect focus;
focus.rect = subControlRect(CC_ComboBox, &comboBoxCopy, SC_ComboBoxEditField, widget)
.adjusted(0, 2, option->direction == Qt::RightToLeft ? 1 : -1, -2);
diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp
index 1fe4627..ab81d97 100644
--- a/src/gui/styles/qgtkstyle.cpp
+++ b/src/gui/styles/qgtkstyle.cpp
@@ -1426,7 +1426,7 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom
QGtk::gtk_widget_style_get(gtkToggleButton, "interior-focus", &interiorFocus, NULL);
int xt = interiorFocus ? gtkToggleButton->style->xthickness : 0;
int yt = interiorFocus ? gtkToggleButton->style->ythickness : 0;
- if ((focus && (option->state & State_KeyboardFocusChange)))
+ if (focus && ((option->state & State_KeyboardFocusChange) || styleHint(SH_UnderlineShortcut, option, widget)))
gtkCachedPainter.paintFocus(gtkToggleButton, "button",
option->rect.adjusted(xt, yt, -xt, -yt),
option->state & State_Sunken ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL,
diff --git a/src/gui/styles/qplastiquestyle.cpp b/src/gui/styles/qplastiquestyle.cpp
index 01c0e44..0a56213 100644
--- a/src/gui/styles/qplastiquestyle.cpp
+++ b/src/gui/styles/qplastiquestyle.cpp
@@ -4568,7 +4568,8 @@ void QPlastiqueStyle::drawComplexControl(ComplexControl control, const QStyleOpt
}
// Draw the focus rect
- if (((option->state & State_HasFocus) && (option->state & State_KeyboardFocusChange)) && !comboBox->editable) {
+ if ((option->state & State_HasFocus) && !comboBox->editable
+ && ((option->state & State_KeyboardFocusChange) || styleHint(SH_UnderlineShortcut, option, widget))) {
QStyleOptionFocusRect focus;
focus.rect = subControlRect(CC_ComboBox, option, SC_ComboBoxEditField, widget)
.adjusted(-2, 0, 2, 0);
diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp
index 0494b72..a05e5a1 100644
--- a/src/gui/text/qcssparser.cpp
+++ b/src/gui/text/qcssparser.cpp
@@ -57,46 +57,6 @@ QT_BEGIN_NAMESPACE
using namespace QCss;
-const char *Scanner::tokenName(QCss::TokenType t)
-{
- switch (t) {
- case NONE: return "NONE";
- case S: return "S";
- case CDO: return "CDO";
- case CDC: return "CDC";
- case INCLUDES: return "INCLUDES";
- case DASHMATCH: return "DASHMATCH";
- case LBRACE: return "LBRACE";
- case PLUS: return "PLUS";
- case GREATER: return "GREATER";
- case COMMA: return "COMMA";
- case STRING: return "STRING";
- case INVALID: return "INVALID";
- case IDENT: return "IDENT";
- case HASH: return "HASH";
- case ATKEYWORD_SYM: return "ATKEYWORD_SYM";
- case EXCLAMATION_SYM: return "EXCLAMATION_SYM";
- case LENGTH: return "LENGTH";
- case PERCENTAGE: return "PERCENTAGE";
- case NUMBER: return "NUMBER";
- case FUNCTION: return "FUNCTION";
- case COLON: return "COLON";
- case SEMICOLON: return "SEMICOLON";
- case RBRACE: return "RBRACE";
- case SLASH: return "SLASH";
- case MINUS: return "MINUS";
- case DOT: return "DOT";
- case STAR: return "STAR";
- case LBRACKET: return "LBRACKET";
- case RBRACKET: return "RBRACKET";
- case EQUAL: return "EQUAL";
- case LPAREN: return "LPAREN";
- case RPAREN: return "RPAREN";
- case OR: return "OR";
- }
- return "";
-}
-
struct QCssKnownValue
{
const char *name;
@@ -279,7 +239,7 @@ static const QCssKnownValue values[NumKnownValues - 1] = {
};
//Map id to strings as they appears in the 'values' array above
-static const int indexOfId[NumKnownValues] = { 0, 40, 47, 41, 48, 53, 34, 26, 68, 69, 25, 42, 5, 62, 46,
+static const short indexOfId[NumKnownValues] = { 0, 40, 47, 41, 48, 53, 34, 26, 68, 69, 25, 42, 5, 62, 46,
29, 57, 58, 27, 50, 60, 6, 10, 38, 55, 19, 13, 17, 18, 20, 21, 49, 24, 45, 65, 36, 3, 2, 39, 61, 16,
11, 56, 14, 32, 63, 54, 64, 33, 67, 8, 28, 37, 12, 35, 59, 7, 9, 4, 66, 52, 22, 23, 30, 31, 1, 15, 0,
51, 44, 43 };
diff --git a/src/gui/text/qcssparser_p.h b/src/gui/text/qcssparser_p.h
index 72bd637..81f306d 100644
--- a/src/gui/text/qcssparser_p.h
+++ b/src/gui/text/qcssparser_p.h
@@ -731,7 +731,6 @@ class Q_AUTOTEST_EXPORT Scanner
public:
static QString preprocess(const QString &input, bool *hasEscapeSequences = 0);
static void scan(const QString &preprocessedInput, QVector<Symbol> *symbols);
- static const char *tokenName(TokenType t);
};
class Q_GUI_EXPORT Parser
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index 6e8adcf..79e341a 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -70,12 +70,6 @@ static inline bool qtransform_equals_no_translate(const QTransform &a, const QTr
}
}
-
-
-QFontEngineGlyphCache::~QFontEngineGlyphCache()
-{
-}
-
// Harfbuzz helper functions
static HB_Bool hb_stringToGlyphs(HB_Font font, const HB_UChar16 *string, hb_uint32 length, HB_Glyph *glyphs, hb_uint32 *numGlyphs, HB_Bool rightToLeft)
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index 0f8d81c..3ef9d5f 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -93,7 +93,6 @@ struct QGlyphLayout;
class Q_GUI_EXPORT QFontEngine : public QObject
{
- Q_OBJECT
public:
enum Type {
Box,
diff --git a/src/gui/text/qfontengineglyphcache_p.h b/src/gui/text/qfontengineglyphcache_p.h
index 8589cc6..ca67e3f 100644
--- a/src/gui/text/qfontengineglyphcache_p.h
+++ b/src/gui/text/qfontengineglyphcache_p.h
@@ -72,7 +72,7 @@
QT_BEGIN_NAMESPACE
-class Q_GUI_EXPORT QFontEngineGlyphCache
+class QFontEngineGlyphCache
{
public:
QFontEngineGlyphCache(const QTransform &matrix) : m_transform(matrix) { }
@@ -83,7 +83,7 @@ public:
Raster_Mono
};
- virtual ~QFontEngineGlyphCache();
+ virtual ~QFontEngineGlyphCache() { }
QTransform m_transform;
};
diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp
index ee743dc..76c59c3 100644
--- a/src/gui/text/qtexthtmlparser.cpp
+++ b/src/gui/text/qtexthtmlparser.cpp
@@ -343,7 +343,7 @@ static QChar resolveEntity(const QString &entity)
return e->code;
}
-static const uint windowsLatin1ExtendedCharacters[0xA0 - 0x80] = {
+static const ushort windowsLatin1ExtendedCharacters[0xA0 - 0x80] = {
0x20ac, // 0x80
0x0081, // 0x81 direct mapping
0x201a, // 0x82
diff --git a/src/gui/util/qdesktopservices_win.cpp b/src/gui/util/qdesktopservices_win.cpp
index 8d2701c..a8aa11c 100644
--- a/src/gui/util/qdesktopservices_win.cpp
+++ b/src/gui/util/qdesktopservices_win.cpp
@@ -115,11 +115,11 @@ static bool launchWebBrowser(const QUrl &url)
if (res == ERROR_SUCCESS) {
returnValue = RegQueryValueEx(handle, L"Progid", 0, 0, reinterpret_cast<unsigned char*>(keyValue), &bufferSize);
if (!returnValue)
- keyName = QString::fromUtf16(keyValue);
+ keyName = QString::fromUtf16((const ushort*)keyValue);
RegCloseKey(handle);
}
keyName += QLatin1String("\\Shell\\Open\\Command");
- res = RegOpenKeyExW(HKEY_CLASSES_ROOT, keyName.utf16(), 0, KEY_READ, &handle);
+ res = RegOpenKeyExW(HKEY_CLASSES_ROOT, (const wchar_t*)keyName.utf16(), 0, KEY_READ, &handle);
if (res != ERROR_SUCCESS)
return false;
@@ -165,6 +165,9 @@ static bool launchWebBrowser(const QUrl &url)
if (!url.isValid())
return false;
+ if (url.scheme().isEmpty())
+ return openDocument(url);
+
quintptr returnValue;
returnValue = (quintptr)ShellExecute(0, 0, (TCHAR *) QString::fromUtf8(url.toEncoded().constData()).utf16(),
0, 0, SW_SHOWNORMAL);
diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp
index 4f0ec1e..58e8f9c 100644
--- a/src/gui/widgets/qdockarealayout.cpp
+++ b/src/gui/widgets/qdockarealayout.cpp
@@ -2202,8 +2202,8 @@ QSet<QWidget*> QDockAreaLayoutInfo::usedSeparatorWidgets() const
{
QSet<QWidget*> result;
- foreach (QWidget *sepWidget, separatorWidgets)
- result << sepWidget;
+ for (int i = 0; i < separatorWidgets.count(); ++i)
+ result << separatorWidgets.at(i);
for (int i = 0; i < item_list.count(); ++i) {
const QDockAreaLayoutItem &item = item_list.at(i);
@@ -3244,8 +3244,8 @@ QSet<QWidget*> QDockAreaLayout::usedSeparatorWidgets() const
{
QSet<QWidget*> result;
- foreach (QWidget *sepWidget, separatorWidgets)
- result << sepWidget;
+ for (int i = 0; i < separatorWidgets.count(); ++i)
+ result << separatorWidgets.at(i);
for (int i = 0; i < QInternal::DockCount; ++i) {
const QDockAreaLayoutInfo &dock = docks[i];
result += dock.usedSeparatorWidgets();
diff --git a/src/gui/widgets/qdockwidget.cpp b/src/gui/widgets/qdockwidget.cpp
index d573b8b..6a0c879 100644
--- a/src/gui/widgets/qdockwidget.cpp
+++ b/src/gui/widgets/qdockwidget.cpp
@@ -221,7 +221,8 @@ void QDockWidgetLayout::addItem(QLayoutItem*)
QLayoutItem *QDockWidgetLayout::itemAt(int index) const
{
int cnt = 0;
- foreach (QLayoutItem *item, item_list) {
+ for (int i = 0; i < item_list.count(); ++i) {
+ QLayoutItem *item = item_list.at(i);
if (item == 0)
continue;
if (index == cnt++)
@@ -250,8 +251,8 @@ QLayoutItem *QDockWidgetLayout::takeAt(int index)
int QDockWidgetLayout::count() const
{
int result = 0;
- foreach (QLayoutItem *item, item_list) {
- if (item != 0)
+ for (int i = 0; i < item_list.count(); ++i) {
+ if (item_list.at(i))
++result;
}
return result;
diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp
index cffc3d5..fc7e901 100644
--- a/src/gui/widgets/qmenubar.cpp
+++ b/src/gui/widgets/qmenubar.cpp
@@ -220,7 +220,8 @@ void QMenuBarPrivate::updateGeometries()
//we try to see if the actions will fit there
bool hasHiddenActions = false;
- foreach(QAction *action, actionList) {
+ for (int i = 0; i < actionList.count(); ++i) {
+ QAction *action = actionList.at(i);
if (!menuRect.contains(actionRect(action))) {
hasHiddenActions = true;
break;
@@ -230,7 +231,8 @@ void QMenuBarPrivate::updateGeometries()
//...and if not, determine the ones that fit on the menu with the extension visible
if (hasHiddenActions) {
menuRect = this->menuRect(true);
- foreach(QAction *action, actionList) {
+ for (int i = 0; i < actionList.count(); ++i) {
+ QAction *action = actionList.at(i);
if (!menuRect.contains(actionRect(action))) {
hiddenActions.append(action);
}
diff --git a/src/gui/widgets/qtoolbarlayout.cpp b/src/gui/widgets/qtoolbarlayout.cpp
index 0bfa493..0af2b65 100644
--- a/src/gui/widgets/qtoolbarlayout.cpp
+++ b/src/gui/widgets/qtoolbarlayout.cpp
@@ -128,7 +128,7 @@ void QToolBarLayout::setUsePopupMenu(bool set)
invalidate();
if (!set) {
QObject::connect(extension, SIGNAL(clicked(bool)),
- this, SLOT(setExpanded(bool)));
+ this, SLOT(setExpanded(bool)), Qt::UniqueConnection);
extension->setPopupMode(QToolButton::DelayedPopup);
extension->setMenu(0);
delete popupMenu;
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
index ea57fdf..5c541d0 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
@@ -157,6 +157,7 @@ QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context)
simpleShaderProg->addShader(compiledShaders[PositionOnlyVertexShader]);
simpleShaderProg->addShader(compiledShaders[MainFragmentShader]);
simpleShaderProg->addShader(compiledShaders[ShockingPinkSrcFragmentShader]);
+ simpleShaderProg->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR);
simpleShaderProg->link();
if (!simpleShaderProg->isLinked()) {
qCritical() << "Errors linking simple shader:"
@@ -444,7 +445,7 @@ bool QGLEngineShaderManager::useCorrectShaderProg()
requiredProgram.program->addShader(requiredProgram.compositionFragShader);
// We have to bind the vertex attribute names before the program is linked:
- requiredProgram.program->bindAttributeLocation("inputVertex", QT_VERTEX_COORDS_ATTR);
+ requiredProgram.program->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR);
if (useTextureCoords)
requiredProgram.program->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR);
diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h
index 920d0bc..70cc67e 100644
--- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h
+++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h
@@ -84,16 +84,20 @@ static const char* const qglslMainWithTexCoordsVertexShader = "\
static const char* const qglslPositionOnlyVertexShader = "\
attribute highp vec4 vertexCoordsArray;\
uniform highp mat4 pmvMatrix;\
+ uniform highp float depth;\
void setPosition(void)\
{\
gl_Position = pmvMatrix * vertexCoordsArray;\
+ gl_Position.z = depth;\
}";
static const char* const qglslUntransformedPositionVertexShader = "\
attribute highp vec4 vertexCoordsArray;\
+ uniform highp float depth;\
void setPosition(void)\
{\
gl_Position = vertexCoordsArray;\
+ gl_Position.z = depth;\
}";
// Pattern Brush - This assumes the texture size is 8x8 and thus, the inverted size is 0.125
@@ -104,9 +108,11 @@ static const char* const qglslPositionWithPatternBrushVertexShader = "\
uniform mediump vec2 invertedTextureSize; \
uniform mediump mat3 brushTransform; \
varying mediump vec2 patternTexCoords; \
+ uniform highp float depth;\
void setPosition(void) { \
gl_Position = pmvMatrix * vertexCoordsArray;\
gl_Position.xy = gl_Position.xy / gl_Position.w; \
+ gl_Position.z = depth;\
mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \
mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \
mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \
@@ -136,9 +142,11 @@ static const char* const qglslPositionWithLinearGradientBrushVertexShader = "\
uniform highp vec3 linearData; \
uniform highp mat3 brushTransform; \
varying mediump float index ; \
+ uniform highp float depth;\
void setPosition() { \
gl_Position = pmvMatrix * vertexCoordsArray;\
gl_Position.xy = gl_Position.xy / gl_Position.w; \
+ gl_Position.z = depth;\
mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \
mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \
mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \
@@ -166,10 +174,12 @@ static const char* const qglslPositionWithConicalGradientBrushVertexShader = "\
uniform mediump vec2 halfViewportSize; \
uniform highp mat3 brushTransform; \
varying highp vec2 A; \
+ uniform highp float depth;\
void setPosition(void)\
{\
gl_Position = pmvMatrix * vertexCoordsArray;\
gl_Position.xy = gl_Position.xy / gl_Position.w; \
+ gl_Position.z = depth; \
mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \
mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \
mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \
@@ -205,10 +215,12 @@ static const char* const qglslPositionWithRadialGradientBrushVertexShader = "\
uniform highp vec2 fmp; \
varying highp float b; \
varying highp vec2 A; \
+ uniform highp float depth;\
void setPosition(void) \
{\
gl_Position = pmvMatrix * vertexCoordsArray;\
gl_Position.xy = gl_Position.xy / gl_Position.w; \
+ gl_Position.z = depth; \
mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \
mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \
mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \
@@ -242,9 +254,11 @@ static const char* const qglslPositionWithTextureBrushVertexShader = "\
uniform mediump vec2 invertedTextureSize; \
uniform mediump mat3 brushTransform; \
varying mediump vec2 brushTextureCoords; \
+ uniform highp float depth;\
void setPosition(void) { \
gl_Position = pmvMatrix * vertexCoordsArray;\
gl_Position.xy = gl_Position.xy / gl_Position.w; \
+ gl_Position.z = depth; \
mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \
mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \
mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 868adcf..bdea187 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -183,8 +183,8 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
pex->transferMode(BrushDrawingMode);
- glDisable(GL_SCISSOR_TEST);
glDisable(GL_DEPTH_TEST);
+ glDisable(GL_SCISSOR_TEST);
glViewport(0, 0, oldWidth, oldHeight);
@@ -217,7 +217,7 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
glViewport(0, 0, pex->width, pex->height);
- pex->updateDepthClip();
+ pex->updateDepthScissorTest();
}
void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph)
@@ -297,6 +297,11 @@ void QGL2PaintEngineExPrivate::useSimpleShader()
shaderManager->simpleProgram()->setUniformValue("pmvMatrix", pmvMatrix);
simpleShaderMatrixUniformDirty = false;
}
+
+ if (simpleShaderDepthUniformDirty) {
+ shaderManager->simpleProgram()->setUniformValue("depth", (GLfloat)q->state()->currentDepth);
+ simpleShaderDepthUniformDirty = false;
+ }
}
@@ -709,6 +714,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
if (path.shape() == QVectorPath::RectangleHint) {
QGLRect rect(points[0].x(), points[0].y(), points[2].x(), points[2].y());
prepareForDraw(currentBrush->isOpaque());
+
composite(rect);
}
else if (path.shape() == QVectorPath::EllipseHint) {
@@ -726,12 +732,14 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
// Stencil the brush onto the dest buffer
glStencilFunc(GL_NOTEQUAL, 0, 0xFFFF); // Pass if stencil buff value != 0
+ glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
+
glEnable(GL_STENCIL_TEST);
prepareForDraw(currentBrush->isOpaque());
composite(vertexCoordinateArray.boundingRect());
glDisable(GL_STENCIL_TEST);
- cleanStencilBuffer(vertexCoordinateArray.boundingRect());
+ glStencilMask(0);
}
}
@@ -739,17 +747,17 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
void QGL2PaintEngineExPrivate::fillStencilWithVertexArray(QGL2PEXVertexArray& vertexArray, bool useWindingFill)
{
// qDebug("QGL2PaintEngineExPrivate::fillStencilWithVertexArray()");
- if (stencilBuferDirty) {
+ glStencilMask(0xFFFF); // Enable stencil writes
+
+ if (stencilBufferDirty) {
// Clear the stencil buffer to zeros
glDisable(GL_STENCIL_TEST);
- glStencilMask(0xFFFF); // Enable writing to stencil buffer, otherwise glClear wont do anything.
glClearStencil(0); // Clear to zero
glClear(GL_STENCIL_BUFFER_BIT);
- stencilBuferDirty = false;
+ stencilBufferDirty = false;
}
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // Disable color writes
- glStencilMask(0xFFFF); // Enable stencil writes
glStencilFunc(GL_ALWAYS, 0, 0xFFFF); // Always pass the stencil test
// Setup the stencil op:
@@ -759,7 +767,7 @@ void QGL2PaintEngineExPrivate::fillStencilWithVertexArray(QGL2PEXVertexArray& ve
} else
glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); // Simply invert the stencil bit
- // No point in using a fancy gradiant shader for writing into the stencil buffer!
+ // No point in using a fancy gradient shader for writing into the stencil buffer!
useSimpleShader();
glEnable(GL_STENCIL_TEST); // For some reason, this has to happen _after_ the simple shader is use()'d
@@ -770,41 +778,6 @@ void QGL2PaintEngineExPrivate::fillStencilWithVertexArray(QGL2PEXVertexArray& ve
// Enable color writes & disable stencil writes
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- glStencilMask(0);
-}
-
-void QGL2PaintEngineExPrivate::cleanStencilBuffer(const QGLRect& area)
-{
-// qDebug("QGL2PaintEngineExPrivate::cleanStencilBuffer()");
- useSimpleShader();
-
- GLfloat rectVerts[] = {
- area.left, area.top,
- area.left, area.bottom,
- area.right, area.bottom,
- area.right, area.top
- };
-
- glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
- glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, rectVerts);
-
- glEnable(GL_STENCIL_TEST);
- glStencilFunc(GL_ALWAYS, 0, 0xFFFF); // Always pass the stencil test
-
- glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // Disable color writes
- glStencilMask(0xFFFF); // Enable writing to stencil buffer
- glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO); // Write 0's to stencil buffer
-
- glDisable(GL_BLEND);
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
-
- // Enable color writes & disable stencil writes
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- glStencilMask(0);
- glDisable(GL_STENCIL_TEST);
}
void QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque)
@@ -843,6 +816,7 @@ void QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque)
// The shader program has changed so mark all uniforms as dirty:
brushUniformsDirty = true;
shaderMatrixUniformDirty = true;
+ depthUniformDirty = true;
}
if (brushUniformsDirty && mode != ImageDrawingMode)
@@ -853,6 +827,11 @@ void QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque)
shaderMatrixUniformDirty = false;
}
+ if (depthUniformDirty) {
+ shaderManager->currentProgram()->setUniformValue("depth", (GLfloat)q->state()->currentDepth);
+ depthUniformDirty = false;
+ }
+
if (useGlobalOpacityUniform)
shaderManager->currentProgram()->setUniformValue("globalOpacity", (GLfloat)q->state()->opacity);
}
@@ -1062,7 +1041,6 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte
matrix.translate(p.x(), p.y());
ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
-
QFontEngineGlyphCache::Type glyphType = ti.fontEngine->glyphFormat >= 0
? QFontEngineGlyphCache::Type(ti.fontEngine->glyphFormat)
: QFontEngineGlyphCache::Raster_A8;
@@ -1146,6 +1124,7 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
}
d->ctx->d_ptr->active_engine = this;
+ d->last_created_state = 0;
d->drawable.makeCurrent();
QSize sz = d->drawable.size();
@@ -1172,12 +1151,16 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
d->brushUniformsDirty = true;
d->matrixDirty = true;
d->compositionModeDirty = true;
- d->stencilBuferDirty = true;
+ d->stencilBufferDirty = true;
+ d->simpleShaderDepthUniformDirty = true;
+ d->depthUniformDirty = true;
d->use_system_clip = !systemClip().isEmpty();
glDisable(GL_DEPTH_TEST);
glDisable(GL_SCISSOR_TEST);
+ glDepthFunc(GL_LEQUAL);
+ glDepthMask(false);
QGLPixmapData *source = d->drawable.copyOnBegin();
if (d->drawable.context()->d_func()->clear_on_painter_begin && d->drawable.autoFillBackground()) {
@@ -1201,7 +1184,7 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
d->drawTexture(QRectF(rect), QRectF(rect), rect.size(), true);
}
- updateClipRegion(QRegion(), Qt::NoClip);
+ d->systemStateChanged();
return true;
}
@@ -1245,260 +1228,297 @@ void QGL2PaintEngineEx::ensureActive()
ctx->d_ptr->active_engine = this;
glDisable(GL_DEPTH_TEST);
- glDisable(GL_SCISSOR_TEST);
glViewport(0, 0, d->width, d->height);
+
setState(state());
- d->updateDepthClip();
}
}
+void QGL2PaintEngineExPrivate::updateDepthScissorTest()
+{
+ Q_Q(QGL2PaintEngineEx);
+ if (q->state()->depthTestEnabled)
+ glEnable(GL_DEPTH_TEST);
+ else
+ glDisable(GL_DEPTH_TEST);
-/////////////////////////////////// State/Clipping stolen from QOpenGLPaintEngine //////////////////////////////////////////
+ if (q->state()->scissorTestEnabled)
+ glEnable(GL_SCISSOR_TEST);
+ else
+ glDisable(GL_SCISSOR_TEST);
+}
void QGL2PaintEngineEx::clipEnabledChanged()
{
Q_D(QGL2PaintEngineEx);
- d->updateDepthClip();
+ d->simpleShaderDepthUniformDirty = true;
+ d->depthUniformDirty = true;
+
+ if (painter()->hasClipping()) {
+ d->regenerateDepthClip();
+ } else {
+ if (d->use_system_clip) {
+ state()->currentDepth = -0.5f;
+ } else {
+ glDisable(GL_DEPTH_TEST);
+ state()->depthTestEnabled = false;
+ }
+ }
}
-void QGL2PaintEngineEx::clip(const QVectorPath &path, Qt::ClipOperation op)
+void QGL2PaintEngineExPrivate::writeClip(const QVectorPath &path, float depth)
{
-// qDebug("QGL2PaintEngineEx::clip()");
- const qreal *points = path.points();
- const QPainterPath::ElementType *types = path.elements();
- if (!types && path.shape() == QVectorPath::RectangleHint) {
- QRectF r(points[0], points[1], points[4]-points[0], points[5]-points[1]);
- updateClipRegion(QRegion(r.toRect()), op);
- return;
- }
+ transferMode(BrushDrawingMode);
- QPainterPath p;
- if (types) {
- int id = 0;
- for (int i=0; i<path.elementCount(); ++i) {
- switch(types[i]) {
- case QPainterPath::MoveToElement:
- p.moveTo(QPointF(points[id], points[id+1]));
- id+=2;
- break;
- case QPainterPath::LineToElement:
- p.lineTo(QPointF(points[id], points[id+1]));
- id+=2;
- break;
- case QPainterPath::CurveToElement: {
- QPointF p1(points[id], points[id+1]);
- QPointF p2(points[id+2], points[id+3]);
- QPointF p3(points[id+4], points[id+5]);
- p.cubicTo(p1, p2, p3);
- id+=6;
- break;
- }
- case QPainterPath::CurveToDataElement:
- ;
- break;
- }
- }
- } else if (!path.isEmpty()) {
- p.moveTo(QPointF(points[0], points[1]));
- int id = 2;
- for (int i=1; i<path.elementCount(); ++i) {
- p.lineTo(QPointF(points[id], points[id+1]));
- id+=2;
- }
+ if (matrixDirty)
+ updateMatrix();
+
+ if (q->state()->needsDepthBufferClear) {
+ glDepthMask(true);
+ glClearDepth(0.5);
+ glClear(GL_DEPTH_BUFFER_BIT);
+ q->state()->needsDepthBufferClear = false;
+ glDepthMask(false);
}
- if (path.hints() & QVectorPath::WindingFill)
- p.setFillRule(Qt::WindingFill);
- updateClipRegion(QRegion(p.toFillPolygon().toPolygon(), p.fillRule()), op);
- return;
+ if (path.isEmpty())
+ return;
+
+ glDisable(GL_BLEND);
+ glDepthMask(false);
+
+ vertexCoordinateArray.clear();
+ vertexCoordinateArray.addPath(path, inverseScale);
+
+ glDepthMask(GL_FALSE);
+ fillStencilWithVertexArray(vertexCoordinateArray, path.hasWindingFill());
+
+ // Stencil the clip onto the clip buffer
+ glColorMask(false, false, false, false);
+ glDepthMask(true);
+
+ shaderManager->simpleProgram()->setUniformValue("depth", depth);
+ simpleShaderDepthUniformDirty = true;
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_ALWAYS);
+
+ glStencilFunc(GL_NOTEQUAL, 0, 0xFFFF); // Pass if stencil buff value != 0
+ glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
+
+ glEnable(GL_STENCIL_TEST);
+ composite(vertexCoordinateArray.boundingRect());
+ glDisable(GL_STENCIL_TEST);
+
+ glStencilMask(0);
+
+ glColorMask(true, true, true, true);
+ glDepthMask(false);
}
-void QGL2PaintEngineEx::updateClipRegion(const QRegion &clipRegion, Qt::ClipOperation op)
+void QGL2PaintEngineEx::clip(const QVectorPath &path, Qt::ClipOperation op)
{
-// qDebug("QGL2PaintEngineEx::updateClipRegion()");
+// qDebug("QGL2PaintEngineEx::clip()");
Q_D(QGL2PaintEngineEx);
- QRegion sysClip = systemClip();
- if (op == Qt::NoClip && !d->use_system_clip) {
- state()->hasClipping = false;
- state()->clipRegion = QRegion();
- d->updateDepthClip();
- return;
- }
+ if (op == Qt::ReplaceClip && !d->hasClipOperations())
+ op = Qt::IntersectClip;
- bool isScreenClip = false;
- if (!d->use_system_clip) {
- QVector<QRect> untransformedRects = clipRegion.rects();
+ if (!path.isEmpty() && op == Qt::IntersectClip && (path.hints() & QVectorPath::RectangleHint)) {
+ const QPointF* const points = reinterpret_cast<const QPointF*>(path.points());
+ QRectF rect(points[0], points[2]);
- if (untransformedRects.size() == 1) {
- QPainterPath path;
- path.addRect(untransformedRects[0]);
- //path = d->matrix.map(path);
- path = state()->matrix.map(path);
-
-// if (path.contains(QRectF(QPointF(), d->drawable.size())))
-// isScreenClip = true;
- if (path.contains(QRectF(0.0, 0.0, d->width, d->height)))
- isScreenClip = true;
+ if (state()->matrix.type() <= QTransform::TxScale) {
+ rect = state()->matrix.mapRect(rect);
+
+ if (d->use_system_clip && rect.contains(d->systemClip.boundingRect())
+ || rect.contains(QRect(0, 0, d->width, d->height)))
+ return;
}
}
-// QRegion region = isScreenClip ? QRegion() : clipRegion * d->matrix;
- QRegion region = isScreenClip ? QRegion() : clipRegion * state()->matrix;
switch (op) {
case Qt::NoClip:
- if (!d->use_system_clip)
- break;
- state()->clipRegion = sysClip;
+ if (d->use_system_clip) {
+ glEnable(GL_DEPTH_TEST);
+ state()->depthTestEnabled = true;
+ state()->currentDepth = -0.5;
+ } else {
+ glDisable(GL_DEPTH_TEST);
+ state()->depthTestEnabled = false;
+ }
+ state()->canRestoreClip = false;
break;
case Qt::IntersectClip:
- if (isScreenClip)
- return;
- if (state()->hasClipping) {
- state()->clipRegion &= region;
- break;
- }
- // fall through
+ state()->maxDepth = (1.0f + state()->maxDepth) * 0.5;
+ d->writeClip(path, state()->maxDepth);
+ state()->currentDepth = 1.5 * state()->maxDepth - 0.5f;
+ state()->depthTestEnabled = true;
+ break;
case Qt::ReplaceClip:
- if (d->use_system_clip && !sysClip.isEmpty())
- state()->clipRegion = region & sysClip;
- else
- state()->clipRegion = region;
+ d->systemStateChanged();
+ state()->maxDepth = 0.5f;
+ glDepthFunc(GL_ALWAYS);
+ d->writeClip(path, state()->maxDepth);
+ state()->currentDepth = 0.25f;
+ state()->canRestoreClip = false;
+ state()->depthTestEnabled = true;
break;
case Qt::UniteClip:
- state()->clipRegion |= region;
- if (d->use_system_clip && !sysClip.isEmpty())
- state()->clipRegion &= sysClip;
- break;
- default:
+ glDepthFunc(GL_ALWAYS);
+ d->writeClip(path, state()->maxDepth);
+ state()->canRestoreClip = false;
+ state()->depthTestEnabled = true;
break;
}
- if (isScreenClip) {
- state()->hasClipping = false;
- state()->clipRegion = QRegion();
- } else {
- state()->hasClipping = op != Qt::NoClip || d->use_system_clip;
+ glDepthFunc(GL_LEQUAL);
+ if (state()->depthTestEnabled) {
+ glEnable(GL_DEPTH_TEST);
+ d->simpleShaderDepthUniformDirty = true;
+ d->depthUniformDirty = true;
}
-
- d->updateDepthClip();
}
-void QGL2PaintEngineExPrivate::systemStateChanged()
+void QGL2PaintEngineExPrivate::regenerateDepthClip()
{
- Q_Q(QGL2PaintEngineEx);
- use_system_clip = !systemClip.isEmpty();
-
- if (q->painter()->hasClipping())
- q->updateClipRegion(q->painter()->clipRegion(), Qt::ReplaceClip);
- else
- q->updateClipRegion(QRegion(), Qt::NoClip);
+ systemStateChanged();
+ replayClipOperations();
}
-void QGL2PaintEngineExPrivate::updateDepthClip()
+void QGL2PaintEngineExPrivate::systemStateChanged()
{
-// qDebug("QGL2PaintEngineExPrivate::updateDepthClip()");
-
Q_Q(QGL2PaintEngineEx);
+ use_system_clip = !systemClip.isEmpty();
- q->ensureActive();
glDisable(GL_DEPTH_TEST);
+ q->state()->depthTestEnabled = false;
+ q->state()->scissorTestEnabled = false;
+ q->state()->needsDepthBufferClear = true;
+
glDisable(GL_SCISSOR_TEST);
- if (!q->state()->hasClipping)
- return;
+ q->state()->currentDepth = -0.5f;
+ q->state()->maxDepth = 0.5f;
- const QVector<QRect> rects = q->state()->clipEnabled ? q->state()->clipRegion.rects() : q->systemClip().rects();
- if (rects.size() == 1) {
- QRect fastClip = rects.at(0);
+ if (use_system_clip) {
+ QRect bounds = systemClip.boundingRect();
+ if (systemClip.numRects() == 1
+ && bounds == QRect(0, 0, width, height))
+ {
+ q->state()->needsDepthBufferClear = true;
+ } else {
+ glEnable(GL_SCISSOR_TEST);
- glEnable(GL_SCISSOR_TEST);
+ const int left = bounds.left();
+ const int width = bounds.width();
+ const int bottom = height - (bounds.top() + bounds.height());
+ const int height = bounds.height();
- const int left = fastClip.left();
- const int width = fastClip.width();
- const int bottom = height - (fastClip.bottom() + 1);
- const int height = fastClip.height();
+ glScissor(left, bottom, width, height);
- glScissor(left, bottom, width, height);
- return;
- }
+ QTransform transform = q->state()->matrix;
+ q->state()->matrix = QTransform();
+ q->transformChanged();
- glClearDepth(0x0);
- glDepthMask(true);
- glClear(GL_DEPTH_BUFFER_BIT);
- glClearDepth(0x1);
+ q->state()->needsDepthBufferClear = false;
- glEnable(GL_SCISSOR_TEST);
- for (int i = 0; i < rects.size(); ++i) {
- QRect rect = rects.at(i);
+ glDepthMask(true);
- const int left = rect.left();
- const int width = rect.width();
- const int bottom = height - (rect.bottom() + 1);
- const int height = rect.height();
+ glClearDepth(0);
+ glClear(GL_DEPTH_BUFFER_BIT);
- glScissor(left, bottom, width, height);
+ QPainterPath path;
+ path.addRegion(systemClip);
- glClear(GL_DEPTH_BUFFER_BIT);
- }
- glDisable(GL_SCISSOR_TEST);
+ glDepthFunc(GL_ALWAYS);
+ writeClip(qtVectorPathForPath(path), 0.0f);
+ glDepthFunc(GL_LEQUAL);
- glDepthMask(false);
- glDepthFunc(GL_LEQUAL);
- glEnable(GL_DEPTH_TEST);
-}
+ glEnable(GL_DEPTH_TEST);
+ q->state()->depthTestEnabled = true;
+ q->state()->scissorTestEnabled = true;
+ q->state()->matrix = transform;
+ q->transformChanged();
+ }
+ q->state()->currentDepth = -0.5f;
+ simpleShaderDepthUniformDirty = true;
+ depthUniformDirty = true;
+ }
+}
void QGL2PaintEngineEx::setState(QPainterState *new_state)
{
-// qDebug("QGL2PaintEngineEx::setState()");
+ // qDebug("QGL2PaintEngineEx::setState()");
Q_D(QGL2PaintEngineEx);
QOpenGL2PaintEngineState *s = static_cast<QOpenGL2PaintEngineState *>(new_state);
-
QOpenGL2PaintEngineState *old_state = state();
- const bool needsDepthClipUpdate = !old_state
- || s->clipEnabled != old_state->clipEnabled
- || (s->clipEnabled && s->clipRegion != old_state->clipRegion);
QPaintEngineEx::setState(s);
- if (needsDepthClipUpdate)
- d->updateDepthClip();
+ if (s == d->last_created_state) {
+ d->last_created_state = 0;
+ return;
+ }
d->matrixDirty = true;
d->compositionModeDirty = true;
d->brushTextureDirty = true;
d->brushUniformsDirty = true;
+ d->simpleShaderDepthUniformDirty = true;
+ d->depthUniformDirty = true;
d->simpleShaderMatrixUniformDirty = true;
d->shaderMatrixUniformDirty = true;
+
+ if (old_state && old_state != s && old_state->canRestoreClip) {
+ d->updateDepthScissorTest();
+ glDepthMask(false);
+ glDepthFunc(GL_LEQUAL);
+ s->maxDepth = old_state->maxDepth;
+ } else {
+ d->regenerateDepthClip();
+ }
}
QPainterState *QGL2PaintEngineEx::createState(QPainterState *orig) const
{
+ Q_D(const QGL2PaintEngineEx);
+
QOpenGL2PaintEngineState *s;
if (!orig)
s = new QOpenGL2PaintEngineState();
else
s = new QOpenGL2PaintEngineState(*static_cast<QOpenGL2PaintEngineState *>(orig));
+ d->last_created_state = s;
return s;
}
QOpenGL2PaintEngineState::QOpenGL2PaintEngineState(QOpenGL2PaintEngineState &other)
: QPainterState(other)
{
- clipRegion = other.clipRegion;
- hasClipping = other.hasClipping;
+ needsDepthBufferClear = other.needsDepthBufferClear;
+ depthTestEnabled = other.depthTestEnabled;
+ scissorTestEnabled = other.scissorTestEnabled;
+ currentDepth = other.currentDepth;
+ maxDepth = other.maxDepth;
+ canRestoreClip = other.canRestoreClip;
}
QOpenGL2PaintEngineState::QOpenGL2PaintEngineState()
{
- hasClipping = false;
+ needsDepthBufferClear = true;
+ depthTestEnabled = false;
+ scissorTestEnabled = false;
+ currentDepth = -0.5f;
+ maxDepth = 0.5f;
+ canRestoreClip = true;
}
QOpenGL2PaintEngineState::~QOpenGL2PaintEngineState()
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
index 7213474..db39ced 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
@@ -77,8 +77,15 @@ public:
QOpenGL2PaintEngineState();
~QOpenGL2PaintEngineState();
- QRegion clipRegion;
- bool hasClipping;
+ bool needsDepthBufferClear;
+ qreal depthBufferClearValue;
+
+ bool depthTestEnabled;
+ bool scissorTestEnabled;
+ qreal currentDepth;
+ qreal maxDepth;
+
+ bool canRestoreClip;
};
@@ -116,7 +123,6 @@ public:
Type type() const { return OpenGL; }
- // State stuff is just for clipping and ripped off from QGLPaintEngine
void setState(QPainterState *s);
QPainterState *createState(QPainterState *orig) const;
inline QOpenGL2PaintEngineState *state() {
@@ -125,7 +131,6 @@ public:
inline const QOpenGL2PaintEngineState *state() const {
return static_cast<const QOpenGL2PaintEngineState *>(QPaintEngineEx::state());
}
- void updateClipRegion(const QRegion &clipRegion, Qt::ClipOperation op);
virtual void sync();
private:
@@ -169,7 +174,6 @@ public:
// ^ Composites the bounding rect onto dest buffer
void fillStencilWithVertexArray(QGL2PEXVertexArray& vertexArray, bool useWindingFill);
// ^ Calls drawVertexArrays to render into stencil buffer
- void cleanStencilBuffer(const QGLRect& area);
void prepareForDraw(bool srcPixelsAreOpaque);
@@ -180,9 +184,10 @@ public:
QGLDrawable drawable;
int width, height;
QGLContext *ctx;
-
EngineMode mode;
+ mutable QOpenGL2PaintEngineState *last_created_state;
+
// Dirty flags
bool matrixDirty; // Implies matrix uniforms are also dirty
bool compositionModeDirty;
@@ -190,7 +195,9 @@ public:
bool brushUniformsDirty;
bool simpleShaderMatrixUniformDirty;
bool shaderMatrixUniformDirty;
- bool stencilBuferDirty;
+ bool stencilBufferDirty;
+ bool depthUniformDirty;
+ bool simpleShaderDepthUniformDirty;
const QBrush* currentBrush; // May not be the state's brush!
@@ -206,8 +213,9 @@ public:
QGLEngineShaderManager* shaderManager;
- // Clipping & state stuff stolen from QOpenGLPaintEngine:
- void updateDepthClip();
+ void writeClip(const QVectorPath &path, float depth);
+ void updateDepthScissorTest();
+ void regenerateDepthClip();
void systemStateChanged();
uint use_system_clip : 1;
};
diff --git a/src/opengl/qegl.cpp b/src/opengl/qegl.cpp
index f1ae4ed..290f77c 100644
--- a/src/opengl/qegl.cpp
+++ b/src/opengl/qegl.cpp
@@ -413,12 +413,18 @@ int QEglProperties::value(int name) const
case EGL_RED_SIZE: return 0;
case EGL_GREEN_SIZE: return 0;
case EGL_BLUE_SIZE: return 0;
- case EGL_LUMINANCE_SIZE: return 0;
case EGL_ALPHA_SIZE: return 0;
+#if defined(EGL_LUMINANCE_SIZE)
+ case EGL_LUMINANCE_SIZE: return 0;
+#endif
+#if defined(EGL_ALPHA_MASK_SIZE)
case EGL_ALPHA_MASK_SIZE: return 0;
+#endif
case EGL_BIND_TO_TEXTURE_RGB: return EGL_DONT_CARE;
case EGL_BIND_TO_TEXTURE_RGBA: return EGL_DONT_CARE;
+#if defined(EGL_COLOR_BUFFER_TYPE)
case EGL_COLOR_BUFFER_TYPE: return EGL_RGB_BUFFER;
+#endif
case EGL_CONFIG_CAVEAT: return EGL_DONT_CARE;
case EGL_CONFIG_ID: return EGL_DONT_CARE;
case EGL_DEPTH_SIZE: return 0;
@@ -427,7 +433,9 @@ int QEglProperties::value(int name) const
case EGL_NATIVE_VISUAL_TYPE: return EGL_DONT_CARE;
case EGL_MAX_SWAP_INTERVAL: return EGL_DONT_CARE;
case EGL_MIN_SWAP_INTERVAL: return EGL_DONT_CARE;
+#if defined(EGL_RENDERABLE_TYPE)
case EGL_RENDERABLE_TYPE: return EGL_OPENGL_ES_BIT;
+#endif
case EGL_SAMPLE_BUFFERS: return 0;
case EGL_SAMPLES: return 0;
case EGL_STENCIL_SIZE: return 0;
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 2e72851..146d088 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -65,12 +65,19 @@
#include "qimage.h"
#include "qgl_p.h"
+#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
#include "gl2paintengineex/qpaintengineex_opengl2_p.h"
+#endif
#ifndef QT_OPENGL_ES_2
#include <private/qpaintengine_opengl_p.h>
#endif
+#ifdef Q_WS_QWS
+#include <private/qglpaintdevice_qws_p.h>
+#include <private/qglwindowsurface_qws_p.h>
+#endif
+
#include <qglpixelbuffer.h>
#include <qglframebufferobject.h>
@@ -4428,7 +4435,11 @@ void QGLDrawable::swapBuffers()
void QGLDrawable::makeCurrent()
{
previous_fbo = 0;
+#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
if (!pixmapData && !fbo) {
+#else
+ if (!fbo) {
+#endif
QGLContext *ctx = context();
previous_fbo = ctx->d_ptr->current_fbo;
ctx->d_ptr->current_fbo = 0;
@@ -4561,8 +4572,10 @@ QColor QGLDrawable::backgroundColor() const
{
if (widget)
return widget->palette().brush(widget->backgroundRole()).color();
+#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
else if (pixmapData)
return pixmapData->fillColor();
+#endif
return QApplication::palette().brush(QPalette::Background).color();
}
@@ -4590,8 +4603,10 @@ bool QGLDrawable::autoFillBackground() const
{
if (widget)
return widget->autoFillBackground();
+#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
else if (pixmapData)
return pixmapData->needsFill();
+#endif
else
return false;
}
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index b3523d4..4af8598 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -428,8 +428,7 @@ private:
extern Q_OPENGL_EXPORT QGLShareRegister* qgl_share_reg();
#ifdef Q_WS_QWS
-class QOpenGLPaintEngine;
-extern QOpenGLPaintEngine* qt_qgl_paint_engine();
+extern QPaintEngine* qt_qgl_paint_engine();
extern EGLDisplay qt_qgl_egl_display();
#endif
diff --git a/src/opengl/qglextensions.cpp b/src/opengl/qglextensions.cpp
index 3c198fb..10ca613 100644
--- a/src/opengl/qglextensions.cpp
+++ b/src/opengl/qglextensions.cpp
@@ -337,6 +337,9 @@ bool qt_resolve_version_2_0_functions(QGLContext *ctx)
if (!qt_resolve_version_1_3_functions(ctx))
gl2supported = false;
+ if (!qt_resolve_framebufferobject_extensions(ctx))
+ gl2supported = false;
+
if (glStencilOpSeparate)
return gl2supported;
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index 3e7ca0a..fb16107 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -43,7 +43,9 @@
#include <qdebug.h>
#include <private/qgl_p.h>
+#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
#include <private/qpaintengineex_opengl2_p.h>
+#endif
#ifndef QT_OPENGL_ES_2
#include <private/qpaintengine_opengl_p.h>
diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp
index 483856a..9b7a506 100644
--- a/src/opengl/qglpixelbuffer.cpp
+++ b/src/opengl/qglpixelbuffer.cpp
@@ -76,7 +76,11 @@
\sa {opengl/pbuffers}{Pbuffers Example}
*/
+#include <QtCore/qglobal.h>
+
+#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
#include <private/qpaintengineex_opengl2_p.h>
+#endif
#include <qglpixelbuffer.h>
#include <private/qglpixelbuffer_p.h>
diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp
index 8d94c8b..98c406b 100644
--- a/src/opengl/qpixmapdata_gl.cpp
+++ b/src/opengl/qpixmapdata_gl.cpp
@@ -389,6 +389,11 @@ QPaintEngine* QGLPixmapData::paintEngine() const
sz.setWidth(qMax(m_width, qRound(sz.width() * 1.5)));
if (sz.height() < m_height)
sz.setHeight(qMax(m_height, qRound(sz.height() * 1.5)));
+
+ // wasting too much space?
+ if (sz.width() * sz.height() > m_width * m_height * 2.5)
+ sz = QSize(m_width, m_height);
+
delete textureBufferStack.at(currentTextureBuffer).fbo;
textureBufferStack[currentTextureBuffer] =
createTextureBuffer(sz, textureBufferStack.at(currentTextureBuffer).engine);
diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
index 6d0bc1f..088ef97 100644
--- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp
+++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
@@ -781,7 +781,8 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage,
#ifndef QT_NO_IMAGE_SMOOTHSCALE
// If high quality not required, shrink image during decompression
- if (scaledSize.isValid() && quality < HIGH_QUALITY_THRESHOLD && !params.contains(QLatin1String("GetHeaderInformation")) ) {
+ if (scaledSize.isValid() && !scaledSize.isEmpty() && quality < HIGH_QUALITY_THRESHOLD
+ && !params.contains(QLatin1String("GetHeaderInformation")) ) {
cinfo.scale_denom = qMin(cinfo.image_width / scaledSize.width(),
cinfo.image_width / scaledSize.height());
if (cinfo.scale_denom < 2) {
diff --git a/src/plugins/imageformats/tiff/qtiffhandler.cpp b/src/plugins/imageformats/tiff/qtiffhandler.cpp
index 77dfeb3..791aeaa 100644
--- a/src/plugins/imageformats/tiff/qtiffhandler.cpp
+++ b/src/plugins/imageformats/tiff/qtiffhandler.cpp
@@ -131,58 +131,138 @@ bool QTiffHandler::read(QImage *image)
if (!canRead())
return false;
- TIFF *tiff = TIFFClientOpen("foo",
- "r",
- this,
- qtiffReadProc,
- qtiffWriteProc,
- qtiffSeekProc,
- qtiffCloseProc,
- qtiffSizeProc,
- qtiffMapProc,
- qtiffUnmapProc);
-
- if (tiff) {
- uint32 width = 0;
- uint32 height = 0;
- TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &width);
- TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &height);
- if (image->size() != QSize(width, height) || image->format() != QImage::Format_ARGB32)
- *image = QImage(width, height, QImage::Format_ARGB32);
+ TIFF *const tiff = TIFFClientOpen("foo",
+ "r",
+ this,
+ qtiffReadProc,
+ qtiffWriteProc,
+ qtiffSeekProc,
+ qtiffCloseProc,
+ qtiffSizeProc,
+ qtiffMapProc,
+ qtiffUnmapProc);
+
+ if (!tiff) {
+ return false;
+ }
+ uint32 width;
+ uint32 height;
+ uint16 photometric;
+ if (!TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &width)
+ || !TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &height)
+ || !TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric)) {
+ TIFFClose(tiff);
+ return false;
+ }
+
+ if (photometric == PHOTOMETRIC_MINISBLACK || photometric == PHOTOMETRIC_MINISWHITE) {
+ if (image->size() != QSize(width, height) || image->format() != QImage::Format_Mono)
+ *image = QImage(width, height, QImage::Format_Mono);
+ QVector<QRgb> colortable(2);
+ if (photometric == PHOTOMETRIC_MINISBLACK) {
+ colortable[0] = 0xff000000;
+ colortable[1] = 0xffffffff;
+ } else {
+ colortable[0] = 0xffffffff;
+ colortable[1] = 0xff000000;
+ }
+ image->setColorTable(colortable);
+
if (!image->isNull()) {
- if (TIFFReadRGBAImageOriented(tiff, width, height, reinterpret_cast<uint32 *>(image->bits()), ORIENTATION_TOPLEFT, 0)) {
- uint16 resUnit = RESUNIT_NONE;
- float resX = 0;
- float resY = 0;
- TIFFGetField(tiff, TIFFTAG_RESOLUTIONUNIT, &resUnit);
- TIFFGetField(tiff, TIFFTAG_XRESOLUTION, &resX);
- TIFFGetField(tiff, TIFFTAG_YRESOLUTION, &resY);
- switch(resUnit) {
- case RESUNIT_CENTIMETER:
- image->setDotsPerMeterX(qRound(resX * 100));
- image->setDotsPerMeterY(qRound(resY * 100));
- break;
- case RESUNIT_INCH:
- image->setDotsPerMeterX(qRound(resX * (100 / 2.54)));
- image->setDotsPerMeterY(qRound(resY * (100 / 2.54)));
- break;
- default:
- // do nothing as defaults have already
- // been set within the QImage class
- break;
+ for (uint32 y=0; y<height; ++y) {
+ if (TIFFReadScanline(tiff, image->scanLine(y), y, 0) < 0) {
+ TIFFClose(tiff);
+ return false;
+ }
+ }
+ }
+ } else {
+ uint16 bitPerSample;
+ if (!TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bitPerSample)) {
+ TIFFClose(tiff);
+ return false;
+ }
+ if (photometric == PHOTOMETRIC_PALETTE && bitPerSample == 8) {
+ if (image->size() != QSize(width, height) || image->format() != QImage::Format_Indexed8)
+ *image = QImage(width, height, QImage::Format_Indexed8);
+ if (!image->isNull()) {
+ // create the color table
+ const uint16 tableSize = 256;
+ uint16 *redTable = static_cast<uint16 *>(qMalloc(tableSize * sizeof(uint16)));
+ uint16 *greenTable = static_cast<uint16 *>(qMalloc(tableSize * sizeof(uint16)));
+ uint16 *blueTable = static_cast<uint16 *>(qMalloc(tableSize * sizeof(uint16)));
+ if (!redTable || !greenTable || !blueTable) {
+ TIFFClose(tiff);
+ return false;
+ }
+ if (!TIFFGetField(tiff, TIFFTAG_COLORMAP, &redTable, &greenTable, &blueTable)) {
+ TIFFClose(tiff);
+ return false;
+ }
+
+ QVector<QRgb> qtColorTable(tableSize);
+ for (int i = 0; i<tableSize ;++i) {
+ const int red = redTable[i] / 257;
+ const int green = greenTable[i] / 257;
+ const int blue = blueTable[i] / 257;
+ qtColorTable[i] = qRgb(red, green, blue);
+
+ }
+
+ image->setColorTable(qtColorTable);
+ for (uint32 y=0; y<height; ++y) {
+ if (TIFFReadScanline(tiff, image->scanLine(y), y, 0) < 0) {
+ TIFFClose(tiff);
+ return false;
+ }
+ }
+
+ // free redTable, greenTable and greenTable done by libtiff
+ }
+ } else {
+ if (image->size() != QSize(width, height) || image->format() != QImage::Format_ARGB32)
+ *image = QImage(width, height, QImage::Format_ARGB32);
+ if (!image->isNull()) {
+ if (TIFFReadRGBAImageOriented(tiff, width, height, reinterpret_cast<uint32 *>(image->bits()), ORIENTATION_TOPLEFT, 0)) {
+ for (uint32 y=0; y<height; ++y)
+ convert32BitOrder(image->scanLine(y), width);
+ } else {
+ TIFFClose(tiff);
+ return false;
}
- for (uint32 y=0; y<height; ++y)
- convert32BitOrder(image->scanLine(y), width);
- } else {
- *image = QImage();
}
}
- TIFFClose(tiff);
}
- if (image->isNull())
+ if (image->isNull()) {
+ TIFFClose(tiff);
return false;
+ }
+
+ float resX = 0;
+ float resY = 0;
+ uint16 resUnit = RESUNIT_NONE;
+ if (TIFFGetField(tiff, TIFFTAG_RESOLUTIONUNIT, &resUnit)
+ && TIFFGetField(tiff, TIFFTAG_XRESOLUTION, &resX)
+ && TIFFGetField(tiff, TIFFTAG_YRESOLUTION, &resY)) {
+
+ switch(resUnit) {
+ case RESUNIT_CENTIMETER:
+ image->setDotsPerMeterX(qRound(resX * 100));
+ image->setDotsPerMeterY(qRound(resY * 100));
+ break;
+ case RESUNIT_INCH:
+ image->setDotsPerMeterX(qRound(resX * (100 / 2.54)));
+ image->setDotsPerMeterY(qRound(resY * (100 / 2.54)));
+ break;
+ default:
+ // do nothing as defaults have already
+ // been set within the QImage class
+ break;
+ }
+ }
+ TIFFClose(tiff);
return true;
}
@@ -191,48 +271,145 @@ bool QTiffHandler::write(const QImage &image)
if (!device()->isWritable())
return false;
- TIFF *tiff = TIFFClientOpen("foo",
- "w",
- this,
- qtiffReadProc,
- qtiffWriteProc,
- qtiffSeekProc,
- qtiffCloseProc,
- qtiffSizeProc,
- qtiffMapProc,
- qtiffUnmapProc);
-
- if (tiff) {
- int width = image.width();
- int height = image.height();
- int depth = 32;
-
- if (!TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, width)
- || !TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, height)
- || !TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB)
- || !TIFFSetField(tiff, TIFFTAG_COMPRESSION, compression == NoCompression ? COMPRESSION_NONE : COMPRESSION_LZW)
- || !TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, depth/8)
- || !TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG)
- || !TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 8)) {
+ TIFF *const tiff = TIFFClientOpen("foo",
+ "w",
+ this,
+ qtiffReadProc,
+ qtiffWriteProc,
+ qtiffSeekProc,
+ qtiffCloseProc,
+ qtiffSizeProc,
+ qtiffMapProc,
+ qtiffUnmapProc);
+ if (!tiff)
+ return false;
+
+ const int width = image.width();
+ const int height = image.height();
+
+ if (!TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, width)
+ || !TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, height)
+ || !TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG)) {
+ TIFFClose(tiff);
+ return false;
+ }
+
+ // set the resolution
+ bool resolutionSet = false;
+ const int dotPerMeterX = image.dotsPerMeterX();
+ const int dotPerMeterY = image.dotsPerMeterY();
+ if ((dotPerMeterX % 100) == 0
+ && (dotPerMeterY % 100) == 0) {
+ resolutionSet = TIFFSetField(tiff, TIFFTAG_RESOLUTIONUNIT, RESUNIT_CENTIMETER)
+ && TIFFSetField(tiff, TIFFTAG_XRESOLUTION, dotPerMeterX/100.0)
+ && TIFFSetField(tiff, TIFFTAG_YRESOLUTION, dotPerMeterY/100.0);
+ } else {
+ resolutionSet = TIFFSetField(tiff, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH)
+ && TIFFSetField(tiff, TIFFTAG_XRESOLUTION, static_cast<float>(image.logicalDpiX()))
+ && TIFFSetField(tiff, TIFFTAG_YRESOLUTION, static_cast<float>(image.logicalDpiY()));
+ }
+ if (!resolutionSet) {
+ TIFFClose(tiff);
+ return false;
+ }
+
+ // configure image depth
+ const QImage::Format format = image.format();
+ if (format == QImage::Format_Mono || format == QImage::Format_MonoLSB) {
+ uint16 photometric = PHOTOMETRIC_MINISBLACK;
+ if (image.colorTable().at(0) == 0xffffffff)
+ photometric = PHOTOMETRIC_MINISWHITE;
+ if (!TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, photometric)
+ || !TIFFSetField(tiff, TIFFTAG_COMPRESSION, compression == NoCompression ? COMPRESSION_NONE : COMPRESSION_CCITTRLE)) {
TIFFClose(tiff);
return false;
}
- // set the resolution
- bool resolutionSet = false;
- const int dotPerMeterX = image.dotsPerMeterX();
- const int dotPerMeterY = image.dotsPerMeterY();
- if ((dotPerMeterX % 100) == 0
- && (dotPerMeterY % 100) == 0) {
- resolutionSet = TIFFSetField(tiff, TIFFTAG_RESOLUTIONUNIT, RESUNIT_CENTIMETER)
- && TIFFSetField(tiff, TIFFTAG_XRESOLUTION, dotPerMeterX/100.0)
- && TIFFSetField(tiff, TIFFTAG_YRESOLUTION, dotPerMeterY/100.0);
- } else {
- resolutionSet = TIFFSetField(tiff, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH)
- && TIFFSetField(tiff, TIFFTAG_XRESOLUTION, static_cast<float>(image.logicalDpiX()))
- && TIFFSetField(tiff, TIFFTAG_YRESOLUTION, static_cast<float>(image.logicalDpiY()));
+ // try to do the conversion in chunks no greater than 16 MB
+ int chunks = (width * height / (1024 * 1024 * 16)) + 1;
+ int chunkHeight = qMax(height / chunks, 1);
+
+ int y = 0;
+ while (y < height) {
+ QImage chunk = image.copy(0, y, width, qMin(chunkHeight, height - y)).convertToFormat(QImage::Format_Mono);
+
+ int chunkStart = y;
+ int chunkEnd = y + chunk.height();
+ while (y < chunkEnd) {
+ if (TIFFWriteScanline(tiff, reinterpret_cast<uint32 *>(chunk.scanLine(y - chunkStart)), y) != 1) {
+ TIFFClose(tiff);
+ return false;
+ }
+ ++y;
+ }
+ }
+ TIFFClose(tiff);
+ } else if (format == QImage::Format_Indexed8) {
+ if (!TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_PALETTE)
+ || !TIFFSetField(tiff, TIFFTAG_COMPRESSION, compression == NoCompression ? COMPRESSION_NONE : COMPRESSION_PACKBITS)
+ || !TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 8)) {
+ TIFFClose(tiff);
+ return false;
+ }
+ //// write the color table
+ // allocate the color tables
+ uint16 *redTable = static_cast<uint16 *>(qMalloc(256 * sizeof(uint16)));
+ uint16 *greenTable = static_cast<uint16 *>(qMalloc(256 * sizeof(uint16)));
+ uint16 *blueTable = static_cast<uint16 *>(qMalloc(256 * sizeof(uint16)));
+ if (!redTable || !greenTable || !blueTable) {
+ TIFFClose(tiff);
+ return false;
+ }
+
+ // set the color table
+ const QVector<QRgb> colorTable = image.colorTable();
+
+ const int tableSize = colorTable.size();
+ Q_ASSERT(tableSize <= 256);
+ for (int i = 0; i<tableSize; ++i) {
+ const QRgb color = colorTable.at(i);
+ redTable[i] = qRed(color) * 257;
+ greenTable[i] = qGreen(color) * 257;
+ blueTable[i] = qBlue(color) * 257;
+ }
+
+ const bool setColorTableSuccess = TIFFSetField(tiff, TIFFTAG_COLORMAP, redTable, greenTable, blueTable);
+
+ qFree(redTable);
+ qFree(greenTable);
+ qFree(blueTable);
+
+ if (!setColorTableSuccess) {
+ TIFFClose(tiff);
+ return false;
+ }
+
+ //// write the data
+ // try to do the conversion in chunks no greater than 16 MB
+ int chunks = (width * height/ (1024 * 1024 * 16)) + 1;
+ int chunkHeight = qMax(height / chunks, 1);
+
+ int y = 0;
+ while (y < height) {
+ QImage chunk = image.copy(0, y, width, qMin(chunkHeight, height - y));
+
+ int chunkStart = y;
+ int chunkEnd = y + chunk.height();
+ while (y < chunkEnd) {
+ if (TIFFWriteScanline(tiff, reinterpret_cast<uint32 *>(chunk.scanLine(y - chunkStart)), y) != 1) {
+ TIFFClose(tiff);
+ return false;
+ }
+ ++y;
+ }
}
- if (!resolutionSet) {
+ TIFFClose(tiff);
+
+ } else {
+ if (!TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB)
+ || !TIFFSetField(tiff, TIFFTAG_COMPRESSION, compression == NoCompression ? COMPRESSION_NONE : COMPRESSION_LZW)
+ || !TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 4)
+ || !TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 8)) {
TIFFClose(tiff);
return false;
}
@@ -260,9 +437,8 @@ bool QTiffHandler::write(const QImage &image)
}
}
TIFFClose(tiff);
- } else {
- return false;
}
+
return true;
}
diff --git a/tests/auto/bic/bic.pro b/tests/auto/bic/bic.pro
index a168d77..82711c9 100644
--- a/tests/auto/bic/bic.pro
+++ b/tests/auto/bic/bic.pro
@@ -2,3 +2,9 @@ load(qttest_p4)
SOURCES += tst_bic.cpp qbic.cpp
QT = core
+wince*:{
+ DEFINES += SRCDIR=\\\"\\\"
+} else {
+ DEFINES += SRCDIR=\\\"$$PWD/\\\"
+}
+
diff --git a/tests/auto/bic/tst_bic.cpp b/tests/auto/bic/tst_bic.cpp
index 181c275..8bc8d4f 100644
--- a/tests/auto/bic/tst_bic.cpp
+++ b/tests/auto/bic/tst_bic.cpp
@@ -165,30 +165,30 @@ void tst_Bic::sizesAndVTables_data()
#if defined Q_OS_LINUX && defined Q_WS_X11
# if defined(__powerpc__) && !defined(__powerpc64__)
- archFileName400 = "data/%1.4.0.0.linux-gcc-ppc32.txt";
- archFileName410 = "data/%1.4.1.0.linux-gcc-ppc32.txt";
- archFileName420 = "data/%1.4.2.0.linux-gcc-ppc32.txt";
+ archFileName400 = SRCDIR "data/%1.4.0.0.linux-gcc-ppc32.txt";
+ archFileName410 = SRCDIR "data/%1.4.1.0.linux-gcc-ppc32.txt";
+ archFileName420 = SRCDIR "data/%1.4.2.0.linux-gcc-ppc32.txt";
# elif defined(__amd64__)
- archFileName400 = "data/%1.4.0.0.linux-gcc-amd64.txt";
+ archFileName400 = SRCDIR "data/%1.4.0.0.linux-gcc-amd64.txt";
# elif defined(__i386__)
- archFileName400 = "data/%1.4.0.0.linux-gcc-ia32.txt";
- archFileName410 = "data/%1.4.1.0.linux-gcc-ia32.txt";
- archFileName420 = "data/%1.4.2.0.linux-gcc-ia32.txt";
- archFileName430 = "data/%1.4.3.0.linux-gcc-ia32.txt";
+ archFileName400 = SRCDIR "data/%1.4.0.0.linux-gcc-ia32.txt";
+ archFileName410 = SRCDIR "data/%1.4.1.0.linux-gcc-ia32.txt";
+ archFileName420 = SRCDIR "data/%1.4.2.0.linux-gcc-ia32.txt";
+ archFileName430 = SRCDIR "data/%1.4.3.0.linux-gcc-ia32.txt";
# endif
#elif defined Q_OS_AIX
if (sizeof(void*) == 4)
- archFileName400 = "data/%1.4.0.0.aix-gcc-power32.txt";
+ archFileName400 = SRCDIR "data/%1.4.0.0.aix-gcc-power32.txt";
#elif defined Q_OS_MAC && defined(__powerpc__)
- archFileName400 = "data/%1.4.0.0.macx-gcc-ppc32.txt";
- archFileName410 = "data/%1.4.1.0.macx-gcc-ppc32.txt";
- archFileName420 = "data/%1.4.2.0.macx-gcc-ppc32.txt";
+ archFileName400 = SRCDIR "data/%1.4.0.0.macx-gcc-ppc32.txt";
+ archFileName410 = SRCDIR "data/%1.4.1.0.macx-gcc-ppc32.txt";
+ archFileName420 = SRCDIR "data/%1.4.2.0.macx-gcc-ppc32.txt";
#elif defined Q_OS_MAC && defined(__i386__)
- archFileName410 = "data/%1.4.1.0.macx-gcc-ia32.txt";
- archFileName420 = "data/%1.4.2.0.macx-gcc-ia32.txt";
+ archFileName410 = SRCDIR "data/%1.4.1.0.macx-gcc-ia32.txt";
+ archFileName420 = SRCDIR "data/%1.4.2.0.macx-gcc-ia32.txt";
#elif defined Q_OS_WIN && defined Q_CC_GNU
- archFileName410 = "data/%1.4.1.0.win32-gcc-ia32.txt";
- archFileName420 = "data/%1.4.2.0.win32-gcc-ia32.txt";
+ archFileName410 = SRCDIR "data/%1.4.1.0.win32-gcc-ia32.txt";
+ archFileName420 = SRCDIR "data/%1.4.2.0.win32-gcc-ia32.txt";
#endif
if (archFileName400.isEmpty() && archFileName410.isEmpty()
@@ -293,6 +293,7 @@ void tst_Bic::sizesAndVTables()
bool isFailed = false;
+ qDebug() << oldLib.arg(libName);
if (oldLib.isEmpty() || !QFile::exists(oldLib.arg(libName)))
QSKIP("No platform spec found for this platform/version.", SkipSingle);
diff --git a/tests/auto/declarative/numberformatter/tst_numberformatter.cpp b/tests/auto/declarative/numberformatter/tst_numberformatter.cpp
index e70d651..9a2f4f3 100644
--- a/tests/auto/declarative/numberformatter/tst_numberformatter.cpp
+++ b/tests/auto/declarative/numberformatter/tst_numberformatter.cpp
@@ -1,4 +1,5 @@
#include <qtest.h>
+#include <QDebug>
#include <QtDeclarative/qmlengine.h>
#include <QtDeclarative/qmlcomponent.h>
#include <QtDeclarative/qnumberformat.h>
diff --git a/tests/auto/math3d/qmatrixnxn/tst_qmatrixnxn.cpp b/tests/auto/math3d/qmatrixnxn/tst_qmatrixnxn.cpp
index 4d51e89..dd3e396 100644
--- a/tests/auto/math3d/qmatrixnxn/tst_qmatrixnxn.cpp
+++ b/tests/auto/math3d/qmatrixnxn/tst_qmatrixnxn.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the $MODULE$ of the Qt Toolkit.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/tests/auto/math3d/qquaternion/tst_qquaternion.cpp b/tests/auto/math3d/qquaternion/tst_qquaternion.cpp
index f25f858..5d70e4d 100644
--- a/tests/auto/math3d/qquaternion/tst_qquaternion.cpp
+++ b/tests/auto/math3d/qquaternion/tst_qquaternion.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the $MODULE$ of the Qt Toolkit.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/tests/auto/math3d/qvectornd/tst_qvectornd.cpp b/tests/auto/math3d/qvectornd/tst_qvectornd.cpp
index a092fb0..f7d2411 100644
--- a/tests/auto/math3d/qvectornd/tst_qvectornd.cpp
+++ b/tests/auto/math3d/qvectornd/tst_qvectornd.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the $MODULE$ of the Qt Toolkit.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/tests/auto/math3d/shared/math3dincludes.h b/tests/auto/math3d/shared/math3dincludes.h
index 1ac0c08..a77090b 100644
--- a/tests/auto/math3d/shared/math3dincludes.h
+++ b/tests/auto/math3d/shared/math3dincludes.h
@@ -3,7 +3,7 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the $MODULE$ of the Qt Toolkit.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/tests/auto/qcssparser/tst_cssparser.cpp b/tests/auto/qcssparser/tst_cssparser.cpp
index b41a745..27258b7 100644
--- a/tests/auto/qcssparser/tst_cssparser.cpp
+++ b/tests/auto/qcssparser/tst_cssparser.cpp
@@ -114,11 +114,52 @@ void tst_CssParser::scanner_data()
}
}
+
+static char *tokenName(QCss::TokenType t)
+{
+ switch (t) {
+ case QCss::NONE: return "NONE";
+ case QCss::S: return "S";
+ case QCss::CDO: return "CDO";
+ case QCss::CDC: return "CDC";
+ case QCss::INCLUDES: return "INCLUDES";
+ case QCss::DASHMATCH: return "DASHMATCH";
+ case QCss::LBRACE: return "LBRACE";
+ case QCss::PLUS: return "PLUS";
+ case QCss::GREATER: return "GREATER";
+ case QCss::COMMA: return "COMMA";
+ case QCss::STRING: return "STRING";
+ case QCss::INVALID: return "INVALID";
+ case QCss::IDENT: return "IDENT";
+ case QCss::HASH: return "HASH";
+ case QCss::ATKEYWORD_SYM: return "ATKEYWORD_SYM";
+ case QCss::EXCLAMATION_SYM: return "EXCLAMATION_SYM";
+ case QCss::LENGTH: return "LENGTH";
+ case QCss::PERCENTAGE: return "PERCENTAGE";
+ case QCss::NUMBER: return "NUMBER";
+ case QCss::FUNCTION: return "FUNCTION";
+ case QCss::COLON: return "COLON";
+ case QCss::SEMICOLON: return "SEMICOLON";
+ case QCss::RBRACE: return "RBRACE";
+ case QCss::SLASH: return "SLASH";
+ case QCss::MINUS: return "MINUS";
+ case QCss::DOT: return "DOT";
+ case QCss::STAR: return "STAR";
+ case QCss::LBRACKET: return "LBRACKET";
+ case QCss::RBRACKET: return "RBRACKET";
+ case QCss::EQUAL: return "EQUAL";
+ case QCss::LPAREN: return "LPAREN";
+ case QCss::RPAREN: return "RPAREN";
+ case QCss::OR: return "OR";
+ }
+ return "";
+}
+
static void debug(const QVector<QCss::Symbol> &symbols, int index = -1)
{
qDebug() << "all symbols:";
for (int i = 0; i < symbols.count(); ++i)
- qDebug() << "(" << i << "); Token:" << QCss::Scanner::tokenName(symbols.at(i).token) << "; Lexem:" << symbols.at(i).lexem();
+ qDebug() << "(" << i << "); Token:" << tokenName(symbols.at(i).token) << "; Lexem:" << symbols.at(i).lexem();
if (index != -1)
qDebug() << "failure at index" << index;
}
@@ -160,7 +201,7 @@ void tst_CssParser::scanner()
QCOMPARE(l.count(), 2);
const QString expectedToken = l.at(0);
const QString expectedLexem = l.at(1);
- QString actualToken = QString::fromLatin1(QCss::Scanner::tokenName(symbols.at(i).token));
+ QString actualToken = QString::fromLatin1(tokenName(symbols.at(i).token));
if (actualToken != expectedToken) {
debug(symbols, i);
QCOMPARE(actualToken, expectedToken);
diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp
index 3d7e6f8..cccdd64 100644
--- a/tests/auto/qfileinfo/tst_qfileinfo.cpp
+++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp
@@ -61,6 +61,7 @@
#include <qdebug.h>
#include "../network-settings.h"
+#include <private/qfileinfo_p.h>
//TESTED_CLASS=
//TESTED_FILES=
@@ -75,6 +76,9 @@ public:
private slots:
void getSetCheck();
+
+ void copy();
+
void isFile_data();
void isFile();
@@ -178,6 +182,58 @@ void tst_QFileInfo::getSetCheck()
QCOMPARE(true, obj1.caching());
}
+static QFileInfoPrivate* getPrivate(QFileInfo &info)
+{
+ return (*reinterpret_cast<QFileInfoPrivate**>(&info));
+}
+
+void tst_QFileInfo::copy()
+{
+ QTemporaryFile *t;
+ t = new QTemporaryFile;
+ t->open();
+ QFileInfo info(t->fileName());
+ QVERIFY(info.exists());
+
+ //copy constructor
+ QFileInfo info2(info);
+ QFileInfoPrivate *privateInfo = getPrivate(info);
+ QFileInfoPrivate *privateInfo2 = getPrivate(info2);
+ QCOMPARE(privateInfo->data, privateInfo2->data);
+
+ //operator =
+ QFileInfo info3 = info;
+ QFileInfoPrivate *privateInfo3 = getPrivate(info3);
+ QCOMPARE(privateInfo->data, privateInfo3->data);
+ QCOMPARE(privateInfo2->data, privateInfo3->data);
+
+ //refreshing info3 will detach it
+ QFile file(info.absoluteFilePath());
+ QVERIFY(file.open(QFile::WriteOnly));
+ QCOMPARE(file.write("JAJAJAA"), qint64(7));
+ file.flush();
+
+ QTest::qWait(250);
+#if defined(Q_OS_WIN) || defined(Q_OS_WINCE)
+ if (QSysInfo::windowsVersion() & QSysInfo::WV_VISTA ||
+ QSysInfo::windowsVersion() & QSysInfo::WV_CE_based)
+ file.close();
+#endif
+#if defined(Q_OS_WINCE)
+ // On Windows CE we need to close the file.
+ // Otherwise the content will be cached and not
+ // flushed to the storage, although we flushed it
+ // manually!!! CE has interim cache, we cannot influence.
+ QTest::qWait(5000);
+#endif
+ info3.refresh();
+ QVERIFY(privateInfo->data != privateInfo3->data);
+ QVERIFY(privateInfo2->data != privateInfo3->data);
+ QCOMPARE(privateInfo->data, privateInfo2->data);
+
+
+}
+
tst_QFileInfo::tst_QFileInfo()
{
}
diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
index 8afdeb4..481dc6b 100644
--- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
+++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
@@ -44,6 +44,7 @@
#include <private/qtextcontrol_p.h>
#include <private/qgraphicsitem_p.h>
+#include <QStyleOptionGraphicsItem>
#include <QAbstractTextDocumentLayout>
#include <QBitmap>
#include <QCursor>
@@ -219,8 +220,14 @@ private slots:
void updateCachedItemAfterMove();
void deviceTransform_data();
void deviceTransform();
+ void update();
void setTransformProperties_data();
void setTransformProperties();
+ void itemUsesExtendedStyleOption();
+ void itemSendsGeometryChanges();
+ void moveItem();
+ void sorting_data();
+ void sorting();
// task specific tests below me
void task141694_textItemEnsureVisible();
@@ -231,6 +238,9 @@ private slots:
void task240400_clickOnTextItem();
void task243707_addChildBeforeParent();
void task197802_childrenVisibility();
+
+private:
+ QList<QGraphicsItem *> paintedItems;
};
void tst_QGraphicsItem::init()
@@ -1790,15 +1800,15 @@ void tst_QGraphicsItem::setMatrix()
QCOMPARE(rlist.at(2), unrotatedRect); // From post-update (update current state)
}
-static QList<QGraphicsItem *> paintedItems;
+static QList<QGraphicsItem *> _paintedItems;
class PainterItem : public QGraphicsItem
{
protected:
QRectF boundingRect() const
{ return QRectF(-10, -10, 20, 20); }
- void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *)
- { paintedItems << this; }
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
+ { _paintedItems << this; painter->fillRect(boundingRect(), Qt::red); }
};
void tst_QGraphicsItem::zValue()
@@ -1830,10 +1840,10 @@ void tst_QGraphicsItem::zValue()
QApplication::sendPostedEvents(); //glib workaround
#endif
- QVERIFY(!paintedItems.isEmpty());
- QVERIFY((paintedItems.size() % 4) == 0);
+ QVERIFY(!_paintedItems.isEmpty());
+ QVERIFY((_paintedItems.size() % 4) == 0);
for (int i = 0; i < 3; ++i)
- QVERIFY(paintedItems.at(i)->zValue() < paintedItems.at(i + 1)->zValue());
+ QVERIFY(_paintedItems.at(i)->zValue() < _paintedItems.at(i + 1)->zValue());
}
void tst_QGraphicsItem::shape()
@@ -3726,8 +3736,20 @@ void tst_QGraphicsItem::defaultItemTest_QGraphicsEllipseItem()
class ItemChangeTester : public QGraphicsRectItem
{
public:
- ItemChangeTester(){}
- ItemChangeTester(QGraphicsItem *parent) : QGraphicsRectItem(parent) {}
+ ItemChangeTester()
+ { setFlag(ItemSendsGeometryChanges); clear(); }
+ ItemChangeTester(QGraphicsItem *parent) : QGraphicsRectItem(parent)
+ { setFlag(ItemSendsGeometryChanges); clear(); }
+
+ void clear()
+ {
+ itemChangeReturnValue = QVariant();
+ itemSceneChangeTargetScene = 0;
+ changes.clear();
+ values.clear();
+ oldValues.clear();
+ }
+
QVariant itemChangeReturnValue;
QGraphicsScene *itemSceneChangeTargetScene;
@@ -3928,7 +3950,8 @@ void tst_QGraphicsItem::itemChange()
QCOMPARE(tester.changes.size(), changeCount);
QCOMPARE(tester.changes.at(tester.changes.size() - 2), QGraphicsItem::ItemFlagsChange);
QCOMPARE(tester.changes.at(tester.changes.size() - 1), QGraphicsItem::ItemFlagsHaveChanged);
- QCOMPARE(tester.values.at(tester.values.size() - 2), qVariantFromValue<quint32>(QGraphicsItem::ItemIsSelectable));
+ QVariant expectedFlags = qVariantFromValue<quint32>(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
+ QCOMPARE(tester.values.at(tester.values.size() - 2), expectedFlags);
QCOMPARE(tester.values.at(tester.values.size() - 1), qVariantFromValue<quint32>(QGraphicsItem::ItemIsSelectable));
}
{
@@ -5775,19 +5798,36 @@ void tst_QGraphicsItem::opacity2()
QCOMPARE(grandChild->repaints, 0);
}
+class StacksBehindParentHelper : public QGraphicsRectItem
+{
+public:
+ StacksBehindParentHelper(QList<QGraphicsItem *> *paintedItems, const QRectF &rect, QGraphicsItem *parent = 0)
+ : QGraphicsRectItem(rect, parent), paintedItems(paintedItems)
+ { }
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+ {
+ QGraphicsRectItem::paint(painter, option, widget);
+ paintedItems->append(this);
+ }
+
+private:
+ QList<QGraphicsItem *> *paintedItems;
+};
+
void tst_QGraphicsItem::itemStacksBehindParent()
{
- QGraphicsRectItem *parent1 = new QGraphicsRectItem(QRectF(0, 0, 100, 50));
- QGraphicsRectItem *child11 = new QGraphicsRectItem(QRectF(-10, 10, 50, 50), parent1);
- QGraphicsRectItem *grandChild111 = new QGraphicsRectItem(QRectF(-20, 20, 50, 50), child11);
- QGraphicsRectItem *child12 = new QGraphicsRectItem(QRectF(60, 10, 50, 50), parent1);
- QGraphicsRectItem *grandChild121 = new QGraphicsRectItem(QRectF(70, 20, 50, 50), child12);
+ StacksBehindParentHelper *parent1 = new StacksBehindParentHelper(&paintedItems, QRectF(0, 0, 100, 50));
+ StacksBehindParentHelper *child11 = new StacksBehindParentHelper(&paintedItems, QRectF(-10, 10, 50, 50), parent1);
+ StacksBehindParentHelper *grandChild111 = new StacksBehindParentHelper(&paintedItems, QRectF(-20, 20, 50, 50), child11);
+ StacksBehindParentHelper *child12 = new StacksBehindParentHelper(&paintedItems, QRectF(60, 10, 50, 50), parent1);
+ StacksBehindParentHelper *grandChild121 = new StacksBehindParentHelper(&paintedItems, QRectF(70, 20, 50, 50), child12);
- QGraphicsRectItem *parent2 = new QGraphicsRectItem(QRectF(0, 0, 100, 50));
- QGraphicsRectItem *child21 = new QGraphicsRectItem(QRectF(-10, 10, 50, 50), parent2);
- QGraphicsRectItem *grandChild211 = new QGraphicsRectItem(QRectF(-20, 20, 50, 50), child21);
- QGraphicsRectItem *child22 = new QGraphicsRectItem(QRectF(60, 10, 50, 50), parent2);
- QGraphicsRectItem *grandChild221 = new QGraphicsRectItem(QRectF(70, 20, 50, 50), child22);
+ StacksBehindParentHelper *parent2 = new StacksBehindParentHelper(&paintedItems, QRectF(0, 0, 100, 50));
+ StacksBehindParentHelper *child21 = new StacksBehindParentHelper(&paintedItems, QRectF(-10, 10, 50, 50), parent2);
+ StacksBehindParentHelper *grandChild211 = new StacksBehindParentHelper(&paintedItems, QRectF(-20, 20, 50, 50), child21);
+ StacksBehindParentHelper *child22 = new StacksBehindParentHelper(&paintedItems, QRectF(60, 10, 50, 50), parent2);
+ StacksBehindParentHelper *grandChild221 = new StacksBehindParentHelper(&paintedItems, QRectF(70, 20, 50, 50), child22);
parent1->setData(0, "parent1");
child11->setData(0, "child11");
@@ -5809,25 +5849,57 @@ void tst_QGraphicsItem::itemStacksBehindParent()
scene.addItem(parent1);
scene.addItem(parent2);
+ paintedItems.clear();
+
+ QGraphicsView view(&scene);
+ view.show();
+#ifdef Q_WS_X11
+ qt_x11_wait_for_window_manager(&view);
+#endif
+ QTest::qWait(250);
+
QCOMPARE(scene.items(0, 0, 100, 100), (QList<QGraphicsItem *>()
<< grandChild111 << child11
<< grandChild121 << child12 << parent1
<< grandChild211 << child21
<< grandChild221 << child22 << parent2));
+ QCOMPARE(paintedItems, QList<QGraphicsItem *>()
+ << parent2 << child22 << grandChild221
+ << child21 << grandChild211
+ << parent1 << child12 << grandChild121
+ << child11 << grandChild111);
child11->setFlag(QGraphicsItem::ItemStacksBehindParent);
+ scene.update();
+ paintedItems.clear();
+ QTest::qWait(250);
+
QCOMPARE(scene.items(0, 0, 100, 100), (QList<QGraphicsItem *>()
<< grandChild121 << child12 << parent1
<< grandChild111 << child11
<< grandChild211 << child21
<< grandChild221 << child22 << parent2));
+ QCOMPARE(paintedItems, QList<QGraphicsItem *>()
+ << parent2 << child22 << grandChild221
+ << child21 << grandChild211
+ << child11 << grandChild111
+ << parent1 << child12 << grandChild121);
child12->setFlag(QGraphicsItem::ItemStacksBehindParent);
+ paintedItems.clear();
+ scene.update();
+ QTest::qWait(250);
+
QCOMPARE(scene.items(0, 0, 100, 100), (QList<QGraphicsItem *>()
<< parent1 << grandChild111 << child11
<< grandChild121 << child12
<< grandChild211 << child21
<< grandChild221 << child22 << parent2));
+ QCOMPARE(paintedItems, QList<QGraphicsItem *>()
+ << parent2 << child22 << grandChild221
+ << child21 << grandChild211
+ << child12 << grandChild121
+ << child11 << grandChild111 << parent1);
}
class ClippingAndTransformsScene : public QGraphicsScene
@@ -5876,6 +5948,7 @@ void tst_QGraphicsItem::nestedClipping()
l3->setData(0, "l3");
QGraphicsView view(&scene);
+ view.setOptimizationFlag(QGraphicsView::IndirectPainting);
view.show();
#ifdef Q_WS_X11
qt_x11_wait_for_window_manager(&view);
@@ -6428,6 +6501,71 @@ void tst_QGraphicsItem::deviceTransform()
QCOMPARE(rect3->deviceTransform(deviceX).map(QPointF(50, 50)), mapResult3);
}
+class MyGraphicsView : public QGraphicsView
+{
+public:
+ int repaints;
+ QRegion paintedRegion;
+ MyGraphicsView(QGraphicsScene *scene) : QGraphicsView(scene), repaints(0) {}
+ void paintEvent(QPaintEvent *e)
+ {
+ paintedRegion += e->region();
+ ++repaints;
+ QGraphicsView::paintEvent(e);
+ }
+ void reset() { repaints = 0; paintedRegion = QRegion(); }
+};
+
+void tst_QGraphicsItem::update()
+{
+ QGraphicsScene scene;
+ MyGraphicsView view(&scene);
+
+ view.show();
+#ifdef Q_WS_X11
+ qt_x11_wait_for_window_manager(&view);
+#endif
+ QTest::qWait(100);
+
+ EventTester *item = new EventTester;
+ scene.addItem(item);
+ QTest::qWait(100); // Make sure all pending updates are processed.
+ item->repaints = 0;
+
+ item->update(); // Item marked as dirty
+ scene.update(); // Entire scene marked as dirty
+ qApp->processEvents();
+ QCOMPARE(item->repaints, 1);
+
+ // Make sure the dirty state from the previous update is reset so that
+ // the item don't think it is already dirty and discards this update.
+ item->update();
+ qApp->processEvents();
+ QCOMPARE(item->repaints, 2);
+
+ // Make sure a partial update doesn't cause a full update to be discarded.
+ view.reset();
+ item->repaints = 0;
+ item->update(QRectF(0, 0, 5, 5));
+ item->update();
+ qApp->processEvents();
+ QCOMPARE(item->repaints, 1);
+ QCOMPARE(view.repaints, 1);
+ const QRect itemDeviceBoundingRect = item->deviceTransform(view.viewportTransform())
+ .mapRect(item->boundingRect()).toRect();
+ const QRegion expectedRegion = itemDeviceBoundingRect.adjusted(-2, -2, 2, 2);
+ // The entire item's bounding rect (adjusted for antialiasing) should have been painted.
+ QCOMPARE(view.paintedRegion, expectedRegion);
+
+ // Make sure update requests outside the bounding rect are discarded.
+ view.reset();
+ item->repaints = 0;
+ item->update(-15, -15, 5, 5); // Item's brect: (-10, -10, 20, 20)
+ qApp->processEvents();
+ QCOMPARE(item->repaints, 0);
+ QCOMPARE(view.repaints, 0);
+}
+
void tst_QGraphicsItem::setTransformProperties_data()
{
QTest::addColumn<QPointF>("origin");
@@ -6440,26 +6578,26 @@ void tst_QGraphicsItem::setTransformProperties_data()
QTest::addColumn<qreal>("shearY");
QTest::newRow("nothing") << QPointF() << qreal(0.0) << qreal(0.0) << qreal(0.0)
- << qreal(1) << qreal(1) << qreal(0.0) << qreal(0.0);
+ << qreal(1.0) << qreal(1.0) << qreal(0.0) << qreal(0.0);
QTest::newRow("rotationZ") << QPointF() << qreal(0.0) << qreal(0.0) << qreal(42.2)
- << qreal(1) << qreal(1) << qreal(0.0) << qreal(0.0);
+ << qreal(1.0) << qreal(1.0) << qreal(0.0) << qreal(0.0);
QTest::newRow("rotationXY") << QPointF() << qreal(12.5) << qreal(53.6) << qreal(0.0)
- << qreal(1) << qreal(1) << qreal(0.0) << qreal(0.0);
+ << qreal(1.0) << qreal(1.0) << qreal(0.0) << qreal(0.0);
QTest::newRow("rotationXYZ") << QPointF() << qreal(-25) << qreal(12) << qreal(556)
- << qreal(1) << qreal(1) << qreal(0.0) << qreal(0.0);
+ << qreal(1.0) << qreal(1.0) << qreal(0.0) << qreal(0.0);
QTest::newRow("rotationXYZ dicentred") << QPointF(-53, 25.2)
<< qreal(-2578.2) << qreal(4565.2) << qreal(56)
- << qreal(1) << qreal(1) << qreal(0.0) << qreal(0.0);
+ << qreal(1.0) << qreal(1.0) << qreal(0.0) << qreal(0.0);
QTest::newRow("Scale") << QPointF() << qreal(0.0) << qreal(0.0) << qreal(0.0)
<< qreal(6) << qreal(0.5) << qreal(0.0) << qreal(0.0);
QTest::newRow("Shear") << QPointF() << qreal(0.0) << qreal(0.0) << qreal(0.0)
- << qreal(1) << qreal(1) << qreal(2.2) << qreal(0.5);
+ << qreal(1.0) << qreal(1.0) << qreal(2.2) << qreal(0.5);
QTest::newRow("Scale and Shear") << QPointF() << qreal(0.0) << qreal(0.0) << qreal(0.0)
<< qreal(5.2) << qreal(2.1) << qreal(5.2) << qreal(5.5);
@@ -6471,6 +6609,11 @@ void tst_QGraphicsItem::setTransformProperties_data()
<< qreal(4) << qreal(2) << qreal(2.56) << qreal(0.8);
}
+/**
+ * the normal QCOMPARE doesn't work because it doesn't use qFuzzyCompare
+ */
+#define QCOMPARE_TRANSFORM(X1, X2) QVERIFY(((X1)*(X2).inverted()).isIdentity())
+
void tst_QGraphicsItem::setTransformProperties()
{
QFETCH(QPointF,origin);
@@ -6494,7 +6637,6 @@ void tst_QGraphicsItem::setTransformProperties()
QGraphicsScene scene;
QGraphicsRectItem *item = new QGraphicsRectItem(QRectF(0, 0, 100, 100));
scene.addItem(item);
- item->setPos(100, 100);
item->setRotation(rotationX, rotationY, rotationZ);
item->setScale(scaleX, scaleY);
@@ -6510,7 +6652,8 @@ void tst_QGraphicsItem::setTransformProperties()
QCOMPARE(item->verticalShear(), shearY);
QCOMPARE(item->transformOrigin(), origin);
- QCOMPARE(result, item->transform());
+ QCOMPARE(QTransform(), item->transform());
+ QCOMPARE(result, item->sceneTransform());
//-----------------------------------------------------------------
//Change the rotation Z
@@ -6533,24 +6676,311 @@ void tst_QGraphicsItem::setTransformProperties()
QCOMPARE(item->verticalShear(), shearY);
QCOMPARE(item->transformOrigin(), origin);
- QCOMPARE(result2, item->transform());
+ QCOMPARE(QTransform(), item->transform());
+ QCOMPARE(result2, item->sceneTransform());
//-----------------------------------------------------------------
- // calling setTransform() should reset the properties to their default
+ // calling setTransform() and setPos shoukld change the sceneTransform
item->setTransform(result);
+ item->setPos(100, -150.5);
- QCOMPARE(item->xRotation(), 0.0);
- QCOMPARE(item->yRotation(), 0.0);
- QCOMPARE(item->zRotation(), 0.0);
- QCOMPARE(item->xScale(), 1.0);
- QCOMPARE(item->yScale(), 1.0);
- QCOMPARE(item->horizontalShear(), 0.0);
- QCOMPARE(item->verticalShear(), 0.0);
- QCOMPARE(item->transformOrigin(), QPointF(0,0));
-
+ QCOMPARE(item->xRotation(), rotationX);
+ QCOMPARE(item->yRotation(), rotationY);
+ QCOMPARE(item->zRotation(), 45.0);
+ QCOMPARE(item->xScale(), scaleX);
+ QCOMPARE(item->yScale(), scaleY);
+ QCOMPARE(item->horizontalShear(), shearX);
+ QCOMPARE(item->verticalShear(), shearY);
+ QCOMPARE(item->transformOrigin(), origin);
QCOMPARE(result, item->transform());
+
+ QTransform result3;
+
+ result3.translate(origin.x(), origin.y());
+ result3 = result * result3;
+ result3.rotate(rotationX, Qt::XAxis);
+ result3.rotate(rotationY, Qt::YAxis);
+ result3.rotate(45, Qt::ZAxis);
+ result3.shear(shearX, shearY);
+ result3.scale(scaleX, scaleY);
+ result3.translate(-origin.x(), -origin.y());
+
+ result3 *= QTransform::fromTranslate(100, -150.5); //the pos;
+
+ QCOMPARE(result3, item->sceneTransform());
+
+ //-----------------------------------------------------
+ // setting the propertiees should be the same as setting a transform
+ {//with center origin on the matrix
+ QGraphicsRectItem *item1 = new QGraphicsRectItem(QRectF(50.2, -150, 230.5, 119));
+ scene.addItem(item1);
+ QGraphicsRectItem *item2 = new QGraphicsRectItem(QRectF(50.2, -150, 230.5, 119));
+ scene.addItem(item2);
+
+ item1->setPos(12.3, -5);
+ item2->setPos(12.3, -5);
+ item1->setRotation(rotationX, rotationY, rotationZ);
+ item1->setScale(scaleX, scaleY);
+ item1->setShear(shearX, shearY);
+ item1->setTransformOrigin(origin);
+
+ item2->setTransform(result);
+
+ QCOMPARE_TRANSFORM(item1->sceneTransform(), item2->sceneTransform());
+
+ QCOMPARE_TRANSFORM(item1->itemTransform(item2), QTransform());
+ QCOMPARE_TRANSFORM(item2->itemTransform(item1), QTransform());
+ }
+
+ {//with center origin on the item
+ QGraphicsRectItem *item1 = new QGraphicsRectItem(QRectF(50.2, -150, 230.5, 119));
+ scene.addItem(item1);
+ QGraphicsRectItem *item2 = new QGraphicsRectItem(QRectF(50.2, -150, 230.5, 119));
+ scene.addItem(item2);
+
+ item1->setPos(12.3, -5);
+ item2->setPos(12.3, -5);
+ item1->setTransformOrigin(origin);
+ item2->setTransformOrigin(origin);
+
+ item1->setRotation(rotationX, rotationY, rotationZ);
+ item1->setScale(scaleX, scaleY);
+ item1->setShear(shearX, shearY);
+
+ QTransform tr;
+ tr.rotate(rotationX, Qt::XAxis);
+ tr.rotate(rotationY, Qt::YAxis);
+ tr.rotate(rotationZ, Qt::ZAxis);
+ tr.shear(shearX, shearY);
+ tr.scale(scaleX, scaleY);
+
+ item2->setTransform(tr);
+
+ QCOMPARE_TRANSFORM(item1->sceneTransform(), item2->sceneTransform());
+
+ QCOMPARE_TRANSFORM(item1->itemTransform(item2), QTransform());
+ QCOMPARE_TRANSFORM(item2->itemTransform(item1), QTransform());
+ }
+}
+
+class MyStyleOptionTester : public QGraphicsRectItem
+{
+public:
+ MyStyleOptionTester(const QRectF &rect)
+ : QGraphicsRectItem(rect), startTrack(false)
+ {}
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0)
+ {
+ if (startTrack) {
+ //Doesn't use the extended style option so the exposed rect is the boundingRect
+ if (!(flags() & QGraphicsItem::ItemUsesExtendedStyleOption)) {
+ QCOMPARE(option->exposedRect, boundingRect());
+ } else {
+ QVERIFY(option->exposedRect != QRect());
+ QVERIFY(option->exposedRect != boundingRect());
+ }
+ }
+ QGraphicsRectItem::paint(painter, option, widget);
+ }
+ bool startTrack;
+};
+
+void tst_QGraphicsItem::itemUsesExtendedStyleOption()
+{
+ QGraphicsScene scene(0, 0, 300, 300);
+ QGraphicsPixmapItem item;
+ item.setFlag(QGraphicsItem::ItemUsesExtendedStyleOption, true);
+ QCOMPARE(item.flags(), QGraphicsItem::GraphicsItemFlags(QGraphicsItem::ItemUsesExtendedStyleOption));
+ item.setFlag(QGraphicsItem::ItemUsesExtendedStyleOption, false);
+ QCOMPARE(item.flags(), 0);
+
+ //We now test the content of the style option
+ MyStyleOptionTester *rect = new MyStyleOptionTester(QRect(0, 0, 100, 100));
+ scene.addItem(rect);
+ rect->setPos(200, 200);
+ QGraphicsView view(&scene);
+ QTest::qWait(500);
+ rect->startTrack = true;
+ rect->update(10, 10, 10, 10);
+ QTest::qWait(125);
+ rect->startTrack = false;
+ rect->setFlag(QGraphicsItem::ItemUsesExtendedStyleOption, true);
+ QVERIFY((rect->flags() & QGraphicsItem::ItemUsesExtendedStyleOption));
+ QTest::qWait(125);
+ rect->startTrack = true;
+ rect->update(10, 10, 10, 10);
+ QTest::qWait(125);
+}
+
+void tst_QGraphicsItem::itemSendsGeometryChanges()
+{
+ ItemChangeTester item;
+ item.setFlags(0);
+ item.clear();
+
+ QTransform x = QTransform().rotate(45);
+ QPointF pos(10, 10);
+ qreal o(0.5);
+ item.setTransform(x);
+ item.setPos(pos);
+ QCOMPARE(item.transform(), x);
+ QCOMPARE(item.pos(), pos);
+ QCOMPARE(item.changes.size(), 0);
+
+ item.setOpacity(o);
+ QCOMPARE(item.changes.size(), 2); // opacity
+
+ item.setFlag(QGraphicsItem::ItemSendsGeometryChanges);
+ QCOMPARE(item.changes.size(), 4); // flags
+ item.setTransform(QTransform());
+ item.setPos(QPointF());
+ QCOMPARE(item.changes.size(), 8); // transform + pos
+ QCOMPARE(item.transform(), QTransform());
+ QCOMPARE(item.pos(), QPointF());
+ QCOMPARE(item.opacity(), o);
+
+ QCOMPARE(item.changes, QList<QGraphicsItem::GraphicsItemChange>()
+ << QGraphicsItem::ItemOpacityChange
+ << QGraphicsItem::ItemOpacityHasChanged
+ << QGraphicsItem::ItemFlagsChange
+ << QGraphicsItem::ItemFlagsHaveChanged
+ << QGraphicsItem::ItemTransformChange
+ << QGraphicsItem::ItemTransformHasChanged
+ << QGraphicsItem::ItemPositionChange
+ << QGraphicsItem::ItemPositionHasChanged);
+}
+
+// Make sure we update moved items correctly.
+void tst_QGraphicsItem::moveItem()
+{
+ QGraphicsScene scene;
+ scene.setSceneRect(-50, -50, 200, 200);
+
+ MyGraphicsView view(&scene);
+ view.show();
+#ifdef Q_WS_X11
+ qt_x11_wait_for_window_manager(&view);
+#endif
+ QTest::qWait(100);
+
+ EventTester *parent = new EventTester;
+ EventTester *child = new EventTester(parent);
+ EventTester *grandChild = new EventTester(child);
+
+#define RESET_COUNTERS \
+ parent->repaints = 0; \
+ child->repaints = 0; \
+ grandChild->repaints = 0; \
+ view.reset();
+
+ scene.addItem(parent);
+ QTest::qWait(100);
+
+ RESET_COUNTERS
+
+ // Item's boundingRect: (-10, -10, 20, 20).
+ QRect parentDeviceBoundingRect = parent->deviceTransform(view.viewportTransform())
+ .mapRect(parent->boundingRect()).toRect()
+ .adjusted(-2, -2, 2, 2); // Adjusted for antialiasing.
+
+ parent->setPos(20, 20);
+ qApp->processEvents();
+ QCOMPARE(parent->repaints, 1);
+ QCOMPARE(view.repaints, 1);
+ QRegion expectedParentRegion = parentDeviceBoundingRect; // old position
+ parentDeviceBoundingRect.translate(20, 20);
+ expectedParentRegion += parentDeviceBoundingRect; // new position
+ QCOMPARE(view.paintedRegion, expectedParentRegion);
+
+ RESET_COUNTERS
+
+ child->setPos(20, 20);
+ qApp->processEvents();
+ QCOMPARE(parent->repaints, 1);
+ QCOMPARE(child->repaints, 1);
+ QCOMPARE(view.repaints, 1);
+ const QRegion expectedChildRegion = expectedParentRegion.translated(20, 20);
+ QCOMPARE(view.paintedRegion, expectedChildRegion);
+
+ RESET_COUNTERS
+
+ grandChild->setPos(20, 20);
+ qApp->processEvents();
+ QCOMPARE(parent->repaints, 1);
+ QCOMPARE(child->repaints, 1);
+ QCOMPARE(grandChild->repaints, 1);
+ QCOMPARE(view.repaints, 1);
+ const QRegion expectedGrandChildRegion = expectedParentRegion.translated(40, 40);
+ QCOMPARE(view.paintedRegion, expectedGrandChildRegion);
+
+ RESET_COUNTERS
+
+ parent->translate(20, 20);
+ qApp->processEvents();
+ QCOMPARE(parent->repaints, 1);
+ QCOMPARE(child->repaints, 1);
+ QCOMPARE(grandChild->repaints, 1);
+ QCOMPARE(view.repaints, 1);
+ expectedParentRegion.translate(20, 20);
+ expectedParentRegion += expectedChildRegion.translated(20, 20);
+ expectedParentRegion += expectedGrandChildRegion.translated(20, 20);
+ QCOMPARE(view.paintedRegion, expectedParentRegion);
}
+void tst_QGraphicsItem::sorting_data()
+{
+ QTest::addColumn<int>("index");
+
+ QTest::newRow("NoIndex") << int(QGraphicsScene::NoIndex);
+ QTest::newRow("BspTreeIndex") << int(QGraphicsScene::BspTreeIndex);
+}
+
+void tst_QGraphicsItem::sorting()
+{
+ _paintedItems.clear();
+
+ QGraphicsScene scene;
+ QGraphicsItem *grid[100][100];
+ for (int x = 0; x < 100; ++x) {
+ for (int y = 0; y < 100; ++y) {
+ PainterItem *item = new PainterItem;
+ item->setPos(x * 25, y * 25);
+ item->setData(0, QString("%1x%2").arg(x).arg(y));
+ grid[x][y] = item;
+ scene.addItem(item);
+ }
+ }
+
+ PainterItem *item1 = new PainterItem;
+ PainterItem *item2 = new PainterItem;
+ item1->setData(0, "item1");
+ item2->setData(0, "item2");
+ scene.addItem(item1);
+ scene.addItem(item2);
+
+ QGraphicsView view(&scene);
+ view.setResizeAnchor(QGraphicsView::NoAnchor);
+ view.setTransformationAnchor(QGraphicsView::NoAnchor);
+ view.resize(100, 100);
+ view.setFrameStyle(0);
+ view.show();
+#ifdef Q_WS_X11
+ qt_x11_wait_for_window_manager(&view);
+#endif
+ QTest::qWait(100);
+
+ _paintedItems.clear();
+
+ view.viewport()->repaint();
+
+ QCOMPARE(_paintedItems, QList<QGraphicsItem *>()
+ << grid[0][0] << grid[0][1] << grid[0][2] << grid[0][3]
+ << grid[1][0] << grid[1][1] << grid[1][2] << grid[1][3]
+ << grid[2][0] << grid[2][1] << grid[2][2] << grid[2][3]
+ << grid[3][0] << grid[3][1] << grid[3][2] << grid[3][3]
+ << item1 << item2);
+}
QTEST_MAIN(tst_QGraphicsItem)
#include "tst_qgraphicsitem.moc"
diff --git a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
index d856024..fa0e035 100644
--- a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
+++ b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
@@ -1487,7 +1487,7 @@ void tst_QGraphicsProxyWidget::scrollUpdate()
QVector<QRect>() << QRect(0, 0, 200, 12) << QRect(0, 12, 102, 10));
QCOMPARE(widget->npaints, 2);
QCOMPARE(widget->paintEventRegion.rects(),
- QVector<QRect>() << QRect(0, 0, 200, 13) << QRect(0, 13, 103, 10));
+ QVector<QRect>() << QRect(0, 0, 200, 12) << QRect(0, 12, 102, 10));
}
void tst_QGraphicsProxyWidget::setWidget_simple()
diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp
index 0c5ebf6..8bb9122 100644
--- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp
+++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp
@@ -274,7 +274,9 @@ void tst_QGraphicsScene::sceneRect()
QCOMPARE(scene.sceneRect(), QRectF());
QGraphicsItem *item = scene.addRect(QRectF(0, 0, 10, 10));
+ qApp->processEvents();
item->setPos(-5, -5);
+ qApp->processEvents();
QCOMPARE(scene.itemAt(0, 0), item);
QCOMPARE(scene.itemAt(10, 10), (QGraphicsItem *)0);
@@ -1317,8 +1319,9 @@ void tst_QGraphicsScene::removeItem()
scene.removeItem(hoverItem);
hoverItem->setAcceptsHoverEvents(false);
scene.addItem(hoverItem);
- qApp->processEvents(); // update
- qApp->processEvents(); // draw
+ qApp->processEvents(); // <- delayed update is called
+ qApp->processEvents(); // <- scene schedules pending update
+ qApp->processEvents(); // <- pending update is sent to view
QVERIFY(!hoverItem->isHovered);
}
@@ -2712,6 +2715,7 @@ void tst_QGraphicsScene::update()
QGraphicsRectItem *rect = new QGraphicsRectItem(0, 0, 100, 100);
scene.addItem(rect);
+ qApp->processEvents();
rect->setPos(-100, -100);
// This function forces indexing
diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp
index 8e490ad..5167682 100644
--- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp
+++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp
@@ -191,6 +191,7 @@ private slots:
void centerOnDirtyItem();
void mouseTracking();
void mouseTracking2();
+ void render();
// task specific tests below me
void task172231_untransformableItems();
@@ -2525,6 +2526,8 @@ void tst_QGraphicsView::acceptMousePressEvent()
scene.addRect(0, 0, 2000, 2000)->setFlag(QGraphicsItem::ItemIsMovable);
+ qApp->processEvents(); // ensure scene rect is updated
+
QApplication::sendEvent(view.viewport(), &event);
QVERIFY(view.accepted);
}
@@ -3201,6 +3204,62 @@ void tst_QGraphicsView::mouseTracking2()
QCOMPARE(spy.count(), 1);
}
+class RenderTester : public QGraphicsRectItem
+{
+public:
+ RenderTester(const QRectF &rect)
+ : QGraphicsRectItem(rect), paints(0)
+ { }
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
+ QWidget *widget)
+ {
+ QGraphicsRectItem::paint(painter, option, widget);
+ ++paints;
+ }
+
+ int paints;
+};
+
+void tst_QGraphicsView::render()
+{
+ // ### This test can be much more thorough - see QGraphicsScene::render.
+ QGraphicsScene scene;
+ RenderTester *r1 = new RenderTester(QRectF(0, 0, 50, 50));
+ RenderTester *r2 = new RenderTester(QRectF(50, 50, 50, 50));
+ RenderTester *r3 = new RenderTester(QRectF(0, 50, 50, 50));
+ RenderTester *r4 = new RenderTester(QRectF(50, 0, 50, 50));
+ scene.addItem(r1);
+ scene.addItem(r2);
+ scene.addItem(r3);
+ scene.addItem(r4);
+
+ QGraphicsView view(&scene);
+ view.setFrameStyle(0);
+ view.resize(200, 200);
+ view.show();
+#ifdef Q_WS_X11
+ qt_x11_wait_for_window_manager(&view);
+#endif
+ QTest::qWait(200);
+
+ QCOMPARE(r1->paints, 1);
+ QCOMPARE(r2->paints, 1);
+ QCOMPARE(r3->paints, 1);
+ QCOMPARE(r4->paints, 1);
+
+ QPixmap pix(200, 200);
+ pix.fill(Qt::transparent);
+ QPainter painter(&pix);
+ view.render(&painter);
+ painter.end();
+
+ QCOMPARE(r1->paints, 2);
+ QCOMPARE(r2->paints, 2);
+ QCOMPARE(r3->paints, 2);
+ QCOMPARE(r4->paints, 2);
+}
+
void tst_QGraphicsView::task253415_reconnectUpdateSceneOnSceneChanged()
{
QGraphicsView view;
diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp
index 56d42c3..00f3155 100644
--- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp
+++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp
@@ -155,6 +155,7 @@ private slots:
void windowFlags_data();
void windowFlags();
void shortcutsDeletion();
+ void painterStateProtectionOnWindowFrame();
// Task fixes
void task236127_bspTreeIndexFails();
@@ -2282,6 +2283,41 @@ void tst_QGraphicsWidget::shortcutsDeletion()
delete widget;
}
+class MessUpPainterWidget : public QGraphicsWidget
+{
+public:
+ MessUpPainterWidget(QGraphicsItem * parent = 0, Qt::WindowFlags wFlags = 0)
+ : QGraphicsWidget(parent, wFlags)
+ {}
+
+ void paintWindowFrame(QPainter * painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+ {
+ QCOMPARE(painter->opacity(), 1.0);
+ painter->setOpacity(0.0);
+ QGraphicsWidget::paintWindowFrame(painter, option, widget);
+ }
+ void paint(QPainter * painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+ {
+ QCOMPARE(painter->opacity(), 1.0);
+ painter->drawRect(0, 0, 100, 100);
+ QGraphicsWidget::paint(painter, option, widget);
+ }
+
+};
+
+void tst_QGraphicsWidget::painterStateProtectionOnWindowFrame()
+{
+ MessUpPainterWidget *widget = new MessUpPainterWidget(0, Qt::Window);
+ QGraphicsScene scene(0, 0, 300, 300);
+ QGraphicsView view(&scene);
+ scene.addItem(widget);
+ view.show();
+#ifdef Q_WS_X11
+ qt_x11_wait_for_window_manager(&view);
+#endif
+ QTest::qWait(500);
+}
+
class ProxyStyle : public QCommonStyle
{
public:
diff --git a/tests/auto/qimagereader/qimagereader.qrc b/tests/auto/qimagereader/qimagereader.qrc
index 3c674ad..c6b963b 100644
--- a/tests/auto/qimagereader/qimagereader.qrc
+++ b/tests/auto/qimagereader/qimagereader.qrc
@@ -30,7 +30,7 @@
<file>images/image.pgm</file>
<file>images/image.png</file>
<file>images/image.ppm</file>
- <file>images/image.tif</file>
+ <file>images/image_100dpi.tif</file>
<file>images/kollada.png</file>
<file>images/marble.xpm</file>
<file>images/namedcolors.xpm</file>
diff --git a/tests/auto/qimagereader/tst_qimagereader.cpp b/tests/auto/qimagereader/tst_qimagereader.cpp
index f5313eb..0b32f0a 100644
--- a/tests/auto/qimagereader/tst_qimagereader.cpp
+++ b/tests/auto/qimagereader/tst_qimagereader.cpp
@@ -156,6 +156,9 @@ private slots:
void pixelCompareWithBaseline_data();
void pixelCompareWithBaseline();
+
+ void task255627_setNullScaledSize_data();
+ void task255627_setNullScaledSize();
};
static const QLatin1String prefix(SRCDIR "/images/");
@@ -333,6 +336,29 @@ void tst_QImageReader::setScaledSize()
QCOMPARE(image.size(), newSize);
}
+void tst_QImageReader::task255627_setNullScaledSize_data()
+{
+ setScaledSize_data();
+}
+
+void tst_QImageReader::task255627_setNullScaledSize()
+{
+ QFETCH(QString, fileName);
+ QFETCH(QByteArray, format);
+
+ if (!format.isEmpty() && !QImageReader::supportedImageFormats().contains(format))
+ QSKIP("Qt does not support reading the \"" + format + "\" format", SkipSingle);
+
+ QImageReader reader(prefix + fileName);
+
+ // set a null size
+ reader.setScaledSize(QSize(0, 0));
+ reader.setQuality(0);
+ QImage image = reader.read();
+ QVERIFY(image.isNull());
+ QCOMPARE(image.size(), QSize(0, 0));
+}
+
void tst_QImageReader::setClipRect_data()
{
QTest::addColumn<QString>("fileName");
diff --git a/tests/auto/qimagewriter/tst_qimagewriter.cpp b/tests/auto/qimagewriter/tst_qimagewriter.cpp
index 349afa5..3ceb2c2 100644
--- a/tests/auto/qimagewriter/tst_qimagewriter.cpp
+++ b/tests/auto/qimagewriter/tst_qimagewriter.cpp
@@ -59,6 +59,7 @@ Q_DECLARE_METATYPE(QStringMap)
Q_DECLARE_METATYPE(QIntList)
Q_DECLARE_METATYPE(QImageWriter::ImageWriterError)
Q_DECLARE_METATYPE(QIODevice *)
+Q_DECLARE_METATYPE(QImage::Format)
//TESTED_FILES=
@@ -82,6 +83,9 @@ private slots:
void writeImage2();
void supportedFormats();
+ void readWriteNonDestructive_data();
+ void readWriteNonDestructive();
+
#if defined QTEST_HAVE_TIFF
void largeTiff();
#endif
@@ -376,6 +380,28 @@ void tst_QImageWriter::supportedFormats()
QCOMPARE(formatSet.size(), formats.size());
}
+void tst_QImageWriter::readWriteNonDestructive_data()
+{
+ QTest::addColumn<QImage::Format>("format");
+ QTest::addColumn<QImage::Format>("expectedFormat");
+ QTest::newRow("tiff mono") << QImage::Format_Mono << QImage::Format_Mono;
+ QTest::newRow("tiff indexed") << QImage::Format_Indexed8 << QImage::Format_Indexed8;
+ QTest::newRow("tiff rgb32") << QImage::Format_ARGB32 << QImage::Format_ARGB32;
+}
+
+void tst_QImageWriter::readWriteNonDestructive()
+{
+ QFETCH(QImage::Format, format);
+ QFETCH(QImage::Format, expectedFormat);
+ QImage image = QImage(prefix + "colorful.bmp").convertToFormat(format);
+ QVERIFY(image.save(prefix + "gen-readWriteNonDestructive.tiff"));
+
+ QImage image2 = QImage(prefix + "gen-readWriteNonDestructive.tiff");
+ QImage::Format readFormat = image2.format();
+ QCOMPARE(readFormat, expectedFormat);
+ QCOMPARE(image, image2);
+}
+
void tst_QImageWriter::setDescription_data()
{
QTest::addColumn<QString>("fileName");
diff --git a/tests/auto/qlistwidget/tst_qlistwidget.cpp b/tests/auto/qlistwidget/tst_qlistwidget.cpp
index 8d15aa4..8468cf3 100644
--- a/tests/auto/qlistwidget/tst_qlistwidget.cpp
+++ b/tests/auto/qlistwidget/tst_qlistwidget.cpp
@@ -883,31 +883,46 @@ void tst_QListWidget::itemStreaming()
void tst_QListWidget::sortItems_data()
{
QTest::addColumn<int>("order");
- QTest::addColumn<QStringList>("initialList");
- QTest::addColumn<QStringList>("expectedList");
+ QTest::addColumn<QVariantList>("initialList");
+ QTest::addColumn<QVariantList>("expectedList");
QTest::addColumn<IntList>("expectedRows");
- QTest::newRow("ascending order")
+ QTest::newRow("ascending strings")
<< static_cast<int>(Qt::AscendingOrder)
- << (QStringList() << "c" << "d" << "a" << "b")
- << (QStringList() << "a" << "b" << "c" << "d")
+ << (QVariantList() << QString("c") << QString("d") << QString("a") << QString("b"))
+ << (QVariantList() << QString("a") << QString("b") << QString("c") << QString("d"))
<< (IntList() << 2 << 3 << 0 << 1);
- QTest::newRow("descending order")
+ QTest::newRow("descending strings")
<< static_cast<int>(Qt::DescendingOrder)
- << (QStringList() << "c" << "d" << "a" << "b")
- << (QStringList() << "d" << "c" << "b" << "a")
+ << (QVariantList() << QString("c") << QString("d") << QString("a") << QString("b"))
+ << (QVariantList() << QString("d") << QString("c") << QString("b") << QString("a"))
<< (IntList() << 1 << 0 << 3 << 2);
+
+ QTest::newRow("ascending numbers")
+ << static_cast<int>(Qt::AscendingOrder)
+ << (QVariantList() << 1 << 11 << 2 << 22)
+ << (QVariantList() << 1 << 2 << 11 << 22)
+ << (IntList() << 0 << 2 << 1 << 3);
+
+ QTest::newRow("descending numbers")
+ << static_cast<int>(Qt::DescendingOrder)
+ << (QVariantList() << 1 << 11 << 2 << 22)
+ << (QVariantList() << 22 << 11 << 2 << 1)
+ << (IntList() << 3 << 1 << 2 << 0);
}
void tst_QListWidget::sortItems()
{
QFETCH(int, order);
- QFETCH(QStringList, initialList);
- QFETCH(QStringList, expectedList);
+ QFETCH(QVariantList, initialList);
+ QFETCH(QVariantList, expectedList);
QFETCH(IntList, expectedRows);
- testWidget->addItems(initialList);
+ foreach (const QVariant &data, initialList) {
+ QListWidgetItem *item = new QListWidgetItem(testWidget);
+ item->setData(Qt::DisplayRole, data);
+ }
QAbstractItemModel *model = testWidget->model();
QList<QPersistentModelIndex> persistent;
@@ -918,7 +933,7 @@ void tst_QListWidget::sortItems()
QCOMPARE(testWidget->count(), expectedList.count());
for (int i = 0; i < testWidget->count(); ++i)
- QCOMPARE(testWidget->item(i)->text(), expectedList.at(i));
+ QCOMPARE(testWidget->item(i)->text(), expectedList.at(i).toString());
for (int k = 0; k < testWidget->count(); ++k)
QCOMPARE(persistent.at(k).row(), expectedRows.at(k));
diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp
index 041aa7a..85d7de1 100644
--- a/tests/auto/qwidget/tst_qwidget.cpp
+++ b/tests/auto/qwidget/tst_qwidget.cpp
@@ -288,6 +288,7 @@ private slots:
void render_systemClip3_data();
void render_systemClip3();
void render_task252837();
+ void render_worldTransform();
void setContentsMargins();
@@ -7151,6 +7152,99 @@ void tst_QWidget::render_task252837()
// Please do not crash.
widget.render(&painter);
}
+
+void tst_QWidget::render_worldTransform()
+{
+ class MyWidget : public QWidget
+ { public:
+ void paintEvent(QPaintEvent *)
+ {
+ QPainter painter(this);
+ // Make sure world transform is identity.
+ QCOMPARE(painter.worldTransform(), QTransform());
+
+ // Make sure device transform is correct.
+ const QPoint widgetOffset = geometry().topLeft();
+ QTransform expectedDeviceTransform = QTransform::fromTranslate(105, 5);
+ expectedDeviceTransform.rotate(90);
+ expectedDeviceTransform.translate(widgetOffset.x(), widgetOffset.y());
+ QCOMPARE(painter.deviceTransform(), expectedDeviceTransform);
+
+ // Set new world transform.
+ QTransform newWorldTransform = QTransform::fromTranslate(10, 10);
+ newWorldTransform.rotate(90);
+ painter.setWorldTransform(newWorldTransform);
+ QCOMPARE(painter.worldTransform(), newWorldTransform);
+
+ // Again, check device transform.
+ expectedDeviceTransform.translate(10, 10);
+ expectedDeviceTransform.rotate(90);
+ QCOMPARE(painter.deviceTransform(), expectedDeviceTransform);
+
+ painter.fillRect(QRect(0, 0, 20, 10), Qt::green);
+ }
+ };
+
+ MyWidget widget;
+ widget.setFixedSize(100, 100);
+ widget.setPalette(Qt::red);
+ widget.setAutoFillBackground(true);
+
+ MyWidget child;
+ child.setParent(&widget);
+ child.move(50, 50);
+ child.setFixedSize(50, 50);
+ child.setPalette(Qt::blue);
+ child.setAutoFillBackground(true);
+
+ QImage image(QSize(110, 110), QImage::Format_RGB32);
+ image.fill(QColor(Qt::black).rgb());
+
+ QPainter painter(&image);
+ painter.translate(105, 5);
+ painter.rotate(90);
+
+ const QTransform worldTransform = painter.worldTransform();
+ const QTransform deviceTransform = painter.deviceTransform();
+
+ // Render widgets onto image.
+ widget.render(&painter);
+#ifdef RENDER_DEBUG
+ image.save("render_worldTransform_image.png");
+#endif
+
+ // Ensure the transforms are unchanged after render.
+ QCOMPARE(painter.worldTransform(), painter.worldTransform());
+ QCOMPARE(painter.deviceTransform(), painter.deviceTransform());
+ painter.end();
+
+ // Paint expected image.
+ QImage expected(QSize(110, 110), QImage::Format_RGB32);
+ expected.fill(QColor(Qt::black).rgb());
+
+ QPainter expectedPainter(&expected);
+ expectedPainter.translate(105, 5);
+ expectedPainter.rotate(90);
+ expectedPainter.save();
+ expectedPainter.fillRect(widget.rect(),Qt::red);
+ expectedPainter.translate(10, 10);
+ expectedPainter.rotate(90);
+ expectedPainter.fillRect(QRect(0, 0, 20, 10), Qt::green);
+ expectedPainter.restore();
+ expectedPainter.translate(50, 50);
+ expectedPainter.fillRect(child.rect(),Qt::blue);
+ expectedPainter.translate(10, 10);
+ expectedPainter.rotate(90);
+ expectedPainter.fillRect(QRect(0, 0, 20, 10), Qt::green);
+ expectedPainter.end();
+
+#ifdef RENDER_DEBUG
+ expected.save("render_worldTransform_expected.png");
+#endif
+
+ QCOMPARE(image, expected);
+}
+
void tst_QWidget::setContentsMargins()
{
QLabel label("why does it always rain on me?");
diff --git a/tools/linguist/lupdate/qml.cpp b/tools/linguist/lupdate/qml.cpp
index 78a9afd..f33eae3 100644
--- a/tools/linguist/lupdate/qml.cpp
+++ b/tools/linguist/lupdate/qml.cpp
@@ -49,12 +49,12 @@
QT_BEGIN_NAMESPACE
-#include "parser/javascriptengine_p.h"
-#include "parser/javascriptparser_p.h"
-#include "parser/javascriptlexer_p.h"
-#include "parser/javascriptnodepool_p.h"
-#include "parser/javascriptastvisitor_p.h"
-#include "parser/javascriptast_p.h"
+#include "parser/qmljsengine_p.h"
+#include "parser/qmljsparser_p.h"
+#include "parser/qmljslexer_p.h"
+#include "parser/qmljsnodepool_p.h"
+#include "parser/qmljsastvisitor_p.h"
+#include "parser/qmljsast_p.h"
#include <QCoreApplication>
#include <QFile>
@@ -65,7 +65,7 @@ QT_BEGIN_NAMESPACE
#include <iostream>
#include <cstdlib>
-using namespace JavaScript;
+using namespace QmlJS;
class FindTrCalls: protected AST::Visitor
{
diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp
index 7a64f5f..d18be12 100644
--- a/tools/qdoc3/htmlgenerator.cpp
+++ b/tools/qdoc3/htmlgenerator.cpp
@@ -701,13 +701,17 @@ int HtmlGenerator::generateAtom(const Atom *atom,
else if (atom->string() == ATOM_LIST_VALUE) {
threeColumnEnumValueTable = isThreeColumnEnumValueTable(atom);
if (threeColumnEnumValueTable) {
- out() << "<p><table border=\"1\" cellpadding=\"2\" cellspacing=\"1\" width=\"100%\">\n"
- "<tr><th width=\"25%\">Constant</th><th width=\"15%\">Value</th>"
- "<th width=\"60%\">Description</th></tr>\n";
+ out() << "<p><table class=\"valuelist\" border=\"1\" cellpadding=\"2\" "
+ << "cellspacing=\"1\" width=\"100%\">\n"
+ << "<tr><th width=\"25%\">Constant</th>"
+ << "<th width=\"15%\">Value</th>"
+ << "<th width=\"60%\">Description</th></tr>\n";
}
else {
- out() << "<p><table border=\"1\" cellpadding=\"2\" cellspacing=\"1\" width=\"40%\">\n"
- << "<tr><th width=\"60%\">Constant</th><th width=\"40%\">Value</th></tr>\n";
+ out() << "<p><table class=\"valuelist\" border=\"1\" cellpadding=\"2\" "
+ << "cellspacing=\"1\" width=\"40%\">\n"
+ << "<tr><th width=\"60%\">Constant</th><th "
+ << "width=\"40%\">Value</th></tr>\n";
}
}
else {
@@ -881,14 +885,17 @@ int HtmlGenerator::generateAtom(const Atom *atom,
}
if (!atom->string().isEmpty()) {
if (atom->string().contains("%"))
- out() << "<p><table width=\"" << atom->string() << "\" "
+ out() << "<p><table class=\"generic\" width=\"" << atom->string() << "\" "
<< "align=\"center\" cellpadding=\"2\" "
<< "cellspacing=\"1\" border=\"0\">\n";
- else
- out() << "<p><table align=\"center\" cellpadding=\"2\" cellspacing=\"1\" border=\"0\">\n";
+ else {
+ out() << "<p><table class=\"generic\" align=\"center\" cellpadding=\"2\" "
+ << "cellspacing=\"1\" border=\"0\">\n";
+ }
}
else {
- out() << "<p><table align=\"center\" cellpadding=\"2\" cellspacing=\"1\" border=\"0\">\n";
+ out() << "<p><table class=\"generic\" align=\"center\" cellpadding=\"2\" "
+ << "cellspacing=\"1\" border=\"0\">\n";
}
numTableRows = 0;
break;
@@ -1102,6 +1109,7 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner,
if (!s->inherited.isEmpty())
needOtherSection = true;
} else {
+ out() << "<hr />\n";
out() << "<a name=\""
<< registerRef((*s).name.toLower())
<< "\"></a>\n";
@@ -1637,9 +1645,9 @@ void HtmlGenerator::generateTableOfContents(const Node *node,
QString tdTag;
if (numColumns > 1) {
- tdTag = "<td width=\"" +
- QString::number((100 + numColumns - 1) / numColumns) + "%\">";
- out() << "<p><table width=\"100%\">\n<tr valign=\"top\">" << tdTag << "\n";
+ tdTag = "<td width=\"" + QString::number((100 + numColumns - 1) / numColumns) + "%\">";
+ out() << "<p><table class=\"toc\" width=\"100%\">\n<tr valign=\"top\">"
+ << tdTag << "\n";
}
// disable nested links in table of contents
@@ -1879,7 +1887,8 @@ void HtmlGenerator::generateAnnotatedList(const Node *relative,
CodeMarker *marker,
const QMap<QString, const Node *> &nodeMap)
{
- out() << "<p><table width=\"100%\" class=\"annotated\" cellpadding=\"2\" cellspacing=\"1\" border=\"0\">\n";
+ out() << "<p><table width=\"100%\" class=\"annotated\" cellpadding=\"2\" "
+ << "cellspacing=\"1\" border=\"0\">\n";
int row = 0;
foreach (const QString &name, nodeMap.keys()) {
@@ -2036,7 +2045,7 @@ void HtmlGenerator::generateCompactList(const Node *relative,
}
firstOffset[NumColumns] = classMap.count();
- out() << "<p><table width=\"100%\">\n";
+ out() << "<p><table class=\"generic\" width=\"100%\">\n";
for (k = 0; k < numRows; k++) {
out() << "<tr>\n";
for (i = 0; i < NumColumns; i++) {
@@ -2362,12 +2371,12 @@ void HtmlGenerator::generateSectionList(const Section& section,
name_alignment = false;
}
if (name_alignment) {
- out() << "<table border=\"0\" cellpadding=\"0\" "
+ out() << "<table class=\"alignedsummary\" border=\"0\" cellpadding=\"0\" "
<< "cellspacing=\"0\" width=\"100%\">\n";
}
else {
if (twoColumn)
- out() << "<p><table width=\"100%\" "
+ out() << "<p><table class=\"propsummary\" width=\"100%\" "
<< "border=\"0\" cellpadding=\"0\""
<< " cellspacing=\"0\">\n"
<< "<tr><td width=\"45%\" valign=\"top\">";
@@ -2424,7 +2433,7 @@ void HtmlGenerator::generateSectionInheritedList(const Section& section,
QList<QPair<ClassNode *, int> >::ConstIterator p = section.inherited.begin();
while (p != section.inherited.end()) {
if (nameAlignment)
- out() << "<li><div bar=2 class=\"fn\"></div>";
+ out() << "<li><div bar=\"2\" class=\"fn\"></div>";
else
out() << "<li><div class=\"fn\"></div>";
out() << (*p).second << " ";
@@ -2485,7 +2494,7 @@ void HtmlGenerator::generateSynopsis(const Node *node,
QString HtmlGenerator::highlightedCode(const QString& markedCode,
CodeMarker *marker,
const Node *relative,
- CodeMarker::SynopsisStyle style,
+ CodeMarker::SynopsisStyle ,
bool nameAlignment)
{
QString src = markedCode;
@@ -2498,8 +2507,6 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode,
// replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*(</@link>)"
static const QString linkTag("link");
- if (src.contains("setAcceptDrops"))
- qDebug() << "SRC:" << src;
bool done = false;
for (int i = 0, n = src.size(); i < n;) {
if (src.at(i) == charLangle && src.at(i + 1).unicode() == '@') {
@@ -2664,12 +2671,13 @@ void HtmlGenerator::generateSectionList(const Section& section,
bool twoColumn = false;
if (style == CodeMarker::SeparateList) {
twoColumn = (section.members.count() >= 16);
- } else if (section.members.first()->type() == Node::Property) {
+ }
+ else if (section.members.first()->type() == Node::Property) {
twoColumn = (section.members.count() >= 5);
}
if (twoColumn)
- out() << "<p><table width=\"100%\" border=\"0\" cellpadding=\"0\""
- " cellspacing=\"0\">\n"
+ out() << "<p><table class=\"generic\" width=\"100%\" border=\"0\" "
+ << "cellpadding=\"0\" cellspacing=\"0\">\n"
<< "<tr><td width=\"45%\" valign=\"top\">";
out() << "<ul>\n";
@@ -2712,7 +2720,7 @@ void HtmlGenerator::generateSectionInheritedList(const Section& section,
{
QList<QPair<ClassNode *, int> >::ConstIterator p = section.inherited.begin();
while (p != section.inherited.end()) {
- out() << "<li><div bar=2 class=\"fn\"></div>";
+ out() << "<li><div bar=\"2\" class=\"fn\"></div>";
out() << (*p).second << " ";
if ((*p).second == 1) {
out() << section.singularMember;
@@ -3771,7 +3779,9 @@ void HtmlGenerator::generateDetailedQmlMember(const Node *node,
generateQmlItem(qpn, relative, marker, false);
out() << "</td></tr>";
if (qpgn->isDefault()) {
- out() << "<div class=\"qmlitem\">"
+ out() << "</table>"
+ << "</div></div>"
+ << "<div class=\"qmlitem\">"
<< "<div class=\"qmlproto\">"
<< "<table class=\"qmlname\">"
<< "<tr><td><font color=\"green\">"
@@ -3841,10 +3851,10 @@ void HtmlGenerator::generateQmlInherits(const QmlClassNode* cn,
generateText(text, cn, marker);
out() << "</p>";
}
- else
- qDebug() << "generateQmlInherits(): "
- << "Inherited element not documented -->"
- << linkPair.first;
+// else
+// qDebug() << "generateQmlInherits(): "
+// << "Inherited element not documented -->"
+// << linkPair.first;
}
}
}
diff --git a/tools/qdoc3/test/classic.css b/tools/qdoc3/test/classic.css
index 45d63db..d8c3d33 100644
--- a/tools/qdoc3/test/classic.css
+++ b/tools/qdoc3/test/classic.css
@@ -14,12 +14,49 @@ H3 {
h3.fn,span.fn
{
- background-color: #e0eff6;
+ background-color: #eee;
border-width: 1px;
border-style: solid;
- border-color: #3388be #e0eff6 #e9f8ff #e0eff6;
+ border-color: #ddd #ddd #ddd #ddd ;
font-weight: bold;
padding: 6px 0px 6px 10px;
+ margin: 42px 0px 0px 0px;
+}
+
+hr {
+ border: 0;
+ color: #9E9E9E;
+ background-color: #ccc;
+ height: 1px;
+ width: 100%;
+ text-align: left;
+ margin: 34px 0px 34px 0px;
+}
+
+table {
+ border-width: 1px 1px 1px 1px;
+ border-style: solid;
+ border-color: #dddddd;
+ border-collapse: collapse;
+ background-color: #f0f0f0;
+ margin-left: 1.5%;
+ width: 97%
+}
+
+table th {
+ border-width: 1px 1px 1px 2px;
+ padding: 4px;
+ border-style: solid;
+ border-color: #444;
+ color:white;
+ background-color:#444;
+}
+
+p {
+ margin-left: 1.5%;
+ margin-top: 8px;
+ width: 97%
+ margin-bottom: 8px;
}
a:link
@@ -66,7 +103,7 @@ body
table td.memItemLeft {
width: 200px;
- padding: 1px 0px 0px 8px;
+ padding: 2px 0px 0px 8px;
margin: 4px;
border-top-width: 1px;
border-right-width: 1px;
@@ -76,7 +113,7 @@ table td.memItemLeft {
border-right-color: #E0E0E0;
border-bottom-color: #E0E0E0;
border-left-color: #E0E0E0;
- border-top-style: solid;
+ border-top-style: none;
border-right-style: none;
border-bottom-style: none;
border-left-style: none;
@@ -85,7 +122,7 @@ table td.memItemLeft {
white-space: nowrap
}
table td.memItemRight {
- padding: 1px 8px 0px 8px;
+ padding: 2px 8px 0px 8px;
margin: 4px;
border-top-width: 1px;
border-right-width: 1px;
@@ -95,7 +132,7 @@ table td.memItemRight {
border-right-color: #E0E0E0;
border-bottom-color: #E0E0E0;
border-left-color: #E0E0E0;
- border-top-style: solid;
+ border-top-style: none;
border-right-style: none;
border-bottom-style: none;
border-left-style: none;
diff --git a/util/local_database/qlocalexml2cpp.py b/util/local_database/qlocalexml2cpp.py
index af6da33..d625cfd 100755
--- a/util/local_database/qlocalexml2cpp.py
+++ b/util/local_database/qlocalexml2cpp.py
@@ -318,7 +318,7 @@ def main():
print
# Locale index
- print "static const uint locale_index[] = {"
+ print "static const quint16 locale_index[] = {"
print " 0, // unused"
index = 0
for key in language_map.keys():
@@ -454,7 +454,7 @@ def main():
print
# Language name index
- print "static const uint language_name_index[] = {"
+ print "static const quint16 language_name_index[] = {"
print " 0, // Unused"
index = 8
for key in language_map.keys():
@@ -477,7 +477,7 @@ def main():
print
# Country name index
- print "static const uint country_name_index[] = {"
+ print "static const quint16 country_name_index[] = {"
print " 0, // AnyCountry"
index = 8
for key in country_map.keys():