tk8.5
DK without yielding
the warning message "No SDK specified: Defaulting to ...".
Reviewed-by: mauricek
---
tools/checksdk/main.cpp | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/tools/checksdk/main.cpp b/tools/checksdk/main.cpp
index 1d4b616..717f5c9 100644
--- a/tools/checksdk/main.cpp
+++ b/tools/checksdk/main.cpp
@@ -97,12 +97,6 @@ int main(int argc, char **argv)
}
}
- // Check for SDK Name, otherwise use Windows Mobile as default
- if (sdkName.isEmpty()) {
- qWarning("No SDK specified: Defaulting to Windows Mobile 5.0 Pocket PC SDK");
- sdkName = QString::fromLatin1("Windows Mobile 5.0 Pocket PC SDK (ARMV4I)");
- }
-
CeSdkHandler handler;
if (!handler.parse()) {
qWarning("Could not find any installed SDK, aborting!");
@@ -118,6 +112,12 @@ int main(int argc, char **argv)
return 0;
}
+ // Check for SDK Name, otherwise use Windows Mobile as default
+ if (sdkName.isEmpty()) {
+ qWarning("No SDK specified: Defaulting to Windows Mobile 5.0 Pocket PC SDK");
+ sdkName = QString::fromLatin1("Windows Mobile 5.0 Pocket PC SDK (ARMV4I)");
+ }
+
// finally find the given SDK and prompt out the environment to be set
for (QList::iterator it = list.begin(); it != list.end(); ++it ) {
if (sdkName == it->name()) {
--
cgit v0.12
From 38b5bff2fab59e965aba59b4f121a7c8945e4d75 Mon Sep 17 00:00:00 2001
From: Kavindra Devi Palaraja
Date: Mon, 6 Apr 2009 12:39:13 +0200
Subject: Doc - Clarified that button style on X11 platforms may depend on the
desktop environment.
Task-number: 250338
Reviewed-by: Jens Bache-Wiig
---
src/gui/widgets/qdialogbuttonbox.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/gui/widgets/qdialogbuttonbox.cpp b/src/gui/widgets/qdialogbuttonbox.cpp
index 246da95..4a95292 100644
--- a/src/gui/widgets/qdialogbuttonbox.cpp
+++ b/src/gui/widgets/qdialogbuttonbox.cpp
@@ -752,7 +752,8 @@ QDialogButtonBox::~QDialogButtonBox()
\value KdeLayout Use a policy appropriate for applications on KDE.
\value GnomeLayout Use a policy appropriate for applications on GNOME.
- The button layout is specified by the \l{style()}{current style}.
+ The button layout is specified by the \l{style()}{current style}. However,
+ on the X11 platform, it may be influenced by the desktop environment.
*/
/*!
--
cgit v0.12
From 1a125061f201bb7ee746f1eddc0604cd85a6545c Mon Sep 17 00:00:00 2001
From: jasplin
Date: Mon, 6 Apr 2009 12:43:53 +0200
Subject: Corrected typo.
Reviewed-by: jasplin
---
dist/README | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dist/README b/dist/README
index 110be1c..38b3a1c 100644
--- a/dist/README
+++ b/dist/README
@@ -114,7 +114,7 @@ HOW TO REPORT A BUG
If you think you have found a bug in Qt, we would like to hear about
it so that we can fix it. Before reporting a bug, please check
http://qtsoftware.com/developer/faqs/ and
-http://qtsoftware.com/products/appdev/platform/platforms/ to see if the to see if
+http://qtsoftware.com/products/appdev/platform/platforms/ to see if
the issue is already known.
Always include the following information in your bug report: the name
--
cgit v0.12
From 73f5131793d52d93b18a40d36599e063f18246e9 Mon Sep 17 00:00:00 2001
From: Thiago Macieira
Date: Mon, 6 Apr 2009 11:18:34 +0200
Subject: Install the animation.mng file.
Otherwise, for people who install Qt (everyone outside Nokia), the
animation file isn't present.
Reviewed-by: Trust Me
BT: yes
---
examples/widgets/movie/movie.pro | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/examples/widgets/movie/movie.pro b/examples/widgets/movie/movie.pro
index b5f0a7a..1c7cbae 100644
--- a/examples/widgets/movie/movie.pro
+++ b/examples/widgets/movie/movie.pro
@@ -4,6 +4,6 @@ SOURCES = main.cpp \
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/movie
-sources.files = $$SOURCES $$HEADERS $$RESOURCES movie.pro movies
+sources.files = $$SOURCES $$HEADERS $$RESOURCES movie.pro animation.mng
sources.path = $$[QT_INSTALL_EXAMPLES]/widgets/movie
INSTALLS += target sources
--
cgit v0.12
From 5bb504a78cad5e38cd522785a37898f4e88cd272 Mon Sep 17 00:00:00 2001
From: Thiago Macieira
Date: Mon, 6 Apr 2009 13:16:39 +0200
Subject: Rename these files to have lowercase .txt extension.
mkdist doesn't case-insensitive comparison.
Reviewed-by: TrustMe
BT: yes
---
FAQ | 18 ------------------
FAQ.txt | 18 ++++++++++++++++++
LGPL_EXCEPTION.TXT | 3 ---
LGPL_EXCEPTION.txt | 3 +++
4 files changed, 21 insertions(+), 21 deletions(-)
delete mode 100644 FAQ
create mode 100644 FAQ.txt
delete mode 100644 LGPL_EXCEPTION.TXT
create mode 100644 LGPL_EXCEPTION.txt
diff --git a/FAQ b/FAQ
deleted file mode 100644
index c243e5c..0000000
--- a/FAQ
+++ /dev/null
@@ -1,18 +0,0 @@
-This is a list of Frequently Asked Questions regarding Qt Release 4.5.0.
-
-Q: I'm using a Unix system and I downloaded the Zip package. However, when I try
-to run the configure script, I get the following error message:
-"bash: ./configure: /bin/sh^M: bad interpreter: No such file or directory"
-A: The problem here is converting files from Windows style line endings (CRLF)
-to Unix style line endings (LF). To avoid this problem, uncompress the file
-again and give the option "-a" to unzip, which will then add the correct line
-endings.
-
-Q: I'm running Windows XP and I downloaded the qt-win-eval-4.5.0-vs2008.exe
-version of Qt. However, when I try to run the examples I get an error saying:
-"The application failed to start because the application configuration is
-incorrect. Reinstalling the application may fix this problem.". I reinstalled
-the package but the error persists. What am I doing wrong?
-A: The problem is an incorrect version of the CRT. Visual studio requires CRT90
-while Windows XP comes with CRT80. To solve this problem, please install the
-2008 CRT redistributable package from Microsoft.
diff --git a/FAQ.txt b/FAQ.txt
new file mode 100644
index 0000000..c243e5c
--- /dev/null
+++ b/FAQ.txt
@@ -0,0 +1,18 @@
+This is a list of Frequently Asked Questions regarding Qt Release 4.5.0.
+
+Q: I'm using a Unix system and I downloaded the Zip package. However, when I try
+to run the configure script, I get the following error message:
+"bash: ./configure: /bin/sh^M: bad interpreter: No such file or directory"
+A: The problem here is converting files from Windows style line endings (CRLF)
+to Unix style line endings (LF). To avoid this problem, uncompress the file
+again and give the option "-a" to unzip, which will then add the correct line
+endings.
+
+Q: I'm running Windows XP and I downloaded the qt-win-eval-4.5.0-vs2008.exe
+version of Qt. However, when I try to run the examples I get an error saying:
+"The application failed to start because the application configuration is
+incorrect. Reinstalling the application may fix this problem.". I reinstalled
+the package but the error persists. What am I doing wrong?
+A: The problem is an incorrect version of the CRT. Visual studio requires CRT90
+while Windows XP comes with CRT80. To solve this problem, please install the
+2008 CRT redistributable package from Microsoft.
diff --git a/LGPL_EXCEPTION.TXT b/LGPL_EXCEPTION.TXT
deleted file mode 100644
index 8d0f85e..0000000
--- a/LGPL_EXCEPTION.TXT
+++ /dev/null
@@ -1,3 +0,0 @@
-Nokia Qt LGPL Exception version 1.0
-
-As a special exception to the GNU Lesser General Public License version 2.1, the object code form of a "work that uses the Library" may incorporate material from a header file that is part of the Library. You may distribute such object code under terms of your choice, provided that the incorporated material (i) does not exceed more than 5% of the total size of the Library; and (ii) is limited to numerical parameters, data structure layouts, accessors, macros, inline functions and templates.
\ No newline at end of file
diff --git a/LGPL_EXCEPTION.txt b/LGPL_EXCEPTION.txt
new file mode 100644
index 0000000..8d0f85e
--- /dev/null
+++ b/LGPL_EXCEPTION.txt
@@ -0,0 +1,3 @@
+Nokia Qt LGPL Exception version 1.0
+
+As a special exception to the GNU Lesser General Public License version 2.1, the object code form of a "work that uses the Library" may incorporate material from a header file that is part of the Library. You may distribute such object code under terms of your choice, provided that the incorporated material (i) does not exceed more than 5% of the total size of the Library; and (ii) is limited to numerical parameters, data structure layouts, accessors, macros, inline functions and templates.
\ No newline at end of file
--
cgit v0.12
From cf65dea821a2ba796bb1f32c80de6b9db224dff5 Mon Sep 17 00:00:00 2001
From: Kavindra Devi Palaraja
Date: Mon, 6 Apr 2009 13:15:00 +0200
Subject: Doc - Mentioned what the default filters are for
QFileSystemModel::filter().
Task-number: 250285
Reviewed-by: Benjamin Poulain
---
src/gui/dialogs/qfilesystemmodel.cpp | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/gui/dialogs/qfilesystemmodel.cpp b/src/gui/dialogs/qfilesystemmodel.cpp
index c7b3137..012d3a1 100644
--- a/src/gui/dialogs/qfilesystemmodel.cpp
+++ b/src/gui/dialogs/qfilesystemmodel.cpp
@@ -1430,7 +1430,10 @@ void QFileSystemModel::setFilter(QDir::Filters filters)
}
/*!
- Returns the filter specification for the directory model.
+ Returns the filter specified for the directory model.
+
+ If a filter has not been set, the default filter is QDir::AllEntries |
+ QDir::NoDotAndDotDot | QDir::AllDirs.
\sa QDir::Filters
*/
--
cgit v0.12
From e27743bdeda7aa3cb42f2d81a521121f8ee04eae Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Wed, 25 Feb 2009 12:18:28 +0100
Subject: Fixes: Optimize QGraphicsView::itemUpdated.
Task: -
RevBy: Andreas
AutoTest: -
Details: Accumulate the parentToItem transform as we iterate instead of
creating it from bottom-up each time.
---
src/gui/graphicsview/qgraphicsview.cpp | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index 2f7f57a..9b0e12d 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -804,10 +804,17 @@ void QGraphicsViewPrivate::itemUpdated(QGraphicsItem *item, const QRectF &rect)
if (item->isClipped()) {
// Minimize unnecessary redraw.
QGraphicsItem *p = item;
+ QTransform xform;
+ QGraphicsItem *lastTransformItem = 0;
while ((p = p->d_ptr->parent)) {
if (p->flags() & QGraphicsItem::ItemClipsChildrenToShape) {
- updateRect &= p->itemTransform(item).mapRect(p->boundingRect());
- if (updateRect.isNull())
+ if (!lastTransformItem)
+ xform = item->itemTransform(p);
+ else
+ xform *= lastTransformItem->itemTransform(p);
+ lastTransformItem = p;
+ updateRect &= xform.inverted().mapRect(p->boundingRect());
+ if (updateRect.isEmpty())
return;
}
@@ -815,7 +822,7 @@ void QGraphicsViewPrivate::itemUpdated(QGraphicsItem *item, const QRectF &rect)
break;
}
- if (updateRect.isNull())
+ if (updateRect.isEmpty())
return;
}
--
cgit v0.12
From be6be8c73929f2ddee9a02f59db05c3ba453a63e Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Thu, 26 Feb 2009 14:49:47 +0100
Subject: Fixes: Optimize QGraphicsViewPrivate::updateRect()/updateRegion().
Details: Those cut-offs are extremely important. After few seconds
interaction with the iphone demo, updateRect() was called
approx. 3000 times with an empty rect. Then imagine what
happens when having e.g. FullViewportUpdate. We do
q->viewport()->update() JUST FOR FUN!
---
src/gui/graphicsview/qgraphicsview.cpp | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index 9b0e12d..aa5f069 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -928,6 +928,9 @@ void QGraphicsViewPrivate::updateAll()
void QGraphicsViewPrivate::updateRegion(const QRegion &r)
{
+ if (r.isEmpty())
+ return;
+
Q_Q(QGraphicsView);
// Rect intersects viewport - update everything?
@@ -976,6 +979,9 @@ void QGraphicsViewPrivate::updateRegion(const QRegion &r)
void QGraphicsViewPrivate::updateRect(const QRect &r)
{
+ if (r.isEmpty())
+ return;
+
Q_Q(QGraphicsView);
// Rect intersects viewport - update everything?
--
cgit v0.12
From e9fa8ba1ad0b0b2d3363fb33635071677f42b983 Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Thu, 26 Feb 2009 15:00:08 +0100
Subject: Fixes: Cleanup calls to
QGraphicsViewPrivate::updateRect()/updateRegion()
Details: Checking for QRect::isNull() was wrong in the first place, and
checking for isEmpty()/isNull() is overhead after
4a491a84aeba68279927597a261522dcc23bb3ff.
---
src/gui/graphicsview/qgraphicsview.cpp | 19 +++++--------------
1 file changed, 5 insertions(+), 14 deletions(-)
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index aa5f069..b92c886 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -829,17 +829,10 @@ void QGraphicsViewPrivate::itemUpdated(QGraphicsItem *item, const QRectF &rect)
// Map the rect to view coordinates.
QRect vr = viewport->rect();
- if (!item->d_ptr->hasBoundingRegionGranularity) {
- QRect r = mapToViewRect(item, updateRect) & vr;
- if (r.isNull())
- return;
- this->updateRect(r);
- } else {
- QRegion r = mapToViewRegion(item, updateRect) & vr;
- if (r.isEmpty())
- return;
- updateRegion(r);
- }
+ if (!item->d_ptr->hasBoundingRegionGranularity)
+ this->updateRect(mapToViewRect(item, updateRect) & vr);
+ else
+ updateRegion(mapToViewRegion(item, updateRect) & vr);
}
void QGraphicsViewPrivate::updateLater()
@@ -863,9 +856,7 @@ void QGraphicsViewPrivate::_q_updateLaterSlot()
for (int i = 0; i < dirtyItems.size(); ++i) {
const QGraphicsItem *item = dirtyItems.at(i);
QTransform x = item->sceneTransform() * viewTransform;
- QRect viewRect = x.mapRect(item->boundingRect()).toAlignedRect() & vr;
- if (!viewRect.isNull())
- updateRect(viewRect);
+ updateRect(x.mapRect(item->boundingRect()).toAlignedRect() & vr);
}
dirtyRectCount += dirtyRects.size();
--
cgit v0.12
From 8a2ebc96220f50be3a9c382c32d7eaab89921ff7 Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Thu, 26 Feb 2009 15:47:04 +0100
Subject: Fixes: Use QRect::isEmpty() rather than isNull() if possible.
RevBy: Andreas
Details: Note that isNull() implies isEmpty(), but it only catches
the cases where width and height is 0.
---
src/gui/graphicsview/qgraphicsitem.cpp | 2 +-
src/gui/graphicsview/qgraphicsscene.cpp | 2 +-
src/gui/graphicsview/qgraphicsview.cpp | 10 +++++-----
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 83a7e67..b982393 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -3757,7 +3757,7 @@ bool QGraphicsItemPrivate::isProxyWidget() const
*/
void QGraphicsItem::update(const QRectF &rect)
{
- if (d_ptr->dirty)
+ if (d_ptr->dirty || (rect.isEmpty() && !rect.isNull()))
return;
if (d_ptr->scene && isVisible()) {
if (CacheMode(d_ptr->cacheMode) != NoCache) {
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index ff46e2e..9b06945 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -3455,7 +3455,7 @@ QVariant QGraphicsScene::inputMethodQuery(Qt::InputMethodQuery query) const
void QGraphicsScene::update(const QRectF &rect)
{
Q_D(QGraphicsScene);
- if (d->updateAll)
+ if (d->updateAll || (rect.isEmpty() && !rect.isNull()))
return;
// Check if anyone's connected; if not, we can send updates directly to
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index b92c886..f88918f 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -862,7 +862,7 @@ void QGraphicsViewPrivate::_q_updateLaterSlot()
dirtyRectCount += dirtyRects.size();
bool noUpdate = !fullUpdatePending && viewportUpdateMode == QGraphicsView::FullViewportUpdate;
- if ((dirtyRectCount > 0 || !dirtyBoundingRect.isNull()) && !fullUpdatePending && !noUpdate) {
+ if ((dirtyRectCount > 0 || !dirtyBoundingRect.isEmpty()) && !fullUpdatePending && !noUpdate) {
if (viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate
|| (viewportUpdateMode == QGraphicsView::SmartViewportUpdate
&& dirtyRectCount >= QGRAPHICSVIEW_REGION_RECT_THRESHOLD)) {
@@ -3284,7 +3284,7 @@ void QGraphicsView::mouseMoveEvent(QMouseEvent *event)
}
// Update old rubberband
- if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate && !d->rubberBandRect.isNull()) {
+ if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate && !d->rubberBandRect.isEmpty()) {
if (d->viewportUpdateMode != FullViewportUpdate)
viewport()->update(d->rubberBandRegion(viewport(), d->rubberBandRect));
else
@@ -3466,7 +3466,7 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
QPainter painter(viewport());
QTransform original = painter.worldTransform();
#ifndef QT_NO_RUBBERBAND
- if (d->rubberBanding && !d->rubberBandRect.isNull())
+ if (d->rubberBanding && !d->rubberBandRect.isEmpty())
painter.save();
#endif
// Set up render hints
@@ -3561,7 +3561,7 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
#ifndef QT_NO_RUBBERBAND
// Rubberband
- if (d->rubberBanding && !d->rubberBandRect.isNull()) {
+ if (d->rubberBanding && !d->rubberBandRect.isEmpty()) {
painter.restore();
QStyleOptionRubberBand option;
option.initFrom(viewport());
@@ -3645,7 +3645,7 @@ void QGraphicsView::scrollContentsBy(int dx, int dy)
#ifndef QT_NO_RUBBERBAND
// Update old rubberband
- if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate && !d->rubberBandRect.isNull()) {
+ if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate && !d->rubberBandRect.isEmpty()) {
if (d->viewportUpdateMode != FullViewportUpdate)
viewport()->update(d->rubberBandRegion(viewport(), d->rubberBandRect));
else
--
cgit v0.12
From eda77b7c410a59d1b77c263994679452613d9d0b Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Fri, 27 Feb 2009 16:00:55 +0100
Subject: Fixes: Small optimization: reduce calls to QTransform::type().
Task: none
RevBy: Ariya Hidayat
AutoTest: Still pass.
Details: QTransform::type() is cached, so only the first call to it
should be expensive. However, it is not inlined so there's
an overhead involved (especially when these functions are
called a gazillion times).
---
src/gui/painting/qtransform.cpp | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp
index c70208c..c120143 100644
--- a/src/gui/painting/qtransform.cpp
+++ b/src/gui/painting/qtransform.cpp
@@ -1222,7 +1222,8 @@ static QPolygonF mapProjective(const QTransform &transform, const QPolygonF &pol
*/
QPolygonF QTransform::map(const QPolygonF &a) const
{
- if (type() >= QTransform::TxProject)
+ TransformationType t = type();
+ if (t >= QTransform::TxProject)
return mapProjective(*this, a);
int size = a.size();
@@ -1231,7 +1232,6 @@ QPolygonF QTransform::map(const QPolygonF &a) const
const QPointF *da = a.constData();
QPointF *dp = p.data();
- TransformationType t = type();
for(i = 0; i < size; ++i) {
MAP(da[i].xp, da[i].yp, dp[i].xp, dp[i].yp);
}
@@ -1249,7 +1249,8 @@ QPolygonF QTransform::map(const QPolygonF &a) const
*/
QPolygon QTransform::map(const QPolygon &a) const
{
- if (type() >= QTransform::TxProject)
+ TransformationType t = type();
+ if (t >= QTransform::TxProject)
return mapProjective(*this, QPolygonF(a)).toPolygon();
int size = a.size();
@@ -1258,7 +1259,6 @@ QPolygon QTransform::map(const QPolygon &a) const
const QPoint *da = a.constData();
QPoint *dp = p.data();
- TransformationType t = type();
for(i = 0; i < size; ++i) {
qreal nx = 0, ny = 0;
MAP(da[i].xp, da[i].yp, nx, ny);
@@ -2061,10 +2061,11 @@ QTransform::operator QVariant() const
Q_GUI_EXPORT
bool qt_scaleForTransform(const QTransform &transform, qreal *scale)
{
- if (transform.type() <= QTransform::TxTranslate) {
+ const QTransform::TransformationType type = transform.type();
+ if (type <= QTransform::TxTranslate) {
*scale = 1;
return true;
- } else if (transform.type() == QTransform::TxScale) {
+ } else if (type == QTransform::TxScale) {
const qreal xScale = qAbs(transform.m11());
const qreal yScale = qAbs(transform.m22());
*scale = qMax(xScale, yScale);
@@ -2076,7 +2077,7 @@ bool qt_scaleForTransform(const QTransform &transform, qreal *scale)
const qreal yScale = transform.m12() * transform.m12()
+ transform.m22() * transform.m22();
*scale = qSqrt(qMax(xScale, yScale));
- return transform.type() == QTransform::TxRotate && qFuzzyCompare(xScale, yScale);
+ return type == QTransform::TxRotate && qFuzzyCompare(xScale, yScale);
}
QT_END_NAMESPACE
--
cgit v0.12
From b4456f8775c36bcb2ceef9ca1a00c7765f1d2735 Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Fri, 27 Feb 2009 18:10:08 +0100
Subject: Fixes: Get rid of a gazillion calls to QTransform::operator*=.
Details: Be a little bit smarter before doing *= :)
---
src/gui/graphicsview/qgraphicsitem.cpp | 38 +++++++++++++++++++++------------
src/gui/graphicsview/qgraphicsscene.cpp | 5 +++--
2 files changed, 27 insertions(+), 16 deletions(-)
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index b982393..bb95543 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -2511,10 +2511,10 @@ QTransform QGraphicsItem::sceneTransform() const
QTransform m;
if (d_ptr->hasTransform) {
m = transform();
- m *= QTransform::fromTranslate(d_ptr->pos.x(), d_ptr->pos.y());
- } else {
- // ### ? QTransform::fromTranslate(d_ptr->pos.x(), d_ptr->pos.y())
- m.translate(d_ptr->pos.x(), d_ptr->pos.y());
+ 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.
@@ -2639,6 +2639,8 @@ QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) co
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());
@@ -2649,7 +2651,8 @@ QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) co
const QPointF &otherPos = other->d_ptr->pos;
if (other->d_ptr->hasTransform) {
QTransform otherToParent = other->transform();
- otherToParent *= QTransform::fromTranslate(otherPos.x(), otherPos.y());
+ if (!otherPos.isNull())
+ otherToParent *= QTransform::fromTranslate(otherPos.x(), otherPos.y());
return otherToParent.inverted(ok);
} else {
if (ok)
@@ -2674,11 +2677,11 @@ QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) co
QTransform itemToParent = QTransform::fromTranslate(itemPos.x(), itemPos.y());
if (hasTr)
- itemToParent = transform() * itemToParent;
+ itemToParent = itemPos.isNull() ? transform() : transform() * itemToParent;
QTransform otherToParent = QTransform::fromTranslate(otherPos.x(), otherPos.y());
if (otherHasTr)
- otherToParent = other->transform() * otherToParent;
+ otherToParent = otherPos.isNull() ? other->transform() : other->transform() * otherToParent;
return itemToParent * otherToParent.inverted(ok);
}
@@ -2718,7 +2721,8 @@ QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) co
const QGraphicsItemPrivate *pd = p->d_ptr;
if (pd->hasTransform)
x *= p->transform();
- x *= QTransform::fromTranslate(pd->pos.x(), pd->pos.y());
+ if (!pd->pos.isNull())
+ x *= QTransform::fromTranslate(pd->pos.x(), pd->pos.y());
} while ((p = p->d_ptr->parent) && p != root);
if (parentOfOther)
return x.inverted(ok);
@@ -2995,7 +2999,9 @@ QRectF QGraphicsItem::childrenBoundingRect() const
QRectF childRect;
foreach (QGraphicsItem *child, children()) {
QPointF childPos = child->pos();
- QTransform matrix = child->transform() * QTransform::fromTranslate(childPos.x(), childPos.y());
+ QTransform matrix = child->transform();
+ if (!childPos.isNull())
+ matrix *= QTransform::fromTranslate(childPos.x(), childPos.y());
childRect |= matrix.mapRect(child->boundingRect() | child->childrenBoundingRect());
}
return childRect;
@@ -8544,13 +8550,17 @@ void QGraphicsItemGroup::addToGroup(QGraphicsItem *item)
QTransform oldSceneMatrix = item->sceneTransform();
item->setPos(mapFromItem(item, 0, 0));
item->setParentItem(this);
- item->setTransform(oldSceneMatrix
- * sceneTransform().inverted()
- * QTransform::fromTranslate(-item->x(), -item->y()));
+ QTransform newItemTransform(oldSceneMatrix);
+ newItemTransform *= sceneTransform().inverted();
+ if (!item->pos().isNull())
+ newItemTransform *= QTransform::fromTranslate(-item->x(), -item->y());
+ item->setTransform(newItemTransform);
item->d_func()->setIsMemberOfGroup(true);
prepareGeometryChange();
- d->itemsBoundingRect |= (item->transform() * QTransform::fromTranslate(item->x(), item->y()))
- .mapRect(item->boundingRect() | item->childrenBoundingRect());
+ QTransform itemTransform(item->transform());
+ if (!item->pos().isNull())
+ itemTransform *= QTransform::fromTranslate(item->x(), item->y());
+ d->itemsBoundingRect |= itemTransform.mapRect(item->boundingRect() | item->childrenBoundingRect());
update();
}
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 9b06945..b509507 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -4772,8 +4772,9 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
if (itemCache->allExposed || !itemCache->exposed.isEmpty() || !scrollExposure.isEmpty()) {
// Construct an item-to-pixmap transform.
QPointF p = deviceRect.topLeft();
- QTransform itemToPixmap = QTransform::fromTranslate(-p.x(), -p.y());
- itemToPixmap = painter->worldTransform() * itemToPixmap;
+ QTransform itemToPixmap = painter->worldTransform();
+ if (!p.isNull())
+ itemToPixmap *= QTransform::fromTranslate(-p.x(), -p.y());
// Map the item's logical expose to pixmap coordinates.
QRegion pixmapExposed = scrollExposure;
--
cgit v0.12
From fac3c7b73ba2c6b39332445ae00b2fe26a578913 Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Mon, 2 Mar 2009 10:34:50 +0100
Subject: Fixes: Optimization: Important cut-offs for QTransform.
Task: none
RevBy: Samuel
AutoTest: Still pass
Details: Please do not perform (potentially expensive) calculations just for fun :)
---
src/gui/painting/qtransform.cpp | 29 ++++++++++++++++++++++++++---
src/gui/painting/qtransform.h | 8 ++++++++
2 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp
index c120143..fa808d0 100644
--- a/src/gui/painting/qtransform.cpp
+++ b/src/gui/painting/qtransform.cpp
@@ -399,6 +399,9 @@ QTransform QTransform::inverted(bool *invertible) const
*/
QTransform & QTransform::translate(qreal dx, qreal dy)
{
+ if (dx == 0 && dy == 0)
+ return *this;
+
switch(type()) {
case TxNone:
affine._dx = dx;
@@ -435,7 +438,10 @@ QTransform & QTransform::translate(qreal dx, qreal dy)
QTransform QTransform::fromTranslate(qreal dx, qreal dy)
{
QTransform transform(1, 0, 0, 1, dx, dy);
- transform.m_dirty = TxTranslate;
+ if (dx == 0 && dy == 0)
+ transform.m_dirty = TxNone;
+ else
+ transform.m_dirty = TxTranslate;
return transform;
}
@@ -447,6 +453,9 @@ QTransform QTransform::fromTranslate(qreal dx, qreal dy)
*/
QTransform & QTransform::scale(qreal sx, qreal sy)
{
+ if (sx == 1 && sy == 1)
+ return *this;
+
switch(type()) {
case TxNone:
case TxTranslate:
@@ -481,7 +490,10 @@ QTransform & QTransform::scale(qreal sx, qreal sy)
QTransform QTransform::fromScale(qreal sx, qreal sy)
{
QTransform transform(sx, 0, 0, sy, 0, 0);
- transform.m_dirty = TxScale;
+ if (sx == 1 && sy == 1)
+ transform.m_dirty = TxNone;
+ else
+ transform.m_dirty = TxScale;
return transform;
}
@@ -544,6 +556,9 @@ const qreal inv_dist_to_plane = 1. / 1024.;
*/
QTransform & QTransform::rotate(qreal a, Qt::Axis axis)
{
+ if (a == 0)
+ return *this;
+
qreal sina = 0;
qreal cosa = 0;
if (a == 90. || a == -270.)
@@ -715,7 +730,15 @@ bool QTransform::operator!=(const QTransform &o) const
*/
QTransform & QTransform::operator*=(const QTransform &o)
{
- TransformationType t = qMax(type(), o.type());
+ const TransformationType otherType = o.type();
+ if (otherType == TxNone)
+ return *this;
+
+ const TransformationType thisType = type();
+ if (thisType == TxNone)
+ return operator=(o);
+
+ TransformationType t = qMax(thisType, otherType);
switch(t) {
case TxNone:
break;
diff --git a/src/gui/painting/qtransform.h b/src/gui/painting/qtransform.h
index de7ebcd..c76409b 100644
--- a/src/gui/painting/qtransform.h
+++ b/src/gui/painting/qtransform.h
@@ -257,6 +257,8 @@ inline qreal QTransform::dy() const
inline QTransform &QTransform::operator*=(qreal num)
{
+ if (num == 1.)
+ return *this;
affine._m11 *= num;
affine._m12 *= num;
m_13 *= num;
@@ -271,11 +273,15 @@ inline QTransform &QTransform::operator*=(qreal num)
}
inline QTransform &QTransform::operator/=(qreal div)
{
+ if (div == 0)
+ return *this;
div = 1/div;
return operator*=(div);
}
inline QTransform &QTransform::operator+=(qreal num)
{
+ if (num == 0)
+ return *this;
affine._m11 += num;
affine._m12 += num;
m_13 += num;
@@ -290,6 +296,8 @@ inline QTransform &QTransform::operator+=(qreal num)
}
inline QTransform &QTransform::operator-=(qreal num)
{
+ if (num == 0)
+ return *this;
affine._m11 -= num;
affine._m12 -= num;
m_13 -= num;
--
cgit v0.12
From ab130a0019fadeff4622778ca9f8b3e630da14da Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Mon, 2 Mar 2009 16:22:20 +0100
Subject: Fixes: Speed up QGrahicsItemPrivate::effectiveOpacity().
RevBy: Andreas
AutoTest: tst_QGraphicsItem::opacity still passes
---
src/gui/graphicsview/qgraphicsitem.cpp | 12 +++++++++++-
src/gui/graphicsview/qgraphicsitem_p.h | 2 ++
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index bb95543..cda1bd1 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -1862,6 +1862,9 @@ 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());
}
@@ -3680,7 +3683,14 @@ void QGraphicsItemPrivate::resolveEffectiveOpacity(qreal parentEffectiveOpacity)
}
// Set this item's resolved opacity.
- setExtra(ExtraEffectiveOpacity, myEffectiveOpacity);
+ if (qFuzzyCompare(myEffectiveOpacity, qreal(1.0))) {
+ // 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)
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index 07f6958..98fe6ed 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -133,6 +133,7 @@ public:
hasBoundingRegionGranularity(0),
flags(0),
hasOpacity(0),
+ hasEffectiveOpacity(0),
isWidget(0),
dirty(0),
dirtyChildren(0),
@@ -262,6 +263,7 @@ public:
// New 32 bytes
quint32 hasOpacity : 1;
+ quint32 hasEffectiveOpacity : 1;
quint32 isWidget : 1;
quint32 dirty : 1;
quint32 dirtyChildren : 1;
--
cgit v0.12
From 7f50f45da0ad4a9eedd3ad7d8a82f719f7f8dd73 Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Tue, 3 Mar 2009 13:06:05 +0100
Subject: Fixes: Optimize: QGraphicsItem::clipPath.
RevBy: Andreas
AutoTest: Still pass
---
src/gui/graphicsview/qgraphicsitem.cpp | 46 +++++++++++-----------------------
1 file changed, 15 insertions(+), 31 deletions(-)
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index cda1bd1..8b37648 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -3143,48 +3143,32 @@ QPainterPath QGraphicsItem::clipPath() const
// Start with the item's bounding rect.
clip.addRect(boundingRect());
- bool clipAway = false;
if (d->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
- // Make list of parents up to the farthest ancestor that clips its
- // children to its shape.
- QVarLengthArray clippingAncestors;
- const QGraphicsItem *parent = parentItem();
- const QGraphicsItem *clipOwner = 0;
- do {
+ const QGraphicsItem *parent = this;
+ const QGraphicsItem *lastParent = this;
+
+ // Intersect any in-between clips starting at the top and moving downwards.
+ while ((parent = parent->d_ptr->parent)) {
if (parent->d_ptr->flags & ItemClipsChildrenToShape) {
- clippingAncestors.append(parent);
- clipOwner = parent;
+ // Map clip to the current parent and intersect with its shape.
+ clip = (lastParent->itemTransform(parent).map(clip)).intersected(parent->shape());
+ if (clip.isEmpty())
+ return clip;
+ lastParent = parent;
}
- } while ((parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) && (parent = parent->parentItem()));
-
- // Start with the topmost clip.
- QPainterPath parentClip = clipOwner->shape();
- // Intersect any in-between clips starting at the bottom and moving
- // upwards.
- for (int i = clippingAncestors.size() - 2; i >= 0; --i) {
- const QGraphicsItem *item = clippingAncestors[i];
- // ### what if itemtransform fails
- if (clipOwner)
- parentClip = clipOwner->itemTransform(item).map(parentClip);
- parentClip = parentClip.intersected(item->shape());
- if (parentClip.isEmpty()) {
- clip = parentClip;
- clipAway = true;
+ if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren))
break;
- }
- clipOwner = item;
}
- if (!clipAway) {
+ if (lastParent != this) {
+ // Map clip back to the item's transform.
// ### what if itemtransform fails
- clip = clip.intersected(clipOwner->itemTransform(this).map(parentClip));
- if (clip.isEmpty())
- clipAway = true;
+ clip = lastParent->itemTransform(this).map(clip);
}
}
- if (!clipAway && d->flags & ItemClipsToShape)
+ if (d->flags & ItemClipsToShape)
clip = clip.intersected(shape());
return clip;
--
cgit v0.12
From b67dffcccea9166918ac93c281d87fd5eb3baf84 Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Tue, 3 Mar 2009 13:30:33 +0100
Subject: Fixes: Small optimization in QGraphicsItem::clipPath().
RevBy: Andreas
Details: Use QPainterPath::addRect() rather than addPolygon() and
closeSubPath().
---
src/gui/graphicsview/qgraphicsitem.cpp | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 8b37648..fa77fd9 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -3259,8 +3259,8 @@ bool QGraphicsItem::collidesWithPath(const QPainterPath &path, Qt::ItemSelection
return false;
}
- QRectF rectA = _q_adjustedRect(boundingRect());
- QRectF rectB = _q_adjustedRect(path.controlPointRect());
+ const QRectF rectA = _q_adjustedRect(boundingRect());
+ const QRectF rectB = _q_adjustedRect(path.controlPointRect());
if (!rectA.intersects(rectB)) {
// This we can determine efficiently. If the two rects neither
// intersect nor contain eachother, then the two items do not collide.
@@ -3269,12 +3269,11 @@ bool QGraphicsItem::collidesWithPath(const QPainterPath &path, Qt::ItemSelection
// For further testing, we need this item's shape or bounding rect.
QPainterPath thisShape;
- if (mode == Qt::IntersectsItemShape || mode == Qt::ContainsItemShape) {
+ if (mode == Qt::IntersectsItemShape || mode == Qt::ContainsItemShape)
thisShape = (isClipped() && !d_ptr->localCollisionHack) ? clipPath() : shape();
- } else {
- thisShape.addPolygon(_q_adjustedRect(boundingRect()));
- thisShape.closeSubpath();
- }
+ else
+ thisShape.addRect(rectA);
+
if (thisShape == QPainterPath()) {
// Empty shape? No collision.
return false;
--
cgit v0.12
From d74f1a91b05b943c1a8ae7847de6ee50b2093b89 Mon Sep 17 00:00:00 2001
From: Alexis Menard
Date: Tue, 3 Mar 2009 17:08:30 +0100
Subject: Fixes: Be a bit more smarter when calling setGeometry from
itemChange
RevBy: bnilsen
AutoTest: Bench
Details : if we come from setPosHelper (so itemChange) we don't need to do all the stuff regarding the size in setGeometry because the size doesn't change.
I remove two calls to fullUpdateHelper and update() because prepareGeometryChange already call updateHelper and setPosHelper call fullUpdaterHelper too so we don't need to call them inside setGeometry.
We can only call prepareGeometryChange only if we don't come from setPos.
---
src/gui/graphicsview/qgraphicsitem.cpp | 6 +--
src/gui/graphicsview/qgraphicsitem_p.h | 2 +-
src/gui/graphicsview/qgraphicswidget.cpp | 58 ++++++++++++---------
src/gui/graphicsview/qgraphicswidget_p.h | 2 +
.../benchmarks/qgraphicswidget/qgraphicswidget.pro | 6 +++
.../qgraphicswidget/tst_qgraphicswidget.cpp | 60 ++++++++++++++++++++++
6 files changed, 105 insertions(+), 29 deletions(-)
create mode 100644 tests/benchmarks/qgraphicswidget/qgraphicswidget.pro
create mode 100644 tests/benchmarks/qgraphicswidget/tst_qgraphicswidget.cpp
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index fa77fd9..443cc8c 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -2352,7 +2352,7 @@ QPointF QGraphicsItem::scenePos() const
the item is also updated; otherwise it is not updated before and after the
change.
*/
-void QGraphicsItemPrivate::setPosHelper(const QPointF &pos, bool update)
+void QGraphicsItemPrivate::setPosHelper(const QPointF &pos)
{
Q_Q(QGraphicsItem);
if (this->pos == pos)
@@ -2364,7 +2364,7 @@ void QGraphicsItemPrivate::setPosHelper(const QPointF &pos, bool update)
return;
// Update and repositition.
- if (scene && update) {
+ if (scene) {
fullUpdateHelper(true);
q->prepareGeometryChange();
}
@@ -2387,7 +2387,7 @@ void QGraphicsItemPrivate::setPosHelper(const QPointF &pos, bool update)
*/
void QGraphicsItem::setPos(const QPointF &pos)
{
- d_ptr->setPosHelper(pos, /* update = */ true);
+ d_ptr->setPosHelper(pos);
}
/*!
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index 98fe6ed..7deae52 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -158,7 +158,7 @@ public:
virtual QVariant inputMethodQueryHelper(Qt::InputMethodQuery query) const;
static bool movableAncestorIsSelected(const QGraphicsItem *item);
- void setPosHelper(const QPointF &pos, bool update);
+ void setPosHelper(const QPointF &pos);
void setVisibleHelper(bool newVisible, bool explicitly, bool update = true);
void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true);
void updateHelper(const QRectF &rect = QRectF(), bool force = false);
diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp
index 64ec0e7..7f02fb9 100644
--- a/src/gui/graphicsview/qgraphicswidget.cpp
+++ b/src/gui/graphicsview/qgraphicswidget.cpp
@@ -366,32 +366,33 @@ void QGraphicsWidget::resize(const QSizeF &size)
void QGraphicsWidget::setGeometry(const QRectF &rect)
{
QGraphicsWidgetPrivate *wd = QGraphicsWidget::d_func();
- const QGraphicsLayoutItemPrivate *d = QGraphicsLayoutItem::d_ptr;
- setAttribute(Qt::WA_Resized);
- QRectF newGeom = rect;
- newGeom.setSize(rect.size().expandedTo(effectiveSizeHint(Qt::MinimumSize))
- .boundedTo(effectiveSizeHint(Qt::MaximumSize)));
- if (newGeom == d->geom)
- return;
-
- // Update and prepare to change the geometry (remove from index).
- if (wd->scene) {
- if (rect.topLeft() != d->geom.topLeft())
- wd->fullUpdateHelper(true);
- else
- update();
- }
- prepareGeometryChange();
-
- // setPos triggers ItemPositionChange, which can adjust position
+ QGraphicsLayoutItemPrivate *d = QGraphicsLayoutItem::d_ptr;
+ QRectF newGeom;
QPointF oldPos = d->geom.topLeft();
- wd->inSetGeometry = 1;
- wd->setPosHelper(newGeom.topLeft(), /* update = */ false);
- wd->inSetGeometry = 0;
- newGeom.moveTopLeft(pos());
-
- if (newGeom == d->geom)
- return;
+ if (!wd->inSetPos) {
+ setAttribute(Qt::WA_Resized);
+ newGeom = rect;
+ newGeom.setSize(rect.size().expandedTo(effectiveSizeHint(Qt::MinimumSize))
+ .boundedTo(effectiveSizeHint(Qt::MaximumSize)));
+ if (newGeom == d->geom)
+ return;
+
+ // setPos triggers ItemPositionChange, which can adjust position
+ wd->inSetGeometry = 1;
+ wd->setPosHelper(newGeom.topLeft());
+ wd->inSetGeometry = 0;
+ newGeom.moveTopLeft(pos());
+
+ if (newGeom == d->geom)
+ return;
+
+ // Update and prepare to change the geometry (remove from index) if the size has changed.
+ if (wd->scene) {
+ if (rect.topLeft() == d->geom.topLeft()) {
+ prepareGeometryChange();
+ }
+ }
+ }
// Update the layout item geometry
bool moved = oldPos != pos();
@@ -401,6 +402,11 @@ void QGraphicsWidget::setGeometry(const QRectF &rect)
event.setOldPos(oldPos);
event.setNewPos(pos());
QApplication::sendEvent(this, &event);
+ if (wd->inSetPos) {
+ //set the new pos
+ d->geom.moveTopLeft(pos());
+ return;
+ }
}
QSizeF oldSize = size();
QGraphicsLayoutItem::setGeometry(newGeom);
@@ -1016,9 +1022,11 @@ QVariant QGraphicsWidget::itemChange(GraphicsItemChange change, const QVariant &
break;
case ItemPositionHasChanged:
if (!d->inSetGeometry) {
+ d->inSetPos = 1;
// Ensure setGeometry is called (avoid recursion when setPos is
// called from within setGeometry).
setGeometry(QRectF(pos(), size()));
+ d->inSetPos = 0 ;
}
break;
case ItemParentChange: {
diff --git a/src/gui/graphicsview/qgraphicswidget_p.h b/src/gui/graphicsview/qgraphicswidget_p.h
index 455a129..53eaa31 100644
--- a/src/gui/graphicsview/qgraphicswidget_p.h
+++ b/src/gui/graphicsview/qgraphicswidget_p.h
@@ -86,6 +86,7 @@ public:
inheritedFontResolveMask(0),
inSetGeometry(0),
polished(0),
+ inSetPos(0),
focusPolicy(Qt::NoFocus),
focusNext(0),
focusPrev(0),
@@ -195,6 +196,7 @@ public:
quint32 attributes : 10;
quint32 inSetGeometry : 1;
quint32 polished: 1;
+ quint32 inSetPos : 1;
// Focus
Qt::FocusPolicy focusPolicy;
diff --git a/tests/benchmarks/qgraphicswidget/qgraphicswidget.pro b/tests/benchmarks/qgraphicswidget/qgraphicswidget.pro
new file mode 100644
index 0000000..f1ec54e
--- /dev/null
+++ b/tests/benchmarks/qgraphicswidget/qgraphicswidget.pro
@@ -0,0 +1,6 @@
+load(qttest_p4)
+TEMPLATE = app
+TARGET = tst_qgraphicswidget
+TEMPLATE = app
+# Input
+SOURCES += tst_qgraphicswidget.cpp
diff --git a/tests/benchmarks/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/benchmarks/qgraphicswidget/tst_qgraphicswidget.cpp
new file mode 100644
index 0000000..97837e2
--- /dev/null
+++ b/tests/benchmarks/qgraphicswidget/tst_qgraphicswidget.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+****************************************************************************/
+
+#include
+#include
+#include
+#include
+#include
+//TESTED_FILES=
+
+class tst_QGraphicsWidget : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QGraphicsWidget();
+ virtual ~tst_QGraphicsWidget();
+
+public slots:
+ void init();
+ void cleanup();
+
+private slots:
+ void move();
+};
+
+tst_QGraphicsWidget::tst_QGraphicsWidget()
+{
+}
+
+tst_QGraphicsWidget::~tst_QGraphicsWidget()
+{
+}
+
+void tst_QGraphicsWidget::init()
+{
+}
+
+void tst_QGraphicsWidget::cleanup()
+{
+}
+
+void tst_QGraphicsWidget::move()
+{
+ QGraphicsScene scene;
+ QGraphicsWidget *widget = new QGraphicsWidget();
+ scene.addItem(widget);
+ QGraphicsView view(&scene);
+ view.show();
+ QBENCHMARK {
+ widget->setPos(qrand(),qrand());
+ }
+}
+
+QTEST_MAIN(tst_QGraphicsWidget)
+#include "tst_qgraphicswidget.moc"
--
cgit v0.12
From 0985805ab3c7de5b15c115a98afb15944b6d93b9 Mon Sep 17 00:00:00 2001
From: Alexis Menard
Date: Mon, 9 Mar 2009 14:33:02 +0100
Subject: Fixes: Don't fill the pixmap because we will copy the cache into
it.
RevBy: bnilsen
AutoTest: All pass + plasma ok
---
src/gui/graphicsview/qgraphicsscene.cpp | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index b509507..8a67d24 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -4736,11 +4736,9 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
if (newCacheIndent != deviceData->cacheIndent || deviceRect.size() != pix.size()) {
QPoint diff = newCacheIndent - deviceData->cacheIndent;
QPixmap newPix(deviceRect.size());
- // ### Investigate removing this fill (test with Plasma and
- // graphicssystem raster).
- newPix.fill(Qt::transparent);
if (!pix.isNull()) {
QPainter newPixPainter(&newPix);
+ newPixPainter.setCompositionMode(QPainter::CompositionMode_Source);
newPixPainter.drawPixmap(-diff, pix);
newPixPainter.end();
}
--
cgit v0.12
From 4556bcbd40c8feb7185aae7da5f0686f12d87565 Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Wed, 11 Mar 2009 17:24:41 +0100
Subject: Fixes: Optimization: Cache QGraphicsItem::clipPath().
RevBy: Alexis
AutoTest: Still pass
Details: No-brainer.
---
src/gui/graphicsview/qgraphicsitem.cpp | 46 ++++++++++++++++++++++++++++------
src/gui/graphicsview/qgraphicsitem_p.h | 14 +++++++++++
2 files changed, 53 insertions(+), 7 deletions(-)
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 443cc8c..5b997f4 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -631,6 +631,7 @@ void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag ch
case QGraphicsItem::ItemClipsChildrenToShape:
flag = AncestorClipsChildren;
enabled = flags & QGraphicsItem::ItemClipsChildrenToShape;
+ invalidateCachedClipPathRecursively(/*childrenOnly=*/true);
break;
case QGraphicsItem::ItemIgnoresTransformations:
flag = AncestorIgnoresTransformations;
@@ -1270,6 +1271,9 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
d_ptr->updateAncestorFlag(ItemClipsChildrenToShape);
}
+ if ((flags & ItemClipsToShape) != (oldFlags & ItemClipsToShape))
+ d_ptr->invalidateCachedClipPath();
+
if ((flags & ItemIgnoresTransformations) != (oldFlags & ItemIgnoresTransformations)) {
// Item children clipping changes. Propagate the ancestor flag to
// all children.
@@ -3136,10 +3140,15 @@ bool QGraphicsItem::isClipped() const
QPainterPath QGraphicsItem::clipPath() const
{
Q_D(const QGraphicsItem);
- QPainterPath clip;
- if (!isClipped())
- return clip;
+ if (!d->dirtyClipPath)
+ return d->cachedClipPath;
+
+ if (!isClipped()) {
+ d_ptr->setCachedClipPath(QPainterPath());
+ return d->cachedClipPath;
+ }
+ QPainterPath clip;
// Start with the item's bounding rect.
clip.addRect(boundingRect());
@@ -3150,15 +3159,27 @@ QPainterPath QGraphicsItem::clipPath() const
// Intersect any in-between clips starting at the top and moving downwards.
while ((parent = parent->d_ptr->parent)) {
if (parent->d_ptr->flags & ItemClipsChildrenToShape) {
- // Map clip to the current parent and intersect with its shape.
- clip = (lastParent->itemTransform(parent).map(clip)).intersected(parent->shape());
- if (clip.isEmpty())
+ // Map clip to the current parent and intersect with its shape/clipPath
+ clip = lastParent->itemTransform(parent).map(clip);
+ if (!parent->d_ptr->dirtyClipPath) {
+ clip = clip.intersected(parent->d_ptr->cachedClipPath);
+ if (!(parent->d_ptr->flags & ItemClipsToShape))
+ clip = clip.intersected(parent->shape());
+ } else {
+ clip = clip.intersected(parent->shape());
+ }
+
+ if (clip.isEmpty()) {
+ d_ptr->setCachedClipPath(clip);
return clip;
+ }
lastParent = parent;
}
- if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren))
+ if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
+ || !parent->d_ptr->dirtyClipPath) {
break;
+ }
}
if (lastParent != this) {
@@ -3171,6 +3192,7 @@ QPainterPath QGraphicsItem::clipPath() const
if (d->flags & ItemClipsToShape)
clip = clip.intersected(shape());
+ d_ptr->setCachedClipPath(clip);
return clip;
}
@@ -3726,6 +3748,15 @@ void QGraphicsItemPrivate::removeExtraItemCache()
unsetExtra(ExtraCacheData);
}
+void QGraphicsItemPrivate::invalidateCachedClipPathRecursively(bool childrenOnly)
+{
+ if (!childrenOnly)
+ invalidateCachedClipPath();
+ // ### Return if this item doesn't clip its children?
+ for (int i = 0; i < children.size(); ++i)
+ children.at(i)->d_ptr->invalidateCachedClipPathRecursively(false);
+}
+
/*!
\internal
@@ -5505,6 +5536,7 @@ void QGraphicsItem::prepareGeometryChange()
QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func();
scenePrivate->removeFromIndex(this);
+ d_ptr->invalidateCachedClipPathRecursively();
}
}
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index 7deae52..1e2c09b 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -138,6 +138,7 @@ public:
dirty(0),
dirtyChildren(0),
localCollisionHack(0),
+ dirtyClipPath(1),
globalStackingOrder(-1),
sceneTransformIndex(-1),
q_ptr(0)
@@ -234,6 +235,18 @@ public:
QGraphicsItemCache *extraItemCache() const;
void removeExtraItemCache();
+ inline void setCachedClipPath(const QPainterPath &path)
+ {
+ cachedClipPath = path;
+ dirtyClipPath = 0;
+ }
+
+ inline void invalidateCachedClipPath()
+ { dirtyClipPath = 1; }
+
+ void invalidateCachedClipPathRecursively(bool childrenOnly = false);
+
+ QPainterPath cachedClipPath;
QPointF pos;
qreal z;
QGraphicsScene *scene;
@@ -268,6 +281,7 @@ public:
quint32 dirty : 1;
quint32 dirtyChildren : 1;
quint32 localCollisionHack : 1;
+ quint32 dirtyClipPath : 1;
// Optional stacking order
int globalStackingOrder;
--
cgit v0.12
From f4547b98b52bfc95fb0c14ec58df204cfcec0db2 Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Fri, 3 Apr 2009 14:19:12 +0200
Subject: Fixes: Cleanup/Optimize QGraphicsView::findItems.
RevBy: Alexis
AutoTest: Still pass
Details: findItems() does almost exactly the same as
QGraphicsView::items, the only difference is that it checks
whether we are about to redraw all items. Next step
is to optimize the items_helper functions.
The patch does also include a fix for
::items/childItems_helper(const QPainterPath ...); it didn't
take Qt::Intersects/ContainsItemBoundingRect into account
(in the same fashion as we do in the other helper functions).
---
src/gui/graphicsview/qgraphicsscene.cpp | 80 ++++++++++++++++-----
src/gui/graphicsview/qgraphicsview.cpp | 122 ++++++++------------------------
src/gui/graphicsview/qgraphicsview_p.h | 7 +-
3 files changed, 94 insertions(+), 115 deletions(-)
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 8a67d24..3db8e35 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -1487,21 +1487,46 @@ QList QGraphicsScenePrivate::items_helper(const QPainterPath &p
Qt::SortOrder order) const
{
QList items;
+ const QRectF pathRect = _q_adjustedRect(path.controlPointRect());
+
// The index returns a rough estimate of what items are inside the rect.
// Refine it by iterating through all returned items.
- foreach (QGraphicsItem *item, estimateItemsInRect(_q_adjustedRect(path.controlPointRect()))) {
+ foreach (QGraphicsItem *item, estimateItemsInRect(pathRect)) {
// Find the item's scene transform in a clever way.
QTransform x = item->sceneTransform();
- bool ok;
- QTransform xinv = x.inverted(&ok);
- if (ok) {
- QPainterPath mappedPath = xinv.map(path);
- if (itemCollidesWithPath(item, mappedPath, mode)) {
+ bool keep = false;
+
+ // ### _q_adjustedRect is only needed because QRectF::intersects,
+ // QRectF::contains and QTransform::map() and friends don't work with
+ // flat rectangles.
+ QRectF br = _q_adjustedRect(item->boundingRect());
+ if (mode >= Qt::ContainsItemBoundingRect) {
+ // Path contains/intersects item's bounding rect
+ if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(x.mapRect(br)))
+ || (mode == Qt::ContainsItemBoundingRect && path.contains(x.mapRect(br)))) {
items << item;
- if (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)
- childItems_helper(&items, item, mappedPath, mode);
+ keep = true;
+ }
+ } else {
+ // Path contains/intersects item's shape
+ if (QRectF_intersects(pathRect, x.mapRect(br))) {
+ bool ok;
+ QTransform xinv = x.inverted(&ok);
+ if (ok) {
+ if (itemCollidesWithPath(item, xinv.map(path), mode)) {
+ items << item;
+ keep = true;
+ }
+ }
}
}
+
+ if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) {
+ bool ok;
+ QTransform xinv = x.inverted(&ok);
+ if (ok)
+ childItems_helper(&items, item, xinv.map(path), mode);
+ }
}
if (order != Qt::SortOrder(-1))
@@ -1629,29 +1654,46 @@ void QGraphicsScenePrivate::childItems_helper(QList *items,
Qt::ItemSelectionMode mode) const
{
bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape);
- QPainterPath intersectedPath = !parentClip ? path : path.intersected(parent->shape());
- if (intersectedPath.isEmpty())
+ QRectF pathRect = _q_adjustedRect(path.boundingRect());
+ QRectF r = !parentClip ? pathRect : pathRect.intersected(_q_adjustedRect(parent->boundingRect()));
+ if (r.isEmpty())
return;
QList &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())
+ continue;
// Skip invisible items.
if (!item->d_ptr->visible || qFuzzyCompare(item->effectiveOpacity(), qreal(0.0)))
continue;
- QTransform x = item->sceneTransform();
-
- bool ok;
- QTransform xinv = x.inverted(&ok);
- if (ok) {
- QPainterPath mappedPath = xinv.map(path);
- if (itemCollidesWithPath(item, mappedPath, mode)) {
+ // ### _q_adjustedRect is only needed because QRectF::intersects,
+ // QRectF::contains and QTransform::map() and friends don't work with
+ // flat rectangles.
+ QRectF br = _q_adjustedRect(item->boundingRect());
+ bool keep = false;
+ if (mode >= Qt::ContainsItemBoundingRect) {
+ // Polygon contains/intersects item's bounding rect
+ if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br)))
+ || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) {
items->append(item);
- if (!item->d_ptr->children.isEmpty())
- childItems_helper(items, item, mappedPath, mode);
+ keep = true;
}
+ } else {
+ // Path contains/intersects item's shape
+ if (QRectF_intersects(pathRect, item->mapRectToParent(br))) {
+ if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) {
+ items->append(item);
+ keep = true;
+ }
+ }
+ }
+
+ if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) {
+ // Recurse into children that clip children.
+ childItems_helper(items, item, item->mapFromParent(path), mode);
}
}
}
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index f88918f..c421417 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -1029,103 +1029,40 @@ void QGraphicsViewPrivate::freeStyleOptionsArray(QStyleOptionGraphicsItem *array
extern QPainterPath qt_regionToPath(const QRegion ®ion);
-QList QGraphicsViewPrivate::findItems(const QRegion &exposedRegion,
- const QTransform &worldTransform,
- bool *allItems) const
+QList QGraphicsViewPrivate::findItems(const QRegion &exposedRegion, bool *allItems) const
{
Q_Q(const QGraphicsView);
- QList itemList;
- QSet tmp;
- bool simpleTransform = worldTransform.type() <= QTransform::TxScale;
-
- QPainterPath path = qt_regionToPath(exposedRegion);
- *allItems = path.contains(q->mapFromScene(scene->d_func()->growingItemsBoundingRect).boundingRect());
- QList exposedRects;
- QList exposedPolys;
-
- // Transform the exposed viewport rects to scene rects or polygons
- foreach (const QRect &rect, exposedRegion.rects()) {
- QPolygonF exposedPoly = q->mapToScene(rect.adjusted(-1, -1, 1, 1));
- QRectF exposedRect = exposedPoly.boundingRect();
- if (!simpleTransform)
- exposedPolys << exposedPoly;
- exposedRects << exposedRect;
- }
-
- // Find which items need to be drawn.
- if (*allItems) {
+ const QPainterPath exposedPath(qt_regionToPath(exposedRegion));
+ const QPainterPath exposedScenePath(q->mapToScene(exposedPath));
+
+ if (exposedScenePath.contains(scene->d_func()->growingItemsBoundingRect)) {
+ Q_ASSERT(allItems);
+ *allItems = true;
+
// All items are guaranteed within the exposed region, don't bother using the index.
- foreach (QGraphicsItem *item, scene->items()) {
+ QList itemList(scene->items());
+ int i = 0;
+ while (i < itemList.size()) {
// But we only want to include items that are visible
- if (item->isVisible())
- itemList << item;
- }
- } else if (simpleTransform) {
- // Simple rect lookups will do.
- if (exposedRects.size() > 1) {
- foreach (const QRectF &rect, exposedRects) {
- foreach (QGraphicsItem *item, scene->d_func()->items_helper(rect, Qt::IntersectsItemBoundingRect, Qt::SortOrder(-1) /* don't sort */)) {
- if (!tmp.contains(item)) {
- tmp << item;
- itemList << item;
- }
- }
- }
- } else {
- itemList += scene->d_func()->items_helper(exposedRects[0], Qt::IntersectsItemBoundingRect, Qt::SortOrder(-1) /* don't sort */);
- }
- } else {
- // Polygon lookup is necessary.
- if (exposedRects.size() > 1) {
- foreach (const QPolygonF &poly, exposedPolys) {
- foreach (QGraphicsItem *item, scene->d_func()->items_helper(poly, Qt::IntersectsItemBoundingRect, Qt::SortOrder(-1) /* don't sort */)) {
- if (!tmp.contains(item)) {
- tmp << item;
- itemList << item;
- }
- }
- }
- } else {
- itemList += scene->d_func()->items_helper(exposedPolys[0], Qt::IntersectsItemBoundingRect, Qt::SortOrder(-1) /* don't sort */);
+ if (!itemList.at(i)->isVisible())
+ itemList.removeAt(i);
+ else
+ ++i;
}
- }
- // Check for items that ignore inherited transformations, and add them if
- // necessary.
- QRectF untr = scene->d_func()->largestUntransformableItem;
- if (!*allItems && !untr.isNull()) {
- // Map the largest untransformable item subtree boundingrect from view
- // to scene coordinates, and use this to expand all exposed rects in
- // search for untransformable items.
- QRectF ltri = matrix.inverted().mapRect(untr);
- ltri.adjust(-untr.width(), -untr.height(), untr.width(), untr.height());
-
- foreach (const QRect &rect, exposedRegion.rects()) {
- QRectF exposed = q->mapToScene(rect.adjusted(-1, -1, 1, 1)).boundingRect();
- exposed.adjust(-ltri.width(), -ltri.height(), ltri.width(), ltri.height());
-
- foreach (QGraphicsItem *item, scene->d_func()->estimateItemsInRect(exposed)) {
- if (item->d_ptr->itemIsUntransformable()) {
- if (!tmp.contains(item)) {
- QPainterPath rectPath;
- rectPath.addRect(rect);
- QPainterPath path = item->deviceTransform(q->viewportTransform()).inverted().map(rectPath);
- if (item->collidesWithPath(path, Qt::IntersectsItemBoundingRect)) {
- itemList << item;
- tmp << item;
- }
- }
- }
- }
- }
+ // Sort the items.
+ QGraphicsScenePrivate::sortItems(&itemList, Qt::DescendingOrder, scene->d_func()->sortCacheEnabled);
+ return itemList;
}
- tmp.clear();
- // Sort the items.
- QGraphicsScenePrivate::sortItems(&itemList, Qt::DescendingOrder,
- scene->d_func()->sortCacheEnabled);
+ if (scene->d_func()->largestUntransformableItem.isNull()) {
+ return scene->d_func()->items_helper(exposedScenePath,
+ Qt::IntersectsItemBoundingRect,
+ Qt::DescendingOrder);
+ }
- return itemList;
+ // NB! Path must be in viewport coordinates.
+ return itemsInArea(exposedPath, Qt::IntersectsItemBoundingRect, Qt::DescendingOrder);
}
void QGraphicsViewPrivate::generateStyleOptions(const QList &itemList,
@@ -2228,7 +2165,8 @@ QList QGraphicsView::items() const
certainly room for improvement.
*/
QList QGraphicsViewPrivate::itemsInArea(const QPainterPath &path,
- Qt::ItemSelectionMode mode) const
+ Qt::ItemSelectionMode mode,
+ Qt::SortOrder order) const
{
Q_Q(const QGraphicsView);
@@ -2278,8 +2216,8 @@ QList QGraphicsViewPrivate::itemsInArea(const QPainterPath &pat
}
// ### Insertion sort would be faster.
- QGraphicsScenePrivate::sortItems(&result, Qt::AscendingOrder,
- scene->d_func()->sortCacheEnabled);
+ if (order != Qt::SortOrder(-1))
+ QGraphicsScenePrivate::sortItems(&result, order, scene->d_func()->sortCacheEnabled);
return result;
}
@@ -3485,7 +3423,7 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
// Find all exposed items
bool allItems = false;
- QList itemList = d->findItems(exposedRegion, viewTransform, &allItems);
+ QList itemList = d->findItems(exposedRegion, &allItems);
#ifdef QGRAPHICSVIEW_DEBUG
int exposedTime = stopWatch.elapsed();
diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h
index 2109673..a76279e 100644
--- a/src/gui/graphicsview/qgraphicsview_p.h
+++ b/src/gui/graphicsview/qgraphicsview_p.h
@@ -85,7 +85,8 @@ public:
qint64 verticalScroll() const;
QList itemsInArea(const QPainterPath &path,
- Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const;
+ Qt::ItemSelectionMode mode = Qt::IntersectsItemShape,
+ Qt::SortOrder = Qt::AscendingOrder) const;
QPointF mousePressItemPoint;
QPointF mousePressScenePoint;
@@ -172,9 +173,7 @@ public:
void updateRegion(const QRegion ®ion);
bool updateSceneSlotReimplementedChecked;
- QList findItems(const QRegion &exposedRegion,
- const QTransform &worldTransform,
- bool *allItems) const;
+ QList findItems(const QRegion &exposedRegion, bool *allItems) const;
void generateStyleOptions(const QList &itemList,
QGraphicsItem **itemArray,
--
cgit v0.12
From 4020327503eaefae42da4bd6e71125b6972ac97f Mon Sep 17 00:00:00 2001
From: Andreas Aardal Hanssen
Date: Fri, 3 Apr 2009 14:43:11 +0200
Subject: Add a cut-off for simple rectangle lookups.
Make sure we use the rect-variation of QGraphicsScene's item lookup
functions if the view has a simple transform and a simple expose
region.
Reviewed-by: Bjoern Erik Nilsen
---
src/gui/graphicsview/qgraphicsview.cpp | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index c421417..9191fc5 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -1056,6 +1056,11 @@ QList QGraphicsViewPrivate::findItems(const QRegion &exposedReg
}
if (scene->d_func()->largestUntransformableItem.isNull()) {
+ if (exposedRegion.numRects() == 1 && matrix.type() <= QTransform::TxScale) {
+ return scene->d_func()->items_helper(exposedScenePath.controlPointRect(),
+ Qt::IntersectsItemBoundingRect,
+ Qt::DescendingOrder);
+ }
return scene->d_func()->items_helper(exposedScenePath,
Qt::IntersectsItemBoundingRect,
Qt::DescendingOrder);
--
cgit v0.12
From 4d019e66fb62d6f25627144539abd7f59413abee Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Tue, 17 Mar 2009 11:42:07 +0100
Subject: Fixes: Only use the parent's cached clip path if it is clipped.
RevBy: TrustMe
Details: ...otherwise it'll be empty and too much will be clipped away.
---
src/gui/graphicsview/qgraphicsitem.cpp | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 5b997f4..a3a12e7 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -3157,11 +3157,12 @@ QPainterPath QGraphicsItem::clipPath() const
const QGraphicsItem *lastParent = this;
// Intersect any in-between clips starting at the top and moving downwards.
+ bool foundValidClipPath = false;
while ((parent = parent->d_ptr->parent)) {
if (parent->d_ptr->flags & ItemClipsChildrenToShape) {
// Map clip to the current parent and intersect with its shape/clipPath
clip = lastParent->itemTransform(parent).map(clip);
- if (!parent->d_ptr->dirtyClipPath) {
+ if ((foundValidClipPath = !parent->d_ptr->dirtyClipPath && parent->isClipped())) {
clip = clip.intersected(parent->d_ptr->cachedClipPath);
if (!(parent->d_ptr->flags & ItemClipsToShape))
clip = clip.intersected(parent->shape());
@@ -3177,7 +3178,7 @@ QPainterPath QGraphicsItem::clipPath() const
}
if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
- || !parent->d_ptr->dirtyClipPath) {
+ || foundValidClipPath) {
break;
}
}
--
cgit v0.12
From bd4b177e051852f0fb94df9c0ee2e512478e0d38 Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Wed, 18 Mar 2009 13:27:16 +0100
Subject: Fixes: Get rid of lots of calls to qFuzzyCompare.
RevBy: Olivier
AutoTest: Still pass.
Details: Items usually don't have effective opacity, i.e. it is 1.0, so
don't bother doing fuzzy compare if that's the case.
---
src/gui/graphicsview/qgraphicsitem_p.h | 6 ++++++
src/gui/graphicsview/qgraphicsscene.cpp | 6 +++---
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index 1e2c09b..df07b87 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -246,6 +246,12 @@ public:
void invalidateCachedClipPathRecursively(bool childrenOnly = false);
+ inline bool isInvisible() const
+ {
+ return !visible || (hasEffectiveOpacity
+ && qFuzzyCompare(q_func()->effectiveOpacity() + 1.0, qreal(1.0)));
+ }
+
QPainterPath cachedClipPath;
QPointF pos;
qreal z;
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 3db8e35..1422184 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -1552,7 +1552,7 @@ void QGraphicsScenePrivate::childItems_helper(QList *items,
continue;
// Skip invisible items and all their children.
- if (!item->d_ptr->visible || qFuzzyCompare(item->effectiveOpacity(), qreal(0.0)))
+ if (item->d_ptr->isInvisible())
continue;
// ### _q_adjustedRect is only needed because QRectF::intersects,
@@ -1612,7 +1612,7 @@ void QGraphicsScenePrivate::childItems_helper(QList *items,
continue;
// Skip invisible items.
- if (!item->d_ptr->visible || qFuzzyCompare(item->effectiveOpacity() + 1, qreal(1.0)))
+ if (item->d_ptr->isInvisible())
continue;
// ### _q_adjustedRect is only needed because QRectF::intersects,
@@ -1666,7 +1666,7 @@ void QGraphicsScenePrivate::childItems_helper(QList *items,
continue;
// Skip invisible items.
- if (!item->d_ptr->visible || qFuzzyCompare(item->effectiveOpacity(), qreal(0.0)))
+ if (item->d_ptr->isInvisible())
continue;
// ### _q_adjustedRect is only needed because QRectF::intersects,
--
cgit v0.12
From 5910dbe6e7a024301d431102703f9abe323ebd13 Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Thu, 19 Mar 2009 15:31:56 +0100
Subject: Fixes: Compile on funky scratchbox ARM compiler.
---
src/gui/graphicsview/qgraphicsitem_p.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index df07b87..98e7c13 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -249,7 +249,7 @@ public:
inline bool isInvisible() const
{
return !visible || (hasEffectiveOpacity
- && qFuzzyCompare(q_func()->effectiveOpacity() + 1.0, qreal(1.0)));
+ && qFuzzyCompare(q_func()->effectiveOpacity() + 1, qreal(1.0)));
}
QPainterPath cachedClipPath;
--
cgit v0.12
From c1909321a486621ef196dd4bb3cf354406d86d46 Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Fri, 20 Mar 2009 18:06:05 +0100
Subject: Fixes: Clever invalidating of the cached clip path.
RevBy: Andreas
AutoTest: still pass
Details: Adds emptyClipPath bit, a cut-off to test if the item
has an empty clip path (i.e., is clipped away). Also adds
code for invalidating the cache from inside setPos().
---
src/gui/graphicsview/qgraphicsitem.cpp | 124 ++++++++++++++++++++++++++++++---
src/gui/graphicsview/qgraphicsitem_p.h | 18 ++++-
2 files changed, 129 insertions(+), 13 deletions(-)
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index a3a12e7..badc41e 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -2368,15 +2368,18 @@ void QGraphicsItemPrivate::setPosHelper(const QPointF &pos)
return;
// Update and repositition.
+ inSetPosHelper = 1;
if (scene) {
fullUpdateHelper(true);
q->prepareGeometryChange();
}
this->pos = newPos;
invalidateSceneTransformCache();
+ updateCachedClipPathFromSetPosHelper();
// Send post-notification.
q->itemChange(QGraphicsItem::ItemPositionHasChanged, newPos);
+ inSetPosHelper = 0;
}
/*!
@@ -3141,7 +3144,7 @@ QPainterPath QGraphicsItem::clipPath() const
{
Q_D(const QGraphicsItem);
if (!d->dirtyClipPath)
- return d->cachedClipPath;
+ return d->emptyClipPath ? QPainterPath() : d->cachedClipPath;
if (!isClipped()) {
d_ptr->setCachedClipPath(QPainterPath());
@@ -3163,6 +3166,13 @@ QPainterPath QGraphicsItem::clipPath() const
// Map clip to the current parent and intersect with its shape/clipPath
clip = lastParent->itemTransform(parent).map(clip);
if ((foundValidClipPath = !parent->d_ptr->dirtyClipPath && parent->isClipped())) {
+ if (parent->d_ptr->emptyClipPath) {
+ if (d_ptr->flags & ItemClipsChildrenToShape)
+ d_ptr->setEmptyCachedClipPathRecursively();
+ else
+ d_ptr->setEmptyCachedClipPath();
+ return QPainterPath();
+ }
clip = clip.intersected(parent->d_ptr->cachedClipPath);
if (!(parent->d_ptr->flags & ItemClipsToShape))
clip = clip.intersected(parent->shape());
@@ -3171,7 +3181,10 @@ QPainterPath QGraphicsItem::clipPath() const
}
if (clip.isEmpty()) {
- d_ptr->setCachedClipPath(clip);
+ if (d_ptr->flags & ItemClipsChildrenToShape)
+ d_ptr->setEmptyCachedClipPathRecursively();
+ else
+ d_ptr->setEmptyCachedClipPath();
return clip;
}
lastParent = parent;
@@ -3749,13 +3762,95 @@ void QGraphicsItemPrivate::removeExtraItemCache()
unsetExtra(ExtraCacheData);
}
-void QGraphicsItemPrivate::invalidateCachedClipPathRecursively(bool childrenOnly)
+void QGraphicsItemPrivate::setEmptyCachedClipPathRecursively(const QRectF &emptyIfOutsideThisRect)
+{
+ setEmptyCachedClipPath();
+
+ const bool checkRect = !emptyIfOutsideThisRect.isNull()
+ && !(flags & QGraphicsItem::ItemClipsChildrenToShape);
+ for (int i = 0; i < children.size(); ++i) {
+ if (!checkRect) {
+ children.at(i)->d_ptr->setEmptyCachedClipPathRecursively();
+ continue;
+ }
+
+ QGraphicsItem *child = children.at(i);
+ const QRectF rect = child->mapRectFromParent(emptyIfOutsideThisRect);
+ if (rect.intersects(child->boundingRect()))
+ child->d_ptr->invalidateCachedClipPathRecursively(false, rect);
+ else
+ child->d_ptr->setEmptyCachedClipPathRecursively(rect);
+ }
+}
+
+void QGraphicsItemPrivate::invalidateCachedClipPathRecursively(bool childrenOnly, const QRectF &emptyIfOutsideThisRect)
{
if (!childrenOnly)
invalidateCachedClipPath();
- // ### Return if this item doesn't clip its children?
- for (int i = 0; i < children.size(); ++i)
- children.at(i)->d_ptr->invalidateCachedClipPathRecursively(false);
+
+ const bool checkRect = !emptyIfOutsideThisRect.isNull();
+ for (int i = 0; i < children.size(); ++i) {
+ if (!checkRect) {
+ children.at(i)->d_ptr->invalidateCachedClipPathRecursively(false);
+ continue;
+ }
+
+ QGraphicsItem *child = children.at(i);
+ const QRectF rect = child->mapRectFromParent(emptyIfOutsideThisRect);
+ if (rect.intersects(child->boundingRect()))
+ child->d_ptr->invalidateCachedClipPathRecursively(false, rect);
+ else
+ child->d_ptr->setEmptyCachedClipPathRecursively(rect);
+ }
+}
+
+void QGraphicsItemPrivate::updateCachedClipPathFromSetPosHelper()
+{
+ Q_ASSERT(inSetPosHelper);
+
+ if (!(ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren))
+ return; // Not clipped by any ancestor.
+
+ // Find closest clip ancestor.
+ QGraphicsItem *clipParent = parent;
+ while (clipParent && !(clipParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape))
+ clipParent = clipParent->d_ptr->parent;
+
+ Q_ASSERT(clipParent);
+ Q_Q(QGraphicsItem);
+
+ // From here everything is calculated in clip parent's coordinates.
+ const QTransform thisToParentTransform(q->itemTransform(clipParent));
+ const QRectF parentBoundingRect(clipParent->boundingRect());
+ const QRectF thisBoundingRect(thisToParentTransform.mapRect(q->boundingRect()));
+
+ if (!parentBoundingRect.intersects(thisBoundingRect)) {
+ // Item is moved outside the clip parent's bounding rect,
+ // i.e. it is fully clipped and the clip path is empty.
+ if (flags & QGraphicsItem::ItemClipsChildrenToShape)
+ setEmptyCachedClipPathRecursively();
+ else
+ setEmptyCachedClipPathRecursively(thisToParentTransform.inverted().mapRect(parentBoundingRect));
+ return;
+ }
+
+ const QPainterPath parentClip(clipParent->isClipped() ? clipParent->clipPath() : clipParent->shape());
+ if (parentClip.contains(thisBoundingRect))
+ return; // Item is inside the clip parent's shape. No update required.
+
+ const QRectF parentClipRect(parentClip.controlPointRect());
+ if (!parentClipRect.intersects(thisBoundingRect)) {
+ // Item is moved outside the clip parent's shape,
+ // i.e. it is fully clipped and the clip path is empty.
+ if (flags & QGraphicsItem::ItemClipsChildrenToShape)
+ setEmptyCachedClipPathRecursively();
+ else
+ setEmptyCachedClipPathRecursively(thisToParentTransform.inverted().mapRect(parentClipRect));
+ } else {
+ // Item is partially inside the clip parent's shape,
+ // i.e. the cached clip path must be invalidated.
+ invalidateCachedClipPathRecursively(false, thisToParentTransform.inverted().mapRect(parentClipRect));
+ }
}
/*!
@@ -5532,13 +5627,20 @@ void QGraphicsItem::removeFromIndex()
*/
void QGraphicsItem::prepareGeometryChange()
{
- if (d_ptr->scene) {
- d_ptr->updateHelper();
+ if (!d_ptr->scene)
+ return;
+
+ d_ptr->updateHelper();
+ QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func();
+ scenePrivate->removeFromIndex(this);
- QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func();
- scenePrivate->removeFromIndex(this);
+ if (d_ptr->inSetPosHelper)
+ return;
+
+ if (d_ptr->flags & ItemClipsChildrenToShape)
d_ptr->invalidateCachedClipPathRecursively();
- }
+ else
+ d_ptr->invalidateCachedClipPath();
}
/*!
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index 98e7c13..f5c3505 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -139,6 +139,8 @@ public:
dirtyChildren(0),
localCollisionHack(0),
dirtyClipPath(1),
+ emptyClipPath(0),
+ inSetPosHelper(0),
globalStackingOrder(-1),
sceneTransformIndex(-1),
q_ptr(0)
@@ -239,12 +241,22 @@ public:
{
cachedClipPath = path;
dirtyClipPath = 0;
+ emptyClipPath = 0;
}
+ inline void setEmptyCachedClipPath()
+ {
+ emptyClipPath = 1;
+ dirtyClipPath = 0;
+ }
+
+ void setEmptyCachedClipPathRecursively(const QRectF &emptyIfOutsideThisRect = QRectF());
+
inline void invalidateCachedClipPath()
- { dirtyClipPath = 1; }
+ { /*static int count = 0 ;qWarning("%i", ++count);*/ dirtyClipPath = 1; emptyClipPath = 0; }
- void invalidateCachedClipPathRecursively(bool childrenOnly = false);
+ void invalidateCachedClipPathRecursively(bool childrenOnly = false, const QRectF &emptyIfOutsideThisRect = QRectF());
+ void updateCachedClipPathFromSetPosHelper();
inline bool isInvisible() const
{
@@ -288,6 +300,8 @@ public:
quint32 dirtyChildren : 1;
quint32 localCollisionHack : 1;
quint32 dirtyClipPath : 1;
+ quint32 emptyClipPath : 1;
+ quint32 inSetPosHelper : 1;
// Optional stacking order
int globalStackingOrder;
--
cgit v0.12
From 95fa7a93bc840e0f49ee30e76abb2b4f8579c997 Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Mon, 23 Mar 2009 15:54:30 +0100
Subject: Fixes: Optimization: Clip path is empty if the bounding rect is
empty.
RevBy: TrustMe
---
src/gui/graphicsview/qgraphicsitem.cpp | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index badc41e..75b6cf1 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -3151,9 +3151,18 @@ QPainterPath QGraphicsItem::clipPath() const
return d->cachedClipPath;
}
+ const QRectF thisBoundingRect(boundingRect());
+ if (thisBoundingRect.isEmpty()) {
+ if (d_ptr->flags & ItemClipsChildrenToShape)
+ d_ptr->setEmptyCachedClipPathRecursively();
+ else
+ d_ptr->setEmptyCachedClipPath();
+ return QPainterPath();
+ }
+
QPainterPath clip;
// Start with the item's bounding rect.
- clip.addRect(boundingRect());
+ clip.addRect(thisBoundingRect);
if (d->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
const QGraphicsItem *parent = this;
--
cgit v0.12
From deccc867b244fbc52ca58e21623febbc27310b05 Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Mon, 23 Mar 2009 19:37:41 +0100
Subject: Fixes: Don't bother processing items that are clipped away.
RevBy: Andreas
---
src/gui/graphicsview/qgraphicsitem_p.h | 3 +
src/gui/graphicsview/qgraphicsscene.cpp | 116 ++++++++++++++++++--------------
2 files changed, 67 insertions(+), 52 deletions(-)
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index f5c3505..3e4c269 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -264,6 +264,9 @@ public:
&& qFuzzyCompare(q_func()->effectiveOpacity() + 1, qreal(1.0)));
}
+ inline bool isClippedAway() const
+ { return !dirtyClipPath && q_func()->isClipped() && (emptyClipPath || cachedClipPath.isEmpty()); }
+
QPainterPath cachedClipPath;
QPointF pos;
qreal z;
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 1422184..f32fe71 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -1539,12 +1539,14 @@ void QGraphicsScenePrivate::childItems_helper(QList *items,
const QRectF &rect,
Qt::ItemSelectionMode mode) const
{
- QPainterPath path;
bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape);
+ if (parentClip && parent->d_ptr->isClippedAway())
+ return;
QRectF r = !parentClip ? _q_adjustedRect(rect) : _q_adjustedRect(rect).intersected(_q_adjustedRect(parent->boundingRect()));
if (r.isEmpty())
return;
+ QPainterPath path;
QList &children = parent->d_ptr->children;
for (int i = 0; i < children.size(); ++i) {
QGraphicsItem *item = children.at(i);
@@ -1555,28 +1557,30 @@ void QGraphicsScenePrivate::childItems_helper(QList *items,
if (item->d_ptr->isInvisible())
continue;
- // ### _q_adjustedRect is only needed because QRectF::intersects,
- // QRectF::contains and QTransform::map() and friends don't work with
- // flat rectangles.
- QRectF br = _q_adjustedRect(item->boundingRect());
- QRectF mbr = item->mapRectToParent(br);
bool keep = false;
- if (mode >= Qt::ContainsItemBoundingRect) {
- // Rect intersects/contains item's bounding rect
- if ((mode == Qt::IntersectsItemBoundingRect && QRectF_intersects(rect, mbr))
- || (mode == Qt::ContainsItemBoundingRect && rect != mbr && rect.contains(br))) {
- items->append(item);
- keep = true;
- }
- } else {
- // Rect intersects/contains item's shape
- if (QRectF_intersects(rect, mbr)) {
- if (path == QPainterPath())
- path.addRect(rect);
- if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) {
+ if (!item->d_ptr->isClippedAway()) {
+ // ### _q_adjustedRect is only needed because QRectF::intersects,
+ // QRectF::contains and QTransform::map() and friends don't work with
+ // flat rectangles.
+ QRectF br = _q_adjustedRect(item->boundingRect());
+ QRectF mbr = item->mapRectToParent(br);
+ if (mode >= Qt::ContainsItemBoundingRect) {
+ // Rect intersects/contains item's bounding rect
+ if ((mode == Qt::IntersectsItemBoundingRect && QRectF_intersects(rect, mbr))
+ || (mode == Qt::ContainsItemBoundingRect && rect != mbr && rect.contains(br))) {
items->append(item);
keep = true;
}
+ } else {
+ // Rect intersects/contains item's shape
+ if (QRectF_intersects(rect, mbr)) {
+ if (path == QPainterPath())
+ path.addRect(rect);
+ if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) {
+ items->append(item);
+ keep = true;
+ }
+ }
}
}
@@ -1598,13 +1602,15 @@ void QGraphicsScenePrivate::childItems_helper(QList *items,
const QPolygonF &polygon,
Qt::ItemSelectionMode mode) const
{
- QPainterPath path;
bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape);
+ if (parentClip && parent->d_ptr->isClippedAway())
+ return;
QRectF polyRect = _q_adjustedRect(polygon.boundingRect());
QRectF r = !parentClip ? polyRect : polyRect.intersected(_q_adjustedRect(parent->boundingRect()));
if (r.isEmpty())
return;
+ QPainterPath path;
QList &children = parent->d_ptr->children;
for (int i = 0; i < children.size(); ++i) {
QGraphicsItem *item = children.at(i);
@@ -1615,29 +1621,31 @@ void QGraphicsScenePrivate::childItems_helper(QList *items,
if (item->d_ptr->isInvisible())
continue;
- // ### _q_adjustedRect is only needed because QRectF::intersects,
- // QRectF::contains and QTransform::map() and friends don't work with
- // flat rectangles.
- QRectF br = _q_adjustedRect(item->boundingRect());
bool keep = false;
- if (mode >= Qt::ContainsItemBoundingRect) {
- // Polygon contains/intersects item's bounding rect
- if (path == QPainterPath())
- path.addPolygon(polygon);
- if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br)))
- || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) {
- items->append(item);
- keep = true;
- }
- } else {
- // Polygon contains/intersects item's shape
- if (QRectF_intersects(polyRect, item->mapRectToParent(br))) {
+ if (!item->d_ptr->isClippedAway()) {
+ // ### _q_adjustedRect is only needed because QRectF::intersects,
+ // QRectF::contains and QTransform::map() and friends don't work with
+ // flat rectangles.
+ QRectF br = _q_adjustedRect(item->boundingRect());
+ if (mode >= Qt::ContainsItemBoundingRect) {
+ // Polygon contains/intersects item's bounding rect
if (path == QPainterPath())
path.addPolygon(polygon);
- if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) {
+ if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br)))
+ || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) {
items->append(item);
keep = true;
}
+ } else {
+ // Polygon contains/intersects item's shape
+ if (QRectF_intersects(polyRect, item->mapRectToParent(br))) {
+ if (path == QPainterPath())
+ path.addPolygon(polygon);
+ if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) {
+ items->append(item);
+ keep = true;
+ }
+ }
}
}
@@ -1654,6 +1662,8 @@ void QGraphicsScenePrivate::childItems_helper(QList *items,
Qt::ItemSelectionMode mode) const
{
bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape);
+ if (parentClip && parent->d_ptr->isClippedAway())
+ return;
QRectF pathRect = _q_adjustedRect(path.boundingRect());
QRectF r = !parentClip ? pathRect : pathRect.intersected(_q_adjustedRect(parent->boundingRect()));
if (r.isEmpty())
@@ -1669,25 +1679,27 @@ void QGraphicsScenePrivate::childItems_helper(QList *items,
if (item->d_ptr->isInvisible())
continue;
- // ### _q_adjustedRect is only needed because QRectF::intersects,
- // QRectF::contains and QTransform::map() and friends don't work with
- // flat rectangles.
- QRectF br = _q_adjustedRect(item->boundingRect());
bool keep = false;
- if (mode >= Qt::ContainsItemBoundingRect) {
- // Polygon contains/intersects item's bounding rect
- if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br)))
- || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) {
- items->append(item);
- keep = true;
- }
- } else {
- // Path contains/intersects item's shape
- if (QRectF_intersects(pathRect, item->mapRectToParent(br))) {
- if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) {
+ if (!item->d_ptr->isClippedAway()) {
+ // ### _q_adjustedRect is only needed because QRectF::intersects,
+ // QRectF::contains and QTransform::map() and friends don't work with
+ // flat rectangles.
+ QRectF br = _q_adjustedRect(item->boundingRect());
+ if (mode >= Qt::ContainsItemBoundingRect) {
+ // Polygon contains/intersects item's bounding rect
+ if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br)))
+ || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) {
items->append(item);
keep = true;
}
+ } else {
+ // Path contains/intersects item's shape
+ if (QRectF_intersects(pathRect, item->mapRectToParent(br))) {
+ if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) {
+ items->append(item);
+ keep = true;
+ }
+ }
}
}
--
cgit v0.12
From 0d959a6c402ea3a3a55d7076d453d4bdbf8dce8e Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Tue, 24 Mar 2009 15:50:26 +0100
Subject: Fixes: Discard update requests if possible.
AutoTest: Still pass.
Details: Update requests can be discarded if the item itself is
clipped away and the item clips all its children to shape.
This cut-off is extremely effective (and aggressive:))
---
src/gui/graphicsview/qgraphicsitem.cpp | 54 ++++++++++++++++++++++------------
src/gui/graphicsview/qgraphicsitem_p.h | 9 ++++--
src/gui/graphicsview/qgraphicsview.cpp | 2 ++
3 files changed, 44 insertions(+), 21 deletions(-)
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 75b6cf1..a5d6021 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -1063,7 +1063,7 @@ void QGraphicsItem::setParentItem(QGraphicsItem *parent)
qVariantSetValue(variant, this);
d_ptr->parent->itemChange(ItemChildAddedChange, variant);
if (!implicitUpdate)
- d_ptr->updateHelper();
+ d_ptr->updateHelper(QRectF(), false, true);
// Inherit ancestor flags from the new parent.
d_ptr->updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1));
@@ -1092,7 +1092,7 @@ void QGraphicsItem::setParentItem(QGraphicsItem *parent)
if (!d_ptr->enabled && !d_ptr->explicitlyDisabled)
d_ptr->setEnabledHelper(true, /* explicit = */ false);
- d_ptr->updateHelper();
+ d_ptr->updateHelper(QRectF(), false, true);
}
if (d_ptr->scene) {
@@ -1236,7 +1236,7 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
int geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations);
bool fullUpdate = (flags & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask);
if (fullUpdate)
- d_ptr->fullUpdateHelper();
+ d_ptr->fullUpdateHelper(false, true);
// Keep the old flags to compare the diff.
GraphicsItemFlags oldFlags = this->flags();
@@ -1281,7 +1281,7 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
}
// ### Why updateHelper?
- d_ptr->updateHelper();
+ d_ptr->updateHelper(QRectF(), false, true);
// Notify change.
itemChange(ItemFlagsHaveChanged, quint32(flags));
@@ -2369,13 +2369,13 @@ void QGraphicsItemPrivate::setPosHelper(const QPointF &pos)
// Update and repositition.
inSetPosHelper = 1;
+ updateCachedClipPathFromSetPosHelper(newPos);
if (scene) {
fullUpdateHelper(true);
q->prepareGeometryChange();
}
this->pos = newPos;
invalidateSceneTransformCache();
- updateCachedClipPathFromSetPosHelper();
// Send post-notification.
q->itemChange(QGraphicsItem::ItemPositionHasChanged, newPos);
@@ -2771,7 +2771,7 @@ void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine)
return;
// Update and set the new transformation.
- d_ptr->fullUpdateHelper(true);
+ d_ptr->fullUpdateHelper(true, true);
prepareGeometryChange();
d_ptr->hasTransform = !newTransform.isIdentity();
d_ptr->setExtra(QGraphicsItemPrivate::ExtraTransform, newTransform);
@@ -2817,7 +2817,7 @@ void QGraphicsItem::setTransform(const QTransform &matrix, bool combine)
return;
// Update and set the new transformation.
- d_ptr->fullUpdateHelper(true);
+ d_ptr->fullUpdateHelper(true, true);
prepareGeometryChange();
d_ptr->hasTransform = !newTransform.isIdentity();
d_ptr->setExtra(QGraphicsItemPrivate::ExtraTransform, newTransform);
@@ -3626,7 +3626,7 @@ void QGraphicsItem::setBoundingRegionGranularity(qreal granularity)
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)
+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.
@@ -3634,6 +3634,8 @@ void QGraphicsItemPrivate::updateHelper(const QRectF &rect, bool force)
return;
if (!scene || (scene && scene->d_func()->updateAll && scene->d_func()->hasSceneRect))
return;
+ if (!force && !maybeDirtyClipPath && discardUpdateRequest())
+ return;
if (scene && (visible || force)) {
if (rect.isNull())
dirty = 1;
@@ -3646,17 +3648,19 @@ void QGraphicsItemPrivate::updateHelper(const QRectF &rect, bool force)
Propagates updates to \a item and all its children.
*/
-void QGraphicsItemPrivate::fullUpdateHelper(bool childrenOnly)
+void QGraphicsItemPrivate::fullUpdateHelper(bool childrenOnly, bool maybeDirtyClipPath)
{
+ if (!maybeDirtyClipPath && discardUpdateRequest())
+ return;
// 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 (!scene || (scene && scene->d_func()->updateAll && scene->d_func()->hasSceneRect))
return;
if (!childrenOnly && !dirty)
- updateHelper();
+ updateHelper(QRectF(), false, maybeDirtyClipPath);
if (children.isEmpty() || dirtyChildren)
return;
- if (flags & QGraphicsItem::ItemClipsChildrenToShape) {
+ if (flags & QGraphicsItem::ItemClipsChildrenToShape || children.isEmpty()) {
// ### mark all children dirty?
// Unnecessary to update children as well.
return;
@@ -3683,7 +3687,7 @@ void QGraphicsItemPrivate::fullUpdateHelper(bool childrenOnly)
}
}
foreach (QGraphicsItem *child, children)
- child->d_ptr->fullUpdateHelper();
+ child->d_ptr->fullUpdateHelper(false, maybeDirtyClipPath);
dirtyChildren = 1;
}
@@ -3813,23 +3817,35 @@ void QGraphicsItemPrivate::invalidateCachedClipPathRecursively(bool childrenOnly
}
}
-void QGraphicsItemPrivate::updateCachedClipPathFromSetPosHelper()
+void QGraphicsItemPrivate::updateCachedClipPathFromSetPosHelper(const QPointF &newPos)
{
Q_ASSERT(inSetPosHelper);
if (!(ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren))
return; // Not clipped by any ancestor.
- // Find closest clip ancestor.
+ // 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());
QGraphicsItem *clipParent = parent;
- while (clipParent && !(clipParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape))
+ 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());
+ }
clipParent = clipParent->d_ptr->parent;
+ }
+ // thisToParentTransform is now the same as q->itemTransform(clipParent), except
+ // that the new position (which is not yet set on the item) is taken into account.
Q_ASSERT(clipParent);
- Q_Q(QGraphicsItem);
+ Q_ASSERT(clipParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape);
// From here everything is calculated in clip parent's coordinates.
- const QTransform thisToParentTransform(q->itemTransform(clipParent));
const QRectF parentBoundingRect(clipParent->boundingRect());
const QRectF thisBoundingRect(thisToParentTransform.mapRect(q->boundingRect()));
@@ -3894,6 +3910,8 @@ void QGraphicsItem::update(const QRectF &rect)
{
if (d_ptr->dirty || (rect.isEmpty() && !rect.isNull()))
return;
+ if (d_ptr->discardUpdateRequest())
+ return;
if (d_ptr->scene && isVisible()) {
if (CacheMode(d_ptr->cacheMode) != NoCache) {
QGraphicsItemCache *cache = d_ptr->extraItemCache();
@@ -5639,7 +5657,7 @@ void QGraphicsItem::prepareGeometryChange()
if (!d_ptr->scene)
return;
- d_ptr->updateHelper();
+ d_ptr->updateHelper(QRectF(), false, /*maybeDirtyClipPath=*/!d_ptr->inSetPosHelper);
QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func();
scenePrivate->removeFromIndex(this);
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index 3e4c269..dabbe53 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -164,8 +164,8 @@ public:
void setPosHelper(const QPointF &pos);
void setVisibleHelper(bool newVisible, bool explicitly, bool update = true);
void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true);
- void updateHelper(const QRectF &rect = QRectF(), bool force = false);
- void fullUpdateHelper(bool childrenOnly = false);
+ void updateHelper(const QRectF &rect = QRectF(), bool force = false, bool maybeDirtyClipPath = false);
+ void fullUpdateHelper(bool childrenOnly = false, bool maybeDirtyClipPath = false);
void resolveEffectiveOpacity(qreal effectiveParentOpacity);
void resolveDepth(int parentDepth);
void invalidateSceneTransformCache();
@@ -256,7 +256,7 @@ public:
{ /*static int count = 0 ;qWarning("%i", ++count);*/ dirtyClipPath = 1; emptyClipPath = 0; }
void invalidateCachedClipPathRecursively(bool childrenOnly = false, const QRectF &emptyIfOutsideThisRect = QRectF());
- void updateCachedClipPathFromSetPosHelper();
+ void updateCachedClipPathFromSetPosHelper(const QPointF &newPos);
inline bool isInvisible() const
{
@@ -267,6 +267,9 @@ public:
inline bool isClippedAway() const
{ return !dirtyClipPath && q_func()->isClipped() && (emptyClipPath || cachedClipPath.isEmpty()); }
+ inline bool discardUpdateRequest() const
+ { return ((flags & QGraphicsItem::ItemClipsChildrenToShape) || children.isEmpty()) && isClippedAway(); }
+
QPainterPath cachedClipPath;
QPointF pos;
qreal z;
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index 9191fc5..43263da 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -855,6 +855,8 @@ void QGraphicsViewPrivate::_q_updateLaterSlot()
const QList &dirtyItems = scene->d_func()->dirtyItems;
for (int i = 0; i < dirtyItems.size(); ++i) {
const QGraphicsItem *item = dirtyItems.at(i);
+ if (item->d_ptr->discardUpdateRequest())
+ continue;
QTransform x = item->sceneTransform() * viewTransform;
updateRect(x.mapRect(item->boundingRect()).toAlignedRect() & vr);
}
--
cgit v0.12
From 9ed299a3edba92791e1c5af64b8fd9c9fe74c0ea Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Wed, 25 Mar 2009 12:38:35 +0100
Subject: Fixes: Optimize QGraphicsViewPrivate::itemUpdated.
AutoTest: Still pass
Details: Get rid of QTransform::inverted()/operator*= and do
nothing if the item clips all its children and the update
rect is outside the bounding rect.
---
src/gui/graphicsview/qgraphicsview.cpp | 40 ++++++++++++++++------------------
1 file changed, 19 insertions(+), 21 deletions(-)
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index 43263da..4db2257 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -801,38 +801,36 @@ void QGraphicsViewPrivate::itemUpdated(QGraphicsItem *item, const QRectF &rect)
updateLater();
QRectF updateRect = rect;
- if (item->isClipped()) {
+ if ((item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape) || item->d_ptr->children.isEmpty()) {
+ updateRect &= item->boundingRect();
+ if (updateRect.isEmpty())
+ return;
+ }
+
+ QGraphicsItem *clipItem = item;
+ if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
// Minimize unnecessary redraw.
- QGraphicsItem *p = item;
- QTransform xform;
- QGraphicsItem *lastTransformItem = 0;
- while ((p = p->d_ptr->parent)) {
- if (p->flags() & QGraphicsItem::ItemClipsChildrenToShape) {
- if (!lastTransformItem)
- xform = item->itemTransform(p);
- else
- xform *= lastTransformItem->itemTransform(p);
- lastTransformItem = p;
- updateRect &= xform.inverted().mapRect(p->boundingRect());
+ 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) & parent->boundingRect();
if (updateRect.isEmpty())
return;
+ clipItem = parent;
}
- if (!(p->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren))
+ if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren))
break;
}
-
- if (updateRect.isEmpty())
- return;
}
- // Map the rect to view coordinates.
- QRect vr = viewport->rect();
-
+ // Map update rect from clipItem coordinates to view coordinates.
+ Q_ASSERT(clipItem);
if (!item->d_ptr->hasBoundingRegionGranularity)
- this->updateRect(mapToViewRect(item, updateRect) & vr);
+ this->updateRect(mapToViewRect(clipItem, updateRect) & viewport->rect());
else
- updateRegion(mapToViewRegion(item, updateRect) & vr);
+ updateRegion(mapToViewRegion(clipItem, updateRect) & viewport->rect());
}
void QGraphicsViewPrivate::updateLater()
--
cgit v0.12
From a914eb155e085ba0efa5b95154bf7345d4be7cd7 Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Wed, 25 Mar 2009 13:41:10 +0100
Subject: Fixes: Minimize QVariant constr/destr in setPosHelper.
RevBy: TrustMe
---
src/gui/graphicsview/qgraphicsitem.cpp | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index a5d6021..396fdbd 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -2363,7 +2363,8 @@ void QGraphicsItemPrivate::setPosHelper(const QPointF &pos)
return;
// Notify the item that the position is changing.
- QPointF newPos = q->itemChange(QGraphicsItem::ItemPositionChange, pos).toPointF();
+ const QVariant newPosVariant(q->itemChange(QGraphicsItem::ItemPositionChange, pos));
+ QPointF newPos = newPosVariant.toPointF();
if (newPos == this->pos)
return;
@@ -2378,7 +2379,7 @@ void QGraphicsItemPrivate::setPosHelper(const QPointF &pos)
invalidateSceneTransformCache();
// Send post-notification.
- q->itemChange(QGraphicsItem::ItemPositionHasChanged, newPos);
+ q->itemChange(QGraphicsItem::ItemPositionHasChanged, newPosVariant);
inSetPosHelper = 0;
}
--
cgit v0.12
From 5564ef89f46fe96aa0b22b888a9a8ba053eea6c7 Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Thu, 26 Mar 2009 16:48:48 +0100
Subject: Fixes: Don't check the force boolean.
Details: It's clipped away regardless.
---
src/gui/graphicsview/qgraphicsitem.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 396fdbd..c691206 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -3635,7 +3635,7 @@ void QGraphicsItemPrivate::updateHelper(const QRectF &rect, bool force, bool may
return;
if (!scene || (scene && scene->d_func()->updateAll && scene->d_func()->hasSceneRect))
return;
- if (!force && !maybeDirtyClipPath && discardUpdateRequest())
+ if (!maybeDirtyClipPath && discardUpdateRequest())
return;
if (scene && (visible || force)) {
if (rect.isNull())
--
cgit v0.12
From 15098c5ec73db5de8ca724f744a1484f888ed271 Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Thu, 26 Mar 2009 17:05:59 +0100
Subject: Fixes: Do not update children if not required.
AutoTest: Still pass
---
src/gui/graphicsview/qgraphicsitem.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index c691206..b4f36de 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -1583,9 +1583,10 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo
}
// Update children with explicitly = false.
+ const bool updateChildren = update && !(flags & QGraphicsItem::ItemClipsChildrenToShape);
foreach (QGraphicsItem *child, children) {
if (!newVisible || !child->d_ptr->explicitlyHidden)
- child->d_ptr->setVisibleHelper(newVisible, false);
+ child->d_ptr->setVisibleHelper(newVisible, false, updateChildren);
}
// Enable subfocus
--
cgit v0.12
From d85835580463f88df6a71d27d2577739e5366f68 Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Thu, 26 Mar 2009 17:16:36 +0100
Subject: Fixes: Don't bother updating hidden items.
AutoTest: Still pass
---
src/gui/graphicsview/qgraphicsitem.cpp | 2 +-
src/gui/graphicsview/qgraphicsscene.cpp | 3 +++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index b4f36de..327b352 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -3652,7 +3652,7 @@ void QGraphicsItemPrivate::updateHelper(const QRectF &rect, bool force, bool may
*/
void QGraphicsItemPrivate::fullUpdateHelper(bool childrenOnly, bool maybeDirtyClipPath)
{
- if (!maybeDirtyClipPath && discardUpdateRequest())
+ if (!visible || (!maybeDirtyClipPath && discardUpdateRequest()))
return;
// 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.
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index f32fe71..e13a767 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -5174,6 +5174,9 @@ void QGraphicsScene::itemUpdated(QGraphicsItem *item, const QRectF &rect)
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
--
cgit v0.12
From 23c73210fc79055f4bac44de0e43f9917f8d0e7f Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Tue, 24 Mar 2009 15:50:26 +0100
Subject: Fixes: Discard update requests if possible.
AutoTest: Still pass.
Details: Update requests can be discarded if the item itself is
clipped away and the item clips all its children to shape.
This cut-off is extremely effective (and aggressive:))
---
src/gui/graphicsview/qgraphicsitem.cpp | 39 +++++++++++++++++++++++++---------
src/gui/graphicsview/qgraphicsitem_p.h | 6 ++++++
2 files changed, 35 insertions(+), 10 deletions(-)
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 327b352..23787a7 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -1102,10 +1102,7 @@ void QGraphicsItem::setParentItem(QGraphicsItem *parent)
}
// Resolve opacity.
- if (QGraphicsItem *p = d_ptr->parent)
- d_ptr->resolveEffectiveOpacity(p->effectiveOpacity());
- else
- d_ptr->resolveEffectiveOpacity(1.0);
+ d_ptr->updateEffectiveOpacity();
// Resolve depth.
d_ptr->resolveDepth(parent ? parent->d_ptr->depth : -1);
@@ -1246,12 +1243,8 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
// Reresolve effective opacity if the opacity flags change.
static const quint32 opacityFlagsMask = ItemIgnoresParentOpacity | ItemDoesntPropagateOpacityToChildren;
- if ((flags & opacityFlagsMask) != (oldFlags & opacityFlagsMask)) {
- if (QGraphicsItem *p = d_ptr->parent)
- d_ptr->resolveEffectiveOpacity(p->effectiveOpacity());
- else
- d_ptr->resolveEffectiveOpacity(1.0);
- }
+ 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
@@ -3693,6 +3686,32 @@ void QGraphicsItemPrivate::fullUpdateHelper(bool childrenOnly, bool maybeDirtyCl
dirtyChildren = 1;
}
+static inline bool allChildrenCombineOpacity(QGraphicsItem *parent)
+{
+ Q_ASSERT(parent);
+ if (parent->flags() & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)
+ return false;
+
+ const QList 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 = ::allChildrenCombineOpacity(parent);
+ } else {
+ resolveEffectiveOpacity(1.0);
+ }
+ allChildrenCombineOpacity = ::allChildrenCombineOpacity(q);
+}
+
/*!
\internal
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index dabbe53..c795915 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -141,6 +141,7 @@ public:
dirtyClipPath(1),
emptyClipPath(0),
inSetPosHelper(0),
+ allChildrenCombineOpacity(1),
globalStackingOrder(-1),
sceneTransformIndex(-1),
q_ptr(0)
@@ -166,6 +167,7 @@ public:
void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true);
void updateHelper(const QRectF &rect = QRectF(), bool force = false, bool maybeDirtyClipPath = false);
void fullUpdateHelper(bool childrenOnly = false, bool maybeDirtyClipPath = false);
+ void updateEffectiveOpacity();
void resolveEffectiveOpacity(qreal effectiveParentOpacity);
void resolveDepth(int parentDepth);
void invalidateSceneTransformCache();
@@ -264,6 +266,9 @@ public:
&& qFuzzyCompare(q_func()->effectiveOpacity() + 1, qreal(1.0)));
}
+ inline bool childrenCombineOpacity() const
+ { return allChildrenCombineOpacity || children.isEmpty(); }
+
inline bool isClippedAway() const
{ return !dirtyClipPath && q_func()->isClipped() && (emptyClipPath || cachedClipPath.isEmpty()); }
@@ -308,6 +313,7 @@ public:
quint32 dirtyClipPath : 1;
quint32 emptyClipPath : 1;
quint32 inSetPosHelper : 1;
+ quint32 allChildrenCombineOpacity : 1;
// Optional stacking order
int globalStackingOrder;
--
cgit v0.12
From 73ce29e6bc09651a4e70b5e61c36d56e568905c7 Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Fri, 27 Mar 2009 18:53:02 +0100
Subject: Fixes: Simplify the cut-offs and be more agressive :-)
AutoTest: Still pass.
Details: It's easier to read and understand the code now.
---
src/gui/graphicsview/qgraphicsitem.cpp | 84 ++++++++++++++++++++--------------
src/gui/graphicsview/qgraphicsitem_p.h | 21 ++++++---
src/gui/graphicsview/qgraphicsview.cpp | 5 +-
3 files changed, 68 insertions(+), 42 deletions(-)
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 23787a7..d27d3cd 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -3613,6 +3613,24 @@ void QGraphicsItem::setBoundingRegionGranularity(qreal granularity)
/*!
\internal
+ Returns true if we can discard an update request; otherwise false.
+*/
+bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreClipping,
+ bool ignoreVisibleBit,
+ bool ignoreDirtyBit) const
+{
+ // 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)
+ || !scene
+ || (scene->d_func()->updateAll && scene->d_func()->hasSceneRect)
+ || (!ignoreClipping && (childrenClippedToShape() && isClippedAway()))
+ || (childrenCombineOpacity() && isFullyTransparent());
+}
+
+/*!
+ \internal
Asks the scene to mark this item's scene rect as dirty, requesting a
redraw. This does not invalidate any cache.
@@ -3625,17 +3643,12 @@ void QGraphicsItemPrivate::updateHelper(const QRectF &rect, bool force, bool may
{
// 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 (dirty)
- return;
- if (!scene || (scene && scene->d_func()->updateAll && scene->d_func()->hasSceneRect))
+ if (discardUpdateRequest(/*ignoreClipping=*/maybeDirtyClipPath, /*ignoreVisibleBit=*/force))
return;
- if (!maybeDirtyClipPath && discardUpdateRequest())
- return;
- if (scene && (visible || force)) {
- if (rect.isNull())
- dirty = 1;
- scene->itemUpdated(q_ptr, rect);
- }
+
+ if (rect.isNull())
+ dirty = 1;
+ scene->itemUpdated(q_ptr, rect);
}
/*!
@@ -3645,21 +3658,23 @@ void QGraphicsItemPrivate::updateHelper(const QRectF &rect, bool force, bool may
*/
void QGraphicsItemPrivate::fullUpdateHelper(bool childrenOnly, bool maybeDirtyClipPath)
{
- if (!visible || (!maybeDirtyClipPath && discardUpdateRequest()))
- return;
- // 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 (!scene || (scene && scene->d_func()->updateAll && scene->d_func()->hasSceneRect))
- return;
- if (!childrenOnly && !dirty)
- updateHelper(QRectF(), false, maybeDirtyClipPath);
- if (children.isEmpty() || dirtyChildren)
+ if (discardUpdateRequest(/*ignoreClipping=*/maybeDirtyClipPath,
+ /*ignoreVisibleBit=*/false,
+ /*ignoreDirtyBit=*/true)) {
return;
- if (flags & QGraphicsItem::ItemClipsChildrenToShape || children.isEmpty()) {
- // ### mark all children dirty?
+ }
+
+ 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.
@@ -3929,22 +3944,23 @@ bool QGraphicsItemPrivate::isProxyWidget() const
*/
void QGraphicsItem::update(const QRectF &rect)
{
- if (d_ptr->dirty || (rect.isEmpty() && !rect.isNull()))
+ if ((rect.isEmpty() && !rect.isNull()) || d_ptr->discardUpdateRequest())
return;
- if (d_ptr->discardUpdateRequest())
- return;
- if (d_ptr->scene && isVisible()) {
- if (CacheMode(d_ptr->cacheMode) != NoCache) {
- QGraphicsItemCache *cache = d_ptr->extraItemCache();
- if (rect.isNull()) {
- cache->allExposed = true;
- cache->exposed.clear();
- } else {
- cache->exposed.append(rect);
- }
+
+ if (CacheMode(d_ptr->cacheMode) != NoCache) {
+ QGraphicsItemCache *cache = d_ptr->extraItemCache();
+ if (rect.isNull()) {
+ cache->allExposed = true;
+ cache->exposed.clear();
+ } else {
+ cache->exposed.append(rect);
}
- d_ptr->updateHelper(rect);
}
+
+ // Effectively the same as updateHelper(rect);
+ if (rect.isNull())
+ d_ptr->dirty = 1;
+ d_ptr->scene->itemUpdated(this, rect);
}
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index c795915..a5871a7 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -165,6 +165,9 @@ public:
void setPosHelper(const QPointF &pos);
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) const;
void updateHelper(const QRectF &rect = QRectF(), bool force = false, bool maybeDirtyClipPath = false);
void fullUpdateHelper(bool childrenOnly = false, bool maybeDirtyClipPath = false);
void updateEffectiveOpacity();
@@ -260,11 +263,8 @@ public:
void invalidateCachedClipPathRecursively(bool childrenOnly = false, const QRectF &emptyIfOutsideThisRect = QRectF());
void updateCachedClipPathFromSetPosHelper(const QPointF &newPos);
- inline bool isInvisible() const
- {
- return !visible || (hasEffectiveOpacity
- && qFuzzyCompare(q_func()->effectiveOpacity() + 1, qreal(1.0)));
- }
+ inline bool isFullyTransparent() const
+ { return hasEffectiveOpacity && qFuzzyCompare(q_func()->effectiveOpacity() + 1, qreal(1.0)); }
inline bool childrenCombineOpacity() const
{ return allChildrenCombineOpacity || children.isEmpty(); }
@@ -272,8 +272,15 @@ public:
inline bool isClippedAway() const
{ return !dirtyClipPath && q_func()->isClipped() && (emptyClipPath || cachedClipPath.isEmpty()); }
- inline bool discardUpdateRequest() const
- { return ((flags & QGraphicsItem::ItemClipsChildrenToShape) || children.isEmpty()) && isClippedAway(); }
+ inline bool childrenClippedToShape() const
+ { return (flags & QGraphicsItem::ItemClipsChildrenToShape) || children.isEmpty(); }
+
+ inline bool isInvisible() const
+ {
+ return !visible
+ || (childrenClippedToShape() && isClippedAway())
+ || (childrenCombineOpacity() && isFullyTransparent());
+ }
QPainterPath cachedClipPath;
QPointF pos;
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index 4db2257..f0d360a 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -853,8 +853,11 @@ void QGraphicsViewPrivate::_q_updateLaterSlot()
const QList &dirtyItems = scene->d_func()->dirtyItems;
for (int i = 0; i < dirtyItems.size(); ++i) {
const QGraphicsItem *item = dirtyItems.at(i);
- if (item->d_ptr->discardUpdateRequest())
+ if (item->d_ptr->discardUpdateRequest(/*ignoreClipping=*/false,
+ /*ignoreVisibleBit=*/false,
+ /*ignoreDirtyBit=*/true)) {
continue;
+ }
QTransform x = item->sceneTransform() * viewTransform;
updateRect(x.mapRect(item->boundingRect()).toAlignedRect() & vr);
}
--
cgit v0.12
From 30d01c387179160c8c418ecedfb4506a55d282e8 Mon Sep 17 00:00:00 2001
From: Lars Knoll
Date: Fri, 27 Mar 2009 22:17:10 +0100
Subject: Optimise QGraphicsScene/View::items(const QPointF &pos)
Implement specialized (and more efficient versions) of item_helper()
and child_helper() that test for QPointF in the scene.
---
src/gui/graphicsview/qgraphicsscene.cpp | 94 ++++++++++++++++++++++++++++-----
src/gui/graphicsview/qgraphicsscene_p.h | 4 ++
src/gui/graphicsview/qgraphicsview.cpp | 4 +-
3 files changed, 88 insertions(+), 14 deletions(-)
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index e13a767..b4dc62c 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -1358,6 +1358,48 @@ QGraphicsWidget *QGraphicsScenePrivate::windowForItem(const QGraphicsItem *item)
return 0;
}
+
+QList QGraphicsScenePrivate::items_helper(const QPointF &pos) const
+{
+ QList items;
+
+ // The index returns a rough estimate of what items are inside the rect.
+ // Refine it by iterating through all returned items.
+ QRectF adjustedRect = QRectF(pos, QSize(1,1));
+ foreach (QGraphicsItem *item, estimateItemsInRect(adjustedRect)) {
+ // Find the item's scene transform in a clever way.
+ QTransform x = item->sceneTransform();
+ bool keep = false;
+
+ // ### _q_adjustedRect is only needed because QRectF::intersects,
+ // QRectF::contains and QTransform::map() and friends don't work with
+ // flat rectangles.
+ QRectF br = _q_adjustedRect(item->boundingRect());
+ // Rect intersects/contains item's shape
+ if (QRectF_intersects(adjustedRect, x.mapRect(br))) {
+ bool ok;
+ QTransform xinv = x.inverted(&ok);
+ if (ok) {
+ if (item->contains(xinv.map(pos))) {
+ items << item;
+ keep = true;
+ }
+ }
+ }
+
+ if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) {
+ // Recurse into children that clip children.
+ bool ok;
+ QTransform xinv = x.inverted(&ok);
+ if (ok)
+ childItems_helper(&items, item, xinv.map(pos));
+ }
+ }
+
+ sortItems(&items, Qt::AscendingOrder, sortCacheEnabled);
+ return items;
+}
+
QList QGraphicsScenePrivate::items_helper(const QRectF &rect,
Qt::ItemSelectionMode mode,
Qt::SortOrder order) const
@@ -1392,7 +1434,7 @@ QList QGraphicsScenePrivate::items_helper(const QRectF &rect,
bool ok;
QTransform xinv = x.inverted(&ok);
if (ok) {
- if (path == QPainterPath())
+ if (path.isEmpty())
path.addRect(rect);
if (itemCollidesWithPath(item, xinv.map(path), mode)) {
items << item;
@@ -1536,6 +1578,42 @@ QList QGraphicsScenePrivate::items_helper(const QPainterPath &p
void QGraphicsScenePrivate::childItems_helper(QList *items,
const QGraphicsItem *parent,
+ const QPointF &pos) const
+{
+ bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape);
+ if (parentClip && parent->d_ptr->isClippedAway())
+ return;
+ // ### is this needed?
+ if (parentClip && !parent->boundingRect().contains(pos))
+ return;
+
+ QList &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())
+ continue;
+
+ // Skip invisible items and all their children.
+ if (item->d_ptr->isInvisible())
+ continue;
+
+ bool keep = false;
+ if (!item->d_ptr->isClippedAway()) {
+ if (item->contains(item->mapFromParent(pos))) {
+ items->append(item);
+ keep = true;
+ }
+ }
+
+ if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty())
+ // Recurse into children.
+ childItems_helper(items, item, item->mapFromParent(pos));
+ }
+}
+
+
+void QGraphicsScenePrivate::childItems_helper(QList *items,
+ const QGraphicsItem *parent,
const QRectF &rect,
Qt::ItemSelectionMode mode) const
{
@@ -1597,6 +1675,7 @@ void QGraphicsScenePrivate::childItems_helper(QList *items,
}
}
+
void QGraphicsScenePrivate::childItems_helper(QList *items,
const QGraphicsItem *parent,
const QPolygonF &polygon,
@@ -2380,17 +2459,8 @@ QList QGraphicsScene::items() const
*/
QList QGraphicsScene::items(const QPointF &pos) const
{
- QList itemsAtPoint;
-
- // Find all items within a 1x1 rect area starting at pos. This can be
- // inefficient for scenes that use small coordinates (like unity
- // coordinates), or for detailed graphs. ### The index should support
- // fetching items at a pos to avoid this limitation.
- foreach (QGraphicsItem *item, items(QRectF(pos, QSizeF(1, 1)), Qt::IntersectsItemBoundingRect)) {
- if (item->contains(item->mapFromScene(pos)))
- itemsAtPoint << item;
- }
- return itemsAtPoint;
+ Q_D(const QGraphicsScene);
+ return d->items_helper(pos);
}
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
index 9c165d1..befbbd8 100644
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_p.h
@@ -197,6 +197,7 @@ public:
void mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent);
QGraphicsWidget *windowForItem(const QGraphicsItem *item) const;
+ QList items_helper(const QPointF &pos) const;
QList items_helper(const QRectF &rect,
Qt::ItemSelectionMode mode,
Qt::SortOrder order) const;
@@ -208,6 +209,9 @@ public:
Qt::SortOrder order) const;
void childItems_helper(QList *items,
const QGraphicsItem *parent,
+ const QPointF &pos) const;
+ void childItems_helper(QList *items,
+ const QGraphicsItem *parent,
const QRectF &rect,
Qt::ItemSelectionMode mode) const;
void childItems_helper(QList *items,
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index f0d360a..ba9cdbf 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -2251,9 +2251,9 @@ QList QGraphicsView::items(const QPoint &pos) const
if (d->scene->d_func()->largestUntransformableItem.isNull()) {
if ((d->identityMatrix || d->matrix.type() <= QTransform::TxScale)) {
QTransform xinv = viewportTransform().inverted();
- return d->scene->items(xinv.mapRect(QRectF(pos.x(), pos.y(), 1, 1)));
+ return d->scene->items(xinv.map(pos));
}
- return d->scene->items(mapToScene(pos.x(), pos.y(), 2, 2));
+ return d->scene->items(mapToScene(pos));
}
QPainterPath path;
--
cgit v0.12
From bc3d96a902d16a9bb358c05de9f6bfede3594731 Mon Sep 17 00:00:00 2001
From: Lars Knoll
Date: Fri, 27 Mar 2009 22:18:47 +0100
Subject: Optimise QPainterPath::contains(QPointF)
We can shortcut quite some calculations for the common case
by first checking whether the point is contained in the
control point rect.
---
src/gui/painting/qpainterpath.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index 70036e1..e1f5eea 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -1725,7 +1725,7 @@ static void qt_painterpath_isect_curve(const QBezier &bezier, const QPointF &pt,
*/
bool QPainterPath::contains(const QPointF &pt) const
{
- if (isEmpty())
+ if (isEmpty() || !controlPointRect().contains(pt))
return false;
QPainterPathData *d = d_func();
--
cgit v0.12
From d516e5fbed3a7eac20229ead34221c732f85cdb6 Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Tue, 31 Mar 2009 14:58:15 +0200
Subject: Fixes: Minimize QVariant overhead related to
QGraphicsItem::itemChange.
RevBy: Andreas
AutoTest: included
---
src/gui/graphicsview/qgraphicsitem.cpp | 70 ++++++++++++++------------
src/gui/graphicsview/qgraphicsscene.cpp | 24 +++++----
tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 18 +++++++
3 files changed, 69 insertions(+), 43 deletions(-)
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index d27d3cd..11a03b6 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -1024,9 +1024,8 @@ void QGraphicsItem::setParentItem(QGraphicsItem *parent)
}
if (parent == d_ptr->parent)
return;
- QVariant variant;
- qVariantSetValue(variant, parent);
- parent = qVariantValue(itemChange(ItemParentChange, variant));
+ const QVariant newParentVariant(itemChange(ItemParentChange, qVariantFromValue(parent)));
+ parent = qVariantValue(newParentVariant);
if (parent == d_ptr->parent)
return;
@@ -1041,11 +1040,11 @@ void QGraphicsItem::setParentItem(QGraphicsItem *parent)
// We anticipate geometry changes
prepareGeometryChange();
+ const QVariant thisPointerVariant(qVariantFromValue(this));
if (d_ptr->parent) {
// Remove from current parent
qt_graphicsitem_removeChild(this, &d_ptr->parent->d_func()->children);
- qVariantSetValue(variant, this);
- d_ptr->parent->itemChange(ItemChildRemovedChange, variant);
+ d_ptr->parent->itemChange(ItemChildRemovedChange, thisPointerVariant);
}
if ((d_ptr->parent = parent)) {
@@ -1060,8 +1059,7 @@ void QGraphicsItem::setParentItem(QGraphicsItem *parent)
}
d_ptr->parent->d_func()->children << this;
- qVariantSetValue(variant, this);
- d_ptr->parent->itemChange(ItemChildAddedChange, variant);
+ d_ptr->parent->itemChange(ItemChildAddedChange, thisPointerVariant);
if (!implicitUpdate)
d_ptr->updateHelper(QRectF(), false, true);
@@ -1111,7 +1109,7 @@ void QGraphicsItem::setParentItem(QGraphicsItem *parent)
d_ptr->invalidateSceneTransformCache();
// Deliver post-change notification
- itemChange(QGraphicsItem::ItemParentHasChanged, qVariantFromValue(parent));
+ itemChange(QGraphicsItem::ItemParentHasChanged, newParentVariant);
}
/*!
@@ -1372,9 +1370,9 @@ QString QGraphicsItem::toolTip() const
*/
void QGraphicsItem::setToolTip(const QString &toolTip)
{
- QString newCursor = itemChange(ItemToolTipChange, toolTip).toString();
- d_ptr->setExtra(QGraphicsItemPrivate::ExtraToolTip, toolTip);
- itemChange(ItemToolTipHasChanged, toolTip);
+ const QVariant toolTipVariant(itemChange(ItemToolTipChange, toolTip));
+ d_ptr->setExtra(QGraphicsItemPrivate::ExtraToolTip, toolTipVariant.toString());
+ itemChange(ItemToolTipHasChanged, toolTipVariant);
}
#endif // QT_NO_TOOLTIP
@@ -1416,9 +1414,8 @@ QCursor QGraphicsItem::cursor() const
*/
void QGraphicsItem::setCursor(const QCursor &cursor)
{
- QCursor newCursor = qVariantValue(itemChange(ItemCursorChange,
- qVariantFromValue(cursor)));
- d_ptr->setExtra(QGraphicsItemPrivate::ExtraCursor, newCursor);
+ const QVariant cursorVariant(itemChange(ItemCursorChange, qVariantFromValue(cursor)));
+ d_ptr->setExtra(QGraphicsItemPrivate::ExtraCursor, qVariantValue(cursorVariant));
d_ptr->hasCursor = 1;
if (d_ptr->scene) {
foreach (QGraphicsView *view, d_ptr->scene->views()) {
@@ -1435,7 +1432,7 @@ void QGraphicsItem::setCursor(const QCursor &cursor)
}
}
}
- itemChange(ItemCursorHasChanged, qVariantFromValue(newCursor));
+ itemChange(ItemCursorHasChanged, cursorVariant);
}
/*!
@@ -1529,7 +1526,9 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo
return;
// Modify the property.
- newVisible = q_ptr->itemChange(QGraphicsItem::ItemVisibleChange, quint32(newVisible)).toBool();
+ const QVariant newVisibleVariant(q_ptr->itemChange(QGraphicsItem::ItemVisibleChange,
+ quint32(newVisible)));
+ newVisible = newVisibleVariant.toBool();
if (visible == quint32(newVisible))
return;
visible = newVisible;
@@ -1591,7 +1590,7 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo
}
// Deliver post-change notification.
- q_ptr->itemChange(QGraphicsItem::ItemVisibleHasChanged, quint32(visible));
+ q_ptr->itemChange(QGraphicsItem::ItemVisibleHasChanged, newVisibleVariant);
}
/*!
@@ -1697,7 +1696,9 @@ void QGraphicsItemPrivate::setEnabledHelper(bool newEnabled, bool explicitly, bo
}
// Modify the property.
- enabled = q_ptr->itemChange(QGraphicsItem::ItemEnabledChange, quint32(newEnabled)).toBool();
+ const QVariant newEnabledVariant(q_ptr->itemChange(QGraphicsItem::ItemEnabledChange,
+ quint32(newEnabled)));
+ enabled = newEnabledVariant.toBool();
// Schedule redraw.
if (update)
@@ -1709,7 +1710,7 @@ void QGraphicsItemPrivate::setEnabledHelper(bool newEnabled, bool explicitly, bo
}
// Deliver post-change notification.
- q_ptr->itemChange(QGraphicsItem::ItemEnabledHasChanged, quint32(enabled));
+ q_ptr->itemChange(QGraphicsItem::ItemEnabledHasChanged, newEnabledVariant);
}
/*!
@@ -1796,7 +1797,8 @@ void QGraphicsItem::setSelected(bool selected)
selected = false;
if (d_ptr->selected == selected)
return;
- bool newSelected = itemChange(ItemSelectedChange, quint32(selected)).toBool();
+ const QVariant newSelectedVariant(itemChange(ItemSelectedChange, quint32(selected)));
+ bool newSelected = newSelectedVariant.toBool();
if (d_ptr->selected == newSelected)
return;
d_ptr->selected = newSelected;
@@ -1816,7 +1818,7 @@ void QGraphicsItem::setSelected(bool selected)
}
// Deliver post-change notification.
- itemChange(QGraphicsItem::ItemSelectedHasChanged, quint32(d_ptr->selected));
+ itemChange(QGraphicsItem::ItemSelectedHasChanged, newSelectedVariant);
}
/*!
@@ -1892,7 +1894,8 @@ qreal QGraphicsItem::effectiveOpacity() const
void QGraphicsItem::setOpacity(qreal opacity)
{
// Notify change.
- qreal newOpacity = itemChange(ItemOpacityChange, double(opacity)).toDouble();
+ const QVariant newOpacityVariant(itemChange(ItemOpacityChange, double(opacity)));
+ qreal newOpacity = newOpacityVariant.toDouble();
// Normalize.
newOpacity = qBound(0.0, newOpacity, 1.0);
@@ -2759,9 +2762,9 @@ void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine)
return;
// Notify the item that the matrix is changing.
- QVariant variant;
- qVariantSetValue(variant, newTransform.toAffine());
- newTransform = QTransform(qVariantValue(itemChange(ItemMatrixChange, variant)));
+ QVariant newTransformVariant(itemChange(ItemMatrixChange,
+ qVariantFromValue(newTransform.toAffine())));
+ newTransform = QTransform(qVariantValue(newTransformVariant));
if (oldTransform == newTransform)
return;
@@ -2773,7 +2776,9 @@ void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine)
d_ptr->invalidateSceneTransformCache();
// Send post-notification.
- itemChange(ItemTransformHasChanged, newTransform);
+ // NB! We have to change the value from QMatrix to QTransform.
+ qVariantSetValue(newTransformVariant, newTransform);
+ itemChange(ItemTransformHasChanged, newTransformVariant);
}
/*!
@@ -2805,9 +2810,9 @@ void QGraphicsItem::setTransform(const QTransform &matrix, bool combine)
return;
// Notify the item that the transformation matrix is changing.
- QVariant variant;
- qVariantSetValue(variant, newTransform);
- newTransform = qVariantValue(itemChange(ItemTransformChange, variant));
+ const QVariant newTransformVariant(itemChange(ItemTransformChange,
+ qVariantFromValue(newTransform)));
+ newTransform = qVariantValue(newTransformVariant);
if (oldTransform == newTransform)
return;
@@ -2819,7 +2824,7 @@ void QGraphicsItem::setTransform(const QTransform &matrix, bool combine)
d_ptr->invalidateSceneTransformCache();
// Send post-notification.
- itemChange(ItemTransformHasChanged, newTransform);
+ itemChange(ItemTransformHasChanged, newTransformVariant);
}
/*!
@@ -2967,7 +2972,8 @@ qreal QGraphicsItem::zValue() const
*/
void QGraphicsItem::setZValue(qreal z)
{
- qreal newZ = qreal(itemChange(ItemZValueChange, double(z)).toDouble());
+ const QVariant newZVariant(itemChange(ItemZValueChange, double(z)));
+ qreal newZ = qreal(newZVariant.toDouble());
if (newZ == d_ptr->z)
return;
d_ptr->z = z;
@@ -2979,7 +2985,7 @@ void QGraphicsItem::setZValue(qreal z)
d_ptr->scene->d_func()->invalidateSortCache();
}
- itemChange(ItemZValueHasChanged, double(newZ));
+ itemChange(ItemZValueHasChanged, newZVariant);
}
/*!
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index b4dc62c..bcc329e 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -632,10 +632,11 @@ void QGraphicsScenePrivate::_q_updateLater()
*/
void QGraphicsScenePrivate::_q_polishItems()
{
+ const QVariant booleanTrueVariant(true);
foreach (QGraphicsItem *item, unpolishedItems) {
if (!item->d_ptr->explicitlyHidden) {
- item->itemChange(QGraphicsItem::ItemVisibleChange, true);
- item->itemChange(QGraphicsItem::ItemVisibleHasChanged, true);
+ item->itemChange(QGraphicsItem::ItemVisibleChange, booleanTrueVariant);
+ item->itemChange(QGraphicsItem::ItemVisibleHasChanged, booleanTrueVariant);
}
if (item->isWidget()) {
QEvent event(QEvent::Polish);
@@ -691,9 +692,8 @@ void QGraphicsScenePrivate::_q_removeItemLater(QGraphicsItem *item)
Q_Q(QGraphicsScene);
if (QGraphicsItem *parent = item->d_func()->parent) {
- QVariant variant;
- qVariantSetValue(variant, item);
- parent->itemChange(QGraphicsItem::ItemChildRemovedChange, variant);
+ parent->itemChange(QGraphicsItem::ItemChildRemovedChange,
+ qVariantFromValue(item));
parent->d_func()->children.removeAll(item);
}
@@ -2847,8 +2847,9 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
// Notify the item that its scene is changing, and allow the item to
// react.
- QGraphicsScene *targetScene = qVariantValue(item->itemChange(QGraphicsItem::ItemSceneChange,
- qVariantFromValue(this)));
+ const QVariant newSceneVariant(item->itemChange(QGraphicsItem::ItemSceneChange,
+ qVariantFromValue(this)));
+ QGraphicsScene *targetScene = qVariantValue(newSceneVariant);
if (targetScene != this) {
if (targetScene && item->scene() != targetScene)
targetScene->addItem(item);
@@ -2942,7 +2943,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
emit selectionChanged();
// Deliver post-change notification
- item->itemChange(QGraphicsItem::ItemSceneHasChanged, qVariantFromValue(this));
+ item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant);
}
/*!
@@ -3206,8 +3207,9 @@ void QGraphicsScene::removeItem(QGraphicsItem *item)
// Notify the item that it's scene is changing to 0, allowing the item to
// react.
- QGraphicsScene *targetScene = qVariantValue(item->itemChange(QGraphicsItem::ItemSceneChange,
- qVariantFromValue(0)));
+ const QVariant newSceneVariant(item->itemChange(QGraphicsItem::ItemSceneChange,
+ qVariantFromValue(0)));
+ QGraphicsScene *targetScene = qVariantValue(newSceneVariant);
if (targetScene != 0 && targetScene != this) {
targetScene->addItem(item);
return;
@@ -3305,7 +3307,7 @@ void QGraphicsScene::removeItem(QGraphicsItem *item)
emit selectionChanged();
// Deliver post-change notification
- item->itemChange(QGraphicsItem::ItemSceneHasChanged, qVariantFromValue(0));
+ item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant);
}
/*!
diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
index 0f2d671..ad0dc97 100644
--- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
+++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
@@ -3934,8 +3934,26 @@ void tst_QGraphicsItem::itemChange()
tester.itemSceneChangeTargetScene = 0;
tester.itemChangeReturnValue = QVariant();
scene.removeItem(&tester);
+ ++changeCount; // ItemSceneChange
+ ++changeCount; // ItemSceneHasChanged
QCOMPARE(tester.scene(), (QGraphicsScene *)0);
}
+ {
+ // ItemToolTipChange/ItemToolTipHasChanged
+ const QString toolTip(QLatin1String("I'm soo cool"));
+ const QString overridenToolTip(QLatin1String("No, you are not soo cool"));
+ tester.itemChangeReturnValue = overridenToolTip;
+ tester.setToolTip(toolTip);
+ ++changeCount; // ItemToolTipChange
+ ++changeCount; // ItemToolTipHasChanged
+ QCOMPARE(tester.changes.size(), changeCount);
+ QCOMPARE(tester.changes.at(changeCount - 2), QGraphicsItem::ItemToolTipChange);
+ QCOMPARE(tester.values.at(changeCount - 2).toString(), toolTip);
+ QCOMPARE(tester.changes.at(changeCount - 1), QGraphicsItem::ItemToolTipHasChanged);
+ QCOMPARE(tester.values.at(changeCount - 1).toString(), overridenToolTip);
+ QCOMPARE(tester.toolTip(), overridenToolTip);
+ tester.itemChangeReturnValue = QVariant();
+ }
}
class EventFilterTesterItem : public QGraphicsLineItem
--
cgit v0.12
From 79799ec4788692d44862832d85f80953d386cb27 Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Wed, 1 Apr 2009 11:25:01 +0200
Subject: Fixes: Partially revert 9b0af2395c84a6895a5ce6368f151d4ec00c8755
RevBy: Andreas
AutoTest: tst_QGraphicsView::itemAt2 pass again
Details: A QPoint in the view has to be mapped to a pixel in the
scene, otherwise it won't be possible to e.g. click
on items that are smaller than a pixel.
So...we have to optimize the hit-testing code in another way
---
src/gui/graphicsview/qgraphicsview.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index ba9cdbf..f0d360a 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -2251,9 +2251,9 @@ QList QGraphicsView::items(const QPoint &pos) const
if (d->scene->d_func()->largestUntransformableItem.isNull()) {
if ((d->identityMatrix || d->matrix.type() <= QTransform::TxScale)) {
QTransform xinv = viewportTransform().inverted();
- return d->scene->items(xinv.map(pos));
+ return d->scene->items(xinv.mapRect(QRectF(pos.x(), pos.y(), 1, 1)));
}
- return d->scene->items(mapToScene(pos));
+ return d->scene->items(mapToScene(pos.x(), pos.y(), 2, 2));
}
QPainterPath path;
--
cgit v0.12
From 32767aa5699937a3737b9515f4f82acc04ccdfcd Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Fri, 3 Apr 2009 11:47:59 +0200
Subject: Fixes: Optimize the way we adjust rectangles.
RevBy: Olivier
AutoTest: Still pass
---
src/gui/graphicsview/qgraphicsitem.cpp | 39 ++++++++---------
src/gui/graphicsview/qgraphicsscene.cpp | 76 +++++++++++++++++++++------------
2 files changed, 68 insertions(+), 47 deletions(-)
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 11a03b6..8478561 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -528,25 +528,22 @@ QT_BEGIN_NAMESPACE
// QRectF::intersects() returns false always if either the source or target
// rectangle's width or height are 0. This works around that problem.
-static QRectF _q_adjustedRect(const QRectF &rect)
-{
- static const qreal p = (qreal)0.00001;
- QRectF r = rect;
- if (!r.width())
- r.adjust(-p, 0, p, 0);
- if (!r.height())
- r.adjust(0, -p, 0, p);
- return r;
+static inline void _q_adjustRect(QRectF *rect)
+{
+ Q_ASSERT(rect);
+ if (!rect->width())
+ rect->adjust(-0.00001, 0, 0.00001, 0);
+ if (!rect->height())
+ rect->adjust(0, -0.00001, 0, 0.00001);
}
-static QRect _q_adjustedRect(const QRect &rect)
+static inline void _q_adjustRect(QRect *rect)
{
- QRect r = rect;
- if (!r.width())
- r.adjust(0, 0, 1, 0);
- if (!r.height())
- r.adjust(0, 0, 0, 1);
- return r;
+ Q_ASSERT(rect);
+ if (!rect->width())
+ rect->adjust(0, 0, 1, 0);
+ if (!rect->height())
+ rect->adjust(0, 0, 0, 1);
}
/*
@@ -3305,8 +3302,10 @@ bool QGraphicsItem::collidesWithPath(const QPainterPath &path, Qt::ItemSelection
return false;
}
- const QRectF rectA = _q_adjustedRect(boundingRect());
- const QRectF rectB = _q_adjustedRect(path.controlPointRect());
+ QRectF rectA(boundingRect());
+ _q_adjustRect(&rectA);
+ QRectF rectB(path.controlPointRect());
+ _q_adjustRect(&rectB);
if (!rectA.intersects(rectB)) {
// This we can determine efficiently. If the two rects neither
// intersect nor contain eachother, then the two items do not collide.
@@ -3489,7 +3488,9 @@ QRegion QGraphicsItem::boundingRegion(const QTransform &itemToDeviceTransform) c
// into the bitmap, converts the result to a QRegion and scales the region
// back to device space with inverse granularity.
qreal granularity = boundingRegionGranularity();
- QRect deviceRect = _q_adjustedRect(itemToDeviceTransform.mapRect(boundingRect()).toRect());
+ QRectF adjustedMappedBoundingRect(itemToDeviceTransform.mapRect(boundingRect()));
+ _q_adjustRect(&adjustedMappedBoundingRect);
+ QRect deviceRect = adjustedMappedBoundingRect.toRect();
if (granularity == 0.0)
return QRegion(deviceRect);
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index bcc329e..a5fec69 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -292,15 +292,21 @@ static inline bool QRectF_intersects(const QRectF &s, const QRectF &r)
// QRectF::intersects() returns false always if either the source or target
// rectangle's width or height are 0. This works around that problem.
-static QRectF _q_adjustedRect(const QRectF &rect)
+static inline void _q_adjustRect(QRectF *rect)
{
- static const qreal p = (qreal)0.00001;
- QRectF r = rect;
- if (!r.width())
- r.adjust(-p, 0, p, 0);
- if (!r.height())
- r.adjust(0, -p, 0, p);
- return r;
+ Q_ASSERT(rect);
+ if (!rect->width())
+ rect->adjust(-0.00001, 0, 0.00001, 0);
+ if (!rect->height())
+ rect->adjust(0, -0.00001, 0, 0.00001);
+}
+
+static inline QRectF adjustedItemBoundingRect(const QGraphicsItem *item)
+{
+ Q_ASSERT(item);
+ QRectF boundingRect(item->boundingRect());
+ _q_adjustRect(&boundingRect);
+ return boundingRect;
}
static void _q_hoverFromMouseEvent(QGraphicsSceneHoverEvent *hover, const QGraphicsSceneMouseEvent *mouseEvent)
@@ -1374,7 +1380,7 @@ QList QGraphicsScenePrivate::items_helper(const QPointF &pos) c
// ### _q_adjustedRect is only needed because QRectF::intersects,
// QRectF::contains and QTransform::map() and friends don't work with
// flat rectangles.
- QRectF br = _q_adjustedRect(item->boundingRect());
+ const QRectF br(adjustedItemBoundingRect(item));
// Rect intersects/contains item's shape
if (QRectF_intersects(adjustedRect, x.mapRect(br))) {
bool ok;
@@ -1410,7 +1416,8 @@ QList QGraphicsScenePrivate::items_helper(const QRectF &rect,
// The index returns a rough estimate of what items are inside the rect.
// Refine it by iterating through all returned items.
- QRectF adjustedRect = _q_adjustedRect(rect);
+ QRectF adjustedRect(rect);
+ _q_adjustRect(&adjustedRect);
foreach (QGraphicsItem *item, estimateItemsInRect(adjustedRect)) {
// Find the item's scene transform in a clever way.
QTransform x = item->sceneTransform();
@@ -1419,7 +1426,7 @@ QList QGraphicsScenePrivate::items_helper(const QRectF &rect,
// ### _q_adjustedRect is only needed because QRectF::intersects,
// QRectF::contains and QTransform::map() and friends don't work with
// flat rectangles.
- QRectF br = _q_adjustedRect(item->boundingRect());
+ const QRectF br(adjustedItemBoundingRect(item));
if (mode >= Qt::ContainsItemBoundingRect) {
// Rect intersects/contains item's bounding rect
QRectF mbr = x.mapRect(br);
@@ -1471,7 +1478,8 @@ QList QGraphicsScenePrivate::items_helper(const QPolygonF &poly
{
QList items;
- QRectF polyRect = _q_adjustedRect(polygon.boundingRect());
+ QRectF polyRect(polygon.boundingRect());
+ _q_adjustRect(&polyRect);
QPainterPath path;
// The index returns a rough estimate of what items are inside the rect.
@@ -1484,7 +1492,7 @@ QList QGraphicsScenePrivate::items_helper(const QPolygonF &poly
// ### _q_adjustedRect is only needed because QRectF::intersects,
// QRectF::contains and QTransform::map() and friends don't work with
// flat rectangles.
- QRectF br = _q_adjustedRect(item->boundingRect());
+ const QRectF br(adjustedItemBoundingRect(item));
if (mode >= Qt::ContainsItemBoundingRect) {
// Polygon contains/intersects item's bounding rect
if (path == QPainterPath())
@@ -1529,7 +1537,8 @@ QList QGraphicsScenePrivate::items_helper(const QPainterPath &p
Qt::SortOrder order) const
{
QList items;
- const QRectF pathRect = _q_adjustedRect(path.controlPointRect());
+ QRectF pathRect(path.controlPointRect());
+ _q_adjustRect(&pathRect);
// The index returns a rough estimate of what items are inside the rect.
// Refine it by iterating through all returned items.
@@ -1541,7 +1550,7 @@ QList QGraphicsScenePrivate::items_helper(const QPainterPath &p
// ### _q_adjustedRect is only needed because QRectF::intersects,
// QRectF::contains and QTransform::map() and friends don't work with
// flat rectangles.
- QRectF br = _q_adjustedRect(item->boundingRect());
+ const QRectF br(adjustedItemBoundingRect(item));
if (mode >= Qt::ContainsItemBoundingRect) {
// Path contains/intersects item's bounding rect
if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(x.mapRect(br)))
@@ -1620,7 +1629,9 @@ void QGraphicsScenePrivate::childItems_helper(QList *items,
bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape);
if (parentClip && parent->d_ptr->isClippedAway())
return;
- QRectF r = !parentClip ? _q_adjustedRect(rect) : _q_adjustedRect(rect).intersected(_q_adjustedRect(parent->boundingRect()));
+ QRectF adjustedRect(rect);
+ _q_adjustRect(&adjustedRect);
+ QRectF r = !parentClip ? adjustedRect : adjustedRect.intersected(adjustedItemBoundingRect(parent));
if (r.isEmpty())
return;
@@ -1640,7 +1651,7 @@ void QGraphicsScenePrivate::childItems_helper(QList *items,
// ### _q_adjustedRect is only needed because QRectF::intersects,
// QRectF::contains and QTransform::map() and friends don't work with
// flat rectangles.
- QRectF br = _q_adjustedRect(item->boundingRect());
+ const QRectF br(adjustedItemBoundingRect(item));
QRectF mbr = item->mapRectToParent(br);
if (mode >= Qt::ContainsItemBoundingRect) {
// Rect intersects/contains item's bounding rect
@@ -1684,8 +1695,9 @@ void QGraphicsScenePrivate::childItems_helper(QList *items,
bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape);
if (parentClip && parent->d_ptr->isClippedAway())
return;
- QRectF polyRect = _q_adjustedRect(polygon.boundingRect());
- QRectF r = !parentClip ? polyRect : polyRect.intersected(_q_adjustedRect(parent->boundingRect()));
+ QRectF polyRect(polygon.boundingRect());
+ _q_adjustRect(&polyRect);
+ QRectF r = !parentClip ? polyRect : polyRect.intersected(adjustedItemBoundingRect(parent));
if (r.isEmpty())
return;
@@ -1705,7 +1717,7 @@ void QGraphicsScenePrivate::childItems_helper(QList *items,
// ### _q_adjustedRect is only needed because QRectF::intersects,
// QRectF::contains and QTransform::map() and friends don't work with
// flat rectangles.
- QRectF br = _q_adjustedRect(item->boundingRect());
+ const QRectF br(adjustedItemBoundingRect(item));
if (mode >= Qt::ContainsItemBoundingRect) {
// Polygon contains/intersects item's bounding rect
if (path == QPainterPath())
@@ -1743,8 +1755,9 @@ void QGraphicsScenePrivate::childItems_helper(QList *items,
bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape);
if (parentClip && parent->d_ptr->isClippedAway())
return;
- QRectF pathRect = _q_adjustedRect(path.boundingRect());
- QRectF r = !parentClip ? pathRect : pathRect.intersected(_q_adjustedRect(parent->boundingRect()));
+ QRectF pathRect(path.boundingRect());
+ _q_adjustRect(&pathRect);
+ QRectF r = !parentClip ? pathRect : pathRect.intersected(adjustedItemBoundingRect(parent));
if (r.isEmpty())
return;
@@ -1763,7 +1776,7 @@ void QGraphicsScenePrivate::childItems_helper(QList *items,
// ### _q_adjustedRect is only needed because QRectF::intersects,
// QRectF::contains and QTransform::map() and friends don't work with
// flat rectangles.
- QRectF br = _q_adjustedRect(item->boundingRect());
+ const QRectF br(adjustedItemBoundingRect(item));
if (mode >= Qt::ContainsItemBoundingRect) {
// Polygon contains/intersects item's bounding rect
if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br)))
@@ -4690,7 +4703,9 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
// Item's (local) bounding rect
QRectF brect = item->boundingRect();
- if (_q_adjustedRect(brect).isEmpty())
+ QRectF adjustedBrect(brect);
+ _q_adjustRect(&adjustedBrect);
+ if (adjustedBrect.isEmpty())
return;
// Fetch the off-screen transparent buffer and exposed area info.
@@ -5232,9 +5247,12 @@ void QGraphicsScene::itemUpdated(QGraphicsItem *item, const QRectF &rect)
update(item->sceneBoundingRect());
} else {
// ### Remove _q_adjustedRects().
- QRectF boundingRect = _q_adjustedRect(item->boundingRect());
- if (!rect.isNull())
- boundingRect &= _q_adjustedRect(rect);
+ 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)
@@ -5264,7 +5282,9 @@ void QGraphicsScene::itemUpdated(QGraphicsItem *item, const QRectF &rect)
// defined scene rect.
if (!d->hasSceneRect) {
QRectF oldGrowingItemsBoundingRect = d->growingItemsBoundingRect;
- d->growingItemsBoundingRect |= _q_adjustedRect(item->sceneBoundingRect());
+ QRectF adjustedItemSceneBoundingRect(item->sceneBoundingRect());
+ _q_adjustRect(&adjustedItemSceneBoundingRect);
+ d->growingItemsBoundingRect |= adjustedItemSceneBoundingRect;
if (d->growingItemsBoundingRect != oldGrowingItemsBoundingRect)
emit sceneRectChanged(d->growingItemsBoundingRect);
}
--
cgit v0.12
From 3dc62362f3380fa653bc1225ce06e5e4cefa745a Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Fri, 3 Apr 2009 16:39:58 +0200
Subject: Fixes: We have to adjust the item's bounding rect.
RevBy: Andreas
AutoTest: Still pass
Details: QRectF::intersects does not work with flat rectangles, so
we cannot intersect the bounding rect without adjusting it
first.
---
src/gui/graphicsview/qgraphicsview.cpp | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index f0d360a..c4297df 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -790,6 +790,19 @@ QRegion QGraphicsViewPrivate::mapToViewRegion(const QGraphicsItem *item, const Q
return item->boundingRegion(itv) & itv.mapRect(rect).toAlignedRect();
}
+// QRectF::intersects() returns false always if either the source or target
+// rectangle's width or height are 0. This works around that problem.
+static inline QRectF adjustedItemBoundingRect(const QGraphicsItem *item)
+{
+ Q_ASSERT(item);
+ QRectF boundingRect(item->boundingRect());
+ if (!boundingRect.width())
+ boundingRect.adjust(-0.00001, 0, 0.00001, 0);
+ if (!boundingRect.height())
+ boundingRect.adjust(0, -0.00001, 0, 0.00001);
+ return boundingRect;
+}
+
/*!
\internal
*/
@@ -802,7 +815,7 @@ void QGraphicsViewPrivate::itemUpdated(QGraphicsItem *item, const QRectF &rect)
QRectF updateRect = rect;
if ((item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape) || item->d_ptr->children.isEmpty()) {
- updateRect &= item->boundingRect();
+ updateRect &= adjustedItemBoundingRect(item);
if (updateRect.isEmpty())
return;
}
@@ -814,7 +827,8 @@ void QGraphicsViewPrivate::itemUpdated(QGraphicsItem *item, const QRectF &rect)
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) & parent->boundingRect();
+ updateRect = clipItem->itemTransform(parent).mapRect(updateRect)
+ & adjustedItemBoundingRect(parent);
if (updateRect.isEmpty())
return;
clipItem = parent;
--
cgit v0.12
From 416fd77e653d089b7832002a68d5b7725fa492db Mon Sep 17 00:00:00 2001
From: Bjoern Erik Nilsen
Date: Fri, 3 Apr 2009 16:52:10 +0200
Subject: Fixes: Wrong adjustment of rect added in
0aa2ef27249dc8e782c2942340776bb19de80a0d
RevBy: TrustMe
AutoTest: tst_QGraphicsItem::boundingRegion() pass again
Details: The original code adjusted the QRect version of a mapped bounding rect,
wheras my patch adjusted a mapped bounding rect (QRectF) and then
converted it to a QRect.
---
src/gui/graphicsview/qgraphicsitem.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 8478561..9d320b7 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -3488,9 +3488,8 @@ QRegion QGraphicsItem::boundingRegion(const QTransform &itemToDeviceTransform) c
// into the bitmap, converts the result to a QRegion and scales the region
// back to device space with inverse granularity.
qreal granularity = boundingRegionGranularity();
- QRectF adjustedMappedBoundingRect(itemToDeviceTransform.mapRect(boundingRect()));
- _q_adjustRect(&adjustedMappedBoundingRect);
- QRect deviceRect = adjustedMappedBoundingRect.toRect();
+ QRect deviceRect = itemToDeviceTransform.mapRect(boundingRect()).toRect();
+ _q_adjustRect(&deviceRect);
if (granularity == 0.0)
return QRegion(deviceRect);
--
cgit v0.12
From cc18633fe45d599bfeac2a8b2737d155f1dd5564 Mon Sep 17 00:00:00 2001
From: Andreas Aardal Hanssen
Date: Mon, 6 Apr 2009 13:31:02 +0200
Subject: Fixup update rect regression by adjusting expose rectangles.
This change shows a limitation in Graphics View caused by QPen's
default width being 0 (cosmetic), while Graphics View actually
does not support cosmetic pens at all. Because items are at risk of
drawing lines that poke 1 pixel outside their bounding rect,
QGraphicsView must look for items that are up to one pixel
larger than their bounding rect mapped to viewport coordinates.
Furthermore, mapToScene(QRect) forces us to adjust the
input rectangle by (0, 0, 1, 1), because it uses QRect::bottomRight()
(etc) when mapping the rectangle to a polygon (which is _wrong_). Since
this behavior has been there since 4.2, we don't want to fix it in
a 4.5 patch release...
The only _proper_ fix to this problem is for the view to know the item's
"adjust" in device coordinates, allowing items to use cosmetic pens
freely. Fex, we could introduce QGraphicsItem::viewportMargins() or so.
Added an autotest to ensure this doesn't break again.
Reviewed-by: bnilsen
---
src/gui/graphicsview/qgraphicsview.cpp | 42 ++++++++++++++----
tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 61 ++++++++++++++++++++++++++
2 files changed, 95 insertions(+), 8 deletions(-)
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index c4297df..418638f 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -1046,13 +1046,24 @@ void QGraphicsViewPrivate::freeStyleOptionsArray(QStyleOptionGraphicsItem *array
extern QPainterPath qt_regionToPath(const QRegion ®ion);
+/*!
+ ### Adjustments in findItems: mapToScene(QRect) forces us to adjust the
+ input rectangle by (0, 0, 1, 1), because it uses QRect::bottomRight()
+ (etc) when mapping the rectangle to a polygon (which is _wrong_). In
+ addition, as QGraphicsItem::boundingRect() is defined in logical space,
+ but the default pen for QPainter is cosmetic with a width of 0, QPainter
+ is at risk of painting 1 pixel outside the bounding rect. Therefore we
+ must search for items with an adjustment of (-1, -1, 1, 1).
+*/
QList QGraphicsViewPrivate::findItems(const QRegion &exposedRegion, bool *allItems) const
{
Q_Q(const QGraphicsView);
- const QPainterPath exposedPath(qt_regionToPath(exposedRegion));
- const QPainterPath exposedScenePath(q->mapToScene(exposedPath));
- if (exposedScenePath.contains(scene->d_func()->growingItemsBoundingRect)) {
+ // Step 1) If all items are contained within the expose region, then
+ // return a list of all visible items.
+ const QRectF exposedRegionSceneBounds = q->mapToScene(exposedRegion.boundingRect().adjusted(-1, -1, 2, 2))
+ .boundingRect();
+ if (exposedRegionSceneBounds.contains(scene->d_func()->growingItemsBoundingRect)) {
Q_ASSERT(allItems);
*allItems = true;
@@ -1072,12 +1083,27 @@ QList QGraphicsViewPrivate::findItems(const QRegion &exposedReg
return itemList;
}
+ // Step 2) If the expose region is a simple rect and the view is only
+ // translated or scaled, search for items using
+ // QGraphicsScene::items(QRectF).
+ bool simpleRectLookup = (scene->d_func()->largestUntransformableItem.isNull()
+ && exposedRegion.numRects() == 1 && matrix.type() <= QTransform::TxScale);
+ if (simpleRectLookup) {
+ return scene->d_func()->items_helper(exposedRegionSceneBounds,
+ Qt::IntersectsItemBoundingRect,
+ Qt::DescendingOrder);
+ }
+
+ // If the region is complex or the view has a complex transform, adjust
+ // the expose region, convert it to a path, and then search for items
+ // using QGraphicsScene::items(QPainterPath);
+ QRegion adjustedRegion;
+ foreach (const QRect &r, exposedRegion.rects())
+ adjustedRegion += r.adjusted(-1, -1, 1, 1);
+
+ const QPainterPath exposedPath(qt_regionToPath(adjustedRegion));
if (scene->d_func()->largestUntransformableItem.isNull()) {
- if (exposedRegion.numRects() == 1 && matrix.type() <= QTransform::TxScale) {
- return scene->d_func()->items_helper(exposedScenePath.controlPointRect(),
- Qt::IntersectsItemBoundingRect,
- Qt::DescendingOrder);
- }
+ const QPainterPath exposedScenePath(q->mapToScene(exposedPath));
return scene->d_func()->items_helper(exposedScenePath,
Qt::IntersectsItemBoundingRect,
Qt::DescendingOrder);
diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp
index 4368e76..412c6c5 100644
--- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp
+++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp
@@ -155,6 +155,8 @@ private slots:
void fitInView();
void itemsAtPoint();
void itemsInRect();
+ void itemsInRect_cosmeticAdjust_data();
+ void itemsInRect_cosmeticAdjust();
void itemsInPoly();
void itemsInPath();
void itemAt();
@@ -1310,6 +1312,65 @@ void tst_QGraphicsView::itemsInRect()
QCOMPARE(items.takeFirst()->zValue(), qreal(3));
}
+class CountPaintItem : public QGraphicsRectItem
+{
+public:
+ int numPaints;
+
+ CountPaintItem(const QRectF &rect)
+ : QGraphicsRectItem(rect), numPaints(0)
+ { }
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0)
+ {
+ ++numPaints;
+ QGraphicsRectItem::paint(painter, option, widget);
+ }
+};
+
+void tst_QGraphicsView::itemsInRect_cosmeticAdjust_data()
+{
+ QTest::addColumn("updateRect");
+ QTest::addColumn("numPaints");
+
+ QTest::newRow("nil") << QRect() << 1;
+ QTest::newRow("0, 0, 300, 100") << QRect(0, 0, 300, 100) << 1;
+ QTest::newRow("0, 0, 100, 300") << QRect(0, 0, 100, 300) << 1;
+ QTest::newRow("200, 0, 100, 300") << QRect(200, 0, 100, 300) << 1;
+ QTest::newRow("0, 200, 300, 100") << QRect(0, 200, 300, 100) << 1;
+ QTest::newRow("0, 0, 300, 99") << QRect(0, 0, 300, 99) << 0;
+ QTest::newRow("0, 0, 99, 300") << QRect(0, 0, 99, 300) << 0;
+ QTest::newRow("201, 0, 99, 300") << QRect(201, 0, 99, 300) << 0;
+ QTest::newRow("0, 201, 300, 99") << QRect(0, 201, 300, 99) << 0;
+}
+
+void tst_QGraphicsView::itemsInRect_cosmeticAdjust()
+{
+ QFETCH(QRect, updateRect);
+ QFETCH(int, numPaints);
+
+ QGraphicsScene scene(-100, -100, 200, 200);
+ CountPaintItem *rect = new CountPaintItem(QRectF(-50, -50, 100, 100));
+ scene.addItem(rect);
+
+ QGraphicsView view(&scene);
+ view.setFrameStyle(0);
+ view.resize(300, 300);
+ view.show();
+#ifdef Q_WS_X11
+ qt_x11_wait_for_window_manager(&view);
+#endif
+ QTest::qWait(125);
+
+ rect->numPaints = 0;
+ if (updateRect.isNull())
+ view.viewport()->update();
+ else
+ view.viewport()->update(updateRect);
+ qApp->processEvents();
+ QCOMPARE(rect->numPaints, numPaints);
+}
+
void tst_QGraphicsView::itemsInPoly()
{
QGraphicsScene scene;
--
cgit v0.12
From f06c4f2d7378b40a0a184393a8986032d5a700ee Mon Sep 17 00:00:00 2001
From: Jens Bache-Wiig
Date: Mon, 6 Apr 2009 14:17:15 +0200
Subject: BT: Fix combobox background color regression There was a regression
in the background color for QComboBox popups. This should resolve it. It
essentially tells the system to stay off the system palette while QGtkStyle
is used. We will introduce a cleaner style hint for this in 4.6.
Reviewed-by: nrc
---
src/gui/kernel/qapplication_x11.cpp | 6 ++++--
src/gui/styles/gtksymbols.cpp | 8 +-------
2 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
index 10fb886..b1270bc 100644
--- a/src/gui/kernel/qapplication_x11.cpp
+++ b/src/gui/kernel/qapplication_x11.cpp
@@ -1362,8 +1362,10 @@ static void qt_set_x11_resources(const char* font = 0, const char* fg = 0,
pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::darkBlue);
}
- QApplicationPrivate::setSystemPalette(pal);
-
+ // QGtkStyle sets it's own system palette
+ if (!(QApplicationPrivate::app_style && QApplicationPrivate::app_style->inherits("QGtkStyle"))) {
+ QApplicationPrivate::setSystemPalette(pal);
+ }
QColor::setAllowX11ColorNames(allowX11ColorNames);
}
diff --git a/src/gui/styles/gtksymbols.cpp b/src/gui/styles/gtksymbols.cpp
index 8123d32..f7af8f8 100644
--- a/src/gui/styles/gtksymbols.cpp
+++ b/src/gui/styles/gtksymbols.cpp
@@ -504,13 +504,6 @@ static QPalette gtkWidgetPalette(const QString >kWidgetName)
pal.setBrush(QPalette::Disabled, QPalette::WindowText, disabledTextColor);
pal.setBrush(QPalette::All, QPalette::ButtonText, textColor);
pal.setBrush(QPalette::Disabled, QPalette::ButtonText, disabledTextColor);
- if (gtkWidgetName == QLS("GtkMenu")) {
- // This really applies to the combo box rendering since
- // QComboBox copies the palette from a QMenu
- GdkColor gdkBg = gtkWidget->style->bg[GTK_STATE_NORMAL];
- QColor bgColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8);
- pal.setBrush(QPalette::Base, bgColor);
- }
return pal;
}
@@ -528,6 +521,7 @@ void QGtk::applyCustomPaletteHash()
GdkColor gdkBg = QGtk::gtkWidget(QLS("GtkMenu"))->style->bg[GTK_STATE_NORMAL];
QColor bgColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8);
menuPal.setBrush(QPalette::Base, bgColor);
+ menuPal.setBrush(QPalette::Window, bgColor);
qApp->setPalette(menuPal, "QMenu");
QPalette toolbarPal = gtkWidgetPalette(QLS("GtkToolbar"));
--
cgit v0.12
From b8dcae1572651774085024ddf4cb02e4a954bcd7 Mon Sep 17 00:00:00 2001
From: Maurice Kalinowski
Date: Mon, 6 Apr 2009 14:29:02 +0200
Subject: compile for systems without Qt3Support
Reviewed-by: joerg
QTest::newRow only accepts char* and without Qt3Support there is no implicit cast available.
---
tests/auto/qpainter/tst_qpainter.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp
index a4c768d..fb8df2e 100644
--- a/tests/auto/qpainter/tst_qpainter.cpp
+++ b/tests/auto/qpainter/tst_qpainter.cpp
@@ -3629,7 +3629,7 @@ void tst_QPainter::drawImage_data()
QString("srcFormat %1, dstFormat %2, odd x: %3, odd width: %4")
.arg(srcFormat).arg(dstFormat).arg(odd_x).arg(odd_width);
- QTest::newRow(description) << (10 + odd_x) << 10 << (20 + odd_width) << 20
+ QTest::newRow(qPrintable(description)) << (10 + odd_x) << 10 << (20 + odd_width) << 20
<< QImage::Format(srcFormat)
<< QImage::Format(dstFormat);
}
--
cgit v0.12
From 6ce4a3b66e2b31f80d1a2d09a4c4087f88a7a9e8 Mon Sep 17 00:00:00 2001
From: Maurice Kalinowski
Date: Mon, 6 Apr 2009 14:42:31 +0200
Subject: remove dead code
Reviewed-by: jbache
---
tests/auto/qmenubar/tst_qmenubar.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/tests/auto/qmenubar/tst_qmenubar.cpp b/tests/auto/qmenubar/tst_qmenubar.cpp
index 277e15c..e0a9f42 100644
--- a/tests/auto/qmenubar/tst_qmenubar.cpp
+++ b/tests/auto/qmenubar/tst_qmenubar.cpp
@@ -1337,7 +1337,6 @@ tst_QMenuBar::allowActiveAndDisabled()
// disabled menu items are added
QMenu fileMenu("&File");
- QAction disabledAction() ;
// Task 241043 : check that second menu is activated
// if all items are disabled
QAction *act = fileMenu.addAction("Disabled");
--
cgit v0.12
From e517ecc9025b68179c67a383791eefbedfee0543 Mon Sep 17 00:00:00 2001
From: Maurice Kalinowski
Date: Mon, 6 Apr 2009 15:07:58 +0200
S