summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBradley T. Hughes <bradley.hughes@nokia.com>2009-06-18 11:33:26 (GMT)
committerBradley T. Hughes <bradley.hughes@nokia.com>2009-06-18 11:33:26 (GMT)
commite6e60b096bb8b5e5073e32220c74810e80bf2d25 (patch)
treeca247002a4193d0deeee3b4be369e830c7b4f778 /src
parent5a350be913139e2b994878c62ce06eb88604abbe (diff)
parentc23d4d6644bff2195fbb6aa84d3425dc2d31491a (diff)
downloadQt-e6e60b096bb8b5e5073e32220c74810e80bf2d25.zip
Qt-e6e60b096bb8b5e5073e32220c74810e80bf2d25.tar.gz
Qt-e6e60b096bb8b5e5073e32220c74810e80bf2d25.tar.bz2
Merge branch 'master' of git@scm.dev.nokia.troll.no:qt/qt
Conflicts: src/gui/graphicsview/qgraphicsitem_p.h
Diffstat (limited to 'src')
-rw-r--r--src/corelib/io/qiodevice.cpp4
-rw-r--r--src/corelib/tools/qstring.cpp68
-rw-r--r--src/corelib/tools/qstringbuilder.cpp2
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h26
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp112
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h5
-rw-r--r--src/gui/graphicsview/qgraphicsview.cpp61
-rw-r--r--src/gui/graphicsview/qgraphicsview_p.h4
-rw-r--r--src/gui/itemviews/qlistview.cpp2
-rw-r--r--src/gui/kernel/qapplication_x11.cpp128
-rw-r--r--src/gui/widgets/qmenubar.cpp3
-rw-r--r--src/network/access/qnetworkaccesscache_p.h3
-rw-r--r--src/network/access/qnetworkaccessftpbackend.cpp18
-rw-r--r--src/network/access/qnetworkaccessftpbackend_p.h4
-rw-r--r--src/network/access/qnetworkaccesshttpbackend.cpp20
-rw-r--r--src/network/access/qnetworkaccesshttpbackend_p.h4
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp24
-rw-r--r--src/network/access/qnetworkaccessmanager_p.h12
-rw-r--r--src/network/socket/qabstractsocket.cpp4
-rw-r--r--src/network/ssl/qsslcertificate.cpp7
-rw-r--r--src/opengl/qpaintengine_opengl.cpp23
-rw-r--r--src/opengl/qpaintengine_opengl_p.h1
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp10
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp25
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp7
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbscreen.h1
-rw-r--r--src/scripttools/debugging/qscriptdebugger.cpp10
-rw-r--r--src/scripttools/debugging/qscriptdebugger_p.h2
-rw-r--r--src/scripttools/debugging/qscriptdebuggerbackend.cpp43
-rw-r--r--src/scripttools/debugging/qscriptdebuggerbackend_p_p.h6
-rw-r--r--src/scripttools/debugging/qscriptenginedebugger.cpp26
-rw-r--r--src/scripttools/debugging/qscriptenginedebugger.h7
32 files changed, 447 insertions, 225 deletions
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index d3fa6a8..2977c7f 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -1454,11 +1454,11 @@ QByteArray QIODevice::peek(qint64 maxSize)
}
/*!
- Blocks until data is available for reading and the readyRead()
+ Blocks until new data is available for reading and the readyRead()
signal has been emitted, or until \a msecs milliseconds have
passed. If msecs is -1, this function will not time out.
- Returns true if data is available for reading; otherwise returns
+ Returns true if new data is available for reading; otherwise returns
false (if the operation timed out or if an error occurred).
This function can operate without an event loop. It is
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index ced6dd5..3b70f44 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -663,6 +663,74 @@ const QString::Null QString::null = { };
formats, the \e precision represents the maximum number of
significant digits (trailing zeroes are omitted).
+ \section1 More Efficient String Construction
+
+ Using the QString \c{'+'} operator, it is easy to construct a
+ complex string from multiple substrings. You will often write code
+ like this:
+
+ \snippet doc/src/snippets/qstring/stringbuilder.cpp 0
+
+ There is nothing wrong with either of these string constructions,
+ but there are a few hidden inefficiencies. Beginning with Qt 4.6,
+ you can eliminate them.
+
+ First, multiple uses of the \c{'+'} operator usually means
+ multiple memory allocations. When concatenating \e{n} substrings,
+ where \e{n > 2}, there can be as many as \e{n - 1} calls to the
+ memory allocator.
+
+ Second, QLatin1String does not store its length internally but
+ calls qstrlen() when it needs to know its length.
+
+ In 4.6, an internal template class \c{QStringBuilder} has been
+ added along with a few helper functions. This class is marked
+ internal and does not appear in the documentation, because you
+ aren't meant to instantiate it in your code. Its use will be
+ automatic, as described below. The class is found in
+ \c {src/corelib/tools/qstringbuilder.cpp} if you want to have a
+ look at it.
+
+ \c{QStringBuilder} uses expression templates and reimplements the
+ \c{'%'} operator so that when you use \c{'%'} for string
+ concatenation instead of \c{'+'}, multiple substring
+ concatenations will be postponed until the final result is about
+ to be assigned to a QString. At this point, the amount of memory
+ required for the final result is known. The memory allocator is
+ then called \e{once} to get the required space, and the substrings
+ are copied into it one by one.
+
+ \c{QLatin1Literal} is a second internal class that can replace
+ QLatin1String, which can't be changed for compatibility reasons.
+ \c{QLatin1Literal} stores its length, thereby saving time when
+ \c{QStringBuilder} computes the amount of memory required for the
+ final string.
+
+ Additional efficiency is gained by inlining and reduced reference
+ counting (the QString created from a \c{QStringBuilder} typically
+ has a ref count of 1, whereas QString::append() needs an extra
+ test).
+
+ There are three ways you can access this improved method of string
+ construction. The straightforward way is to include
+ \c{QStringBuilder} wherever you want to use it, and use the
+ \c{'%'} operator instead of \c{'+'} when concatenating strings:
+
+ \snippet doc/src/snippets/qstring/stringbuilder.cpp 5
+
+ A more global approach is to include this define:
+
+ \snippet doc/src/snippets/qstring/stringbuilder.cpp 3
+
+ and use \c{'%'} instead of \c{'+'} for string concatenation
+ everywhere. The third approach, which is the most convenient but
+ not entirely source compatible, is to include two defines:
+
+ \snippet doc/src/snippets/qstring/stringbuilder.cpp 4
+
+ and the \c{'+'} will automatically be performed as the
+ \c{QStringBuilder} \c{'%'} everywhere.
+
\sa fromRawData(), QChar, QLatin1String, QByteArray, QStringRef
*/
diff --git a/src/corelib/tools/qstringbuilder.cpp b/src/corelib/tools/qstringbuilder.cpp
index 17e2cec..fbb784e 100644
--- a/src/corelib/tools/qstringbuilder.cpp
+++ b/src/corelib/tools/qstringbuilder.cpp
@@ -43,6 +43,7 @@
/*!
\class QLatin1Literal
+ \internal
\reentrant
\since 4.6
@@ -83,6 +84,7 @@
/*!
\class QStringBuilder
+ \internal
\reentrant
\since 4.6
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index 688130b..a0d061b 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -56,6 +56,7 @@
#include "qgraphicsitem.h"
#include "qset.h"
#include "qpixmapcache.h"
+#include "qgraphicsview_p.h"
#include <QtCore/qpoint.h>
@@ -158,6 +159,8 @@ public:
geometryChanged(0),
inDestructor(0),
isObject(0),
+ ignoreVisible(0),
+ ignoreOpacity(0),
acceptTouchEvents(0),
acceptedTouchBeginEvent(0),
globalStackingOrder(-1),
@@ -181,7 +184,7 @@ public:
void combineTransformToParent(QTransform *x, const QTransform *viewTransform = 0) const;
void combineTransformFromParent(QTransform *x, const QTransform *viewTransform = 0) const;
-
+
// ### Qt 5: Remove. Workaround for reimplementation added after Qt 4.4.
virtual QVariant inputMethodQueryHelper(Qt::InputMethodQuery query) const;
static bool movableAncestorIsSelected(const QGraphicsItem *item);
@@ -250,7 +253,7 @@ public:
}
}
}
-
+
struct ExtraStruct {
ExtraStruct(Extra type, QVariant value)
: type(type), value(value)
@@ -262,7 +265,7 @@ public:
bool operator<(Extra extra) const
{ return type < extra; }
};
-
+
QList<ExtraStruct> extras;
QGraphicsItemCache *maybeExtraItemCache() const;
@@ -337,6 +340,15 @@ public:
return calcEffectiveOpacity();
}
+ inline qreal combineOpacityFromParent(qreal parentOpacity) const
+ {
+ if (parent && !(flags & QGraphicsItem::ItemIgnoresParentOpacity)
+ && !(parent->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) {
+ return parentOpacity * opacity;
+ }
+ return opacity;
+ }
+
inline bool childrenCombineOpacity() const
{
if (!children.size())
@@ -423,8 +435,8 @@ public:
quint32 cacheMode : 2;
quint32 hasBoundingRegionGranularity : 1;
quint32 isWidget : 1;
- quint32 dirty : 1;
- quint32 dirtyChildren : 1;
+ quint32 dirty : 1;
+ quint32 dirtyChildren : 1;
quint32 localCollisionHack : 1;
quint32 dirtyClipPath : 1;
quint32 emptyClipPath : 1;
@@ -441,9 +453,11 @@ public:
quint32 geometryChanged : 1;
quint32 inDestructor : 1;
quint32 isObject : 1;
+ quint32 ignoreVisible : 1;
+ quint32 ignoreOpacity : 1;
quint32 acceptTouchEvents : 1;
quint32 acceptedTouchBeginEvent : 1;
- quint32 unused : 12; // feel free to use
+ quint32 unused : 10; // feel free to use
// Optional stacking order
int globalStackingOrder;
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 13b1b5a..7428d79 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -5180,14 +5180,7 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
if (item) {
if (!item->d_ptr->visible)
return;
- QGraphicsItem *p = item->d_ptr->parent;
- bool itemIgnoresParentOpacity = item->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity;
- bool parentDoesntPropagateOpacity = (p && (p->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren));
- if (!itemIgnoresParentOpacity && !parentDoesntPropagateOpacity) {
- opacity = parentOpacity * item->opacity();
- } else {
- opacity = item->d_ptr->opacity;
- }
+ opacity = item->d_ptr->combineOpacityFromParent(parentOpacity);
if (opacity == 0.0 && !(item->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) {
invisibleButChildIgnoresParentOpacity = !item->d_ptr->childrenCombineOpacity();
if (!invisibleButChildIgnoresParentOpacity)
@@ -5337,7 +5330,11 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
if (clipsToShape)
painter->setClipPath(item->shape(), Qt::IntersectClip);
painter->setOpacity(opacity);
- drawItemHelper(item, painter, &styleOptionTmp, widget, painterStateProtection);
+
+ if (!item->d_ptr->cacheMode && !item->d_ptr->isWidget)
+ item->paint(painter, &styleOptionTmp, widget);
+ else
+ drawItemHelper(item, painter, &styleOptionTmp, widget, painterStateProtection);
if (savePainter)
painter->restore();
@@ -5421,6 +5418,11 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b
item->d_ptr->dirtyChildren = 1;
}
+ if (force)
+ item->d_ptr->ignoreVisible = 1;
+ if (ignoreOpacity)
+ item->d_ptr->ignoreOpacity = 1;
+
QGraphicsItem *p = item->d_ptr->parent;
while (p && !p->d_ptr->dirtyChildren) {
p->d_ptr->dirtyChildren = 1;
@@ -5428,34 +5430,58 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b
}
}
-void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren)
+static inline bool updateHelper(QGraphicsViewPrivate *view, QGraphicsItemPrivate *item,
+ const QRectF &rect, const QTransform &xform)
+{
+ Q_ASSERT(view);
+ Q_ASSERT(item);
+ if (item->hasBoundingRegionGranularity)
+ return view->updateRegion(xform.map(QRegion(rect.toRect())));
+ return view->updateRect(xform.mapRect(rect).toRect());
+}
+
+void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren,
+ qreal parentOpacity)
{
Q_Q(QGraphicsScene);
- // Calculate the full scene transform for this item.
+ bool wasDirtyParentViewBoundingRects = false;
bool wasDirtyParentSceneTransform = false;
- if (item && item->d_ptr->dirtySceneTransform && !item->d_ptr->itemIsUntransformable()) {
- item->d_ptr->sceneTransform = item->d_ptr->parent ? item->d_ptr->parent->d_ptr->sceneTransform
- : QTransform();
- item->d_ptr->combineTransformFromParent(&item->d_ptr->sceneTransform);
- item->d_ptr->dirtySceneTransform = 0;
- wasDirtyParentSceneTransform = true;
+ qreal opacity = parentOpacity;
+
+ if (item) {
+ wasDirtyParentViewBoundingRects = item->d_ptr->paintedViewBoundingRectsNeedRepaint;
+ opacity = item->d_ptr->combineOpacityFromParent(parentOpacity);
+ const bool itemIsHidden = !item->d_ptr->ignoreVisible && !item->d_ptr->visible;
+ const bool itemIsFullyTransparent = !item->d_ptr->ignoreOpacity && opacity == 0.0;
+
+ if (item->d_ptr->dirtySceneTransform && !itemIsHidden && !item->d_ptr->itemIsUntransformable()
+ && !(itemIsFullyTransparent && item->d_ptr->childrenCombineOpacity())) {
+ // Calculate the full scene transform for this item.
+ item->d_ptr->sceneTransform = item->d_ptr->parent ? item->d_ptr->parent->d_ptr->sceneTransform
+ : QTransform();
+ item->d_ptr->combineTransformFromParent(&item->d_ptr->sceneTransform);
+ item->d_ptr->dirtySceneTransform = 0;
+ wasDirtyParentSceneTransform = true;
+ }
+
+ if (itemIsHidden || itemIsFullyTransparent || (item->d_ptr->flags & QGraphicsItem::ItemHasNoContents)) {
+ // Make sure we don't process invisible items or items with no content.
+ item->d_ptr->dirty = 0;
+ item->d_ptr->paintedViewBoundingRectsNeedRepaint = 0;
+ }
}
// Process item.
- bool wasDirtyParentViewBoundingRects = false;
if (item && (item->d_ptr->dirty || item->d_ptr->paintedViewBoundingRectsNeedRepaint)) {
const bool useCompatUpdate = views.isEmpty() || (connectedSignals & changedSignalMask);
const bool untransformableItem = item->d_ptr->itemIsUntransformable();
- const QRectF itemBoundingRect = item->boundingRect();
+ const QRectF itemBoundingRect = adjustedItemBoundingRect(item);
if (item->d_ptr->geometryChanged) {
// Update growingItemsBoundingRect.
- if (!hasSceneRect) {
- QRectF itemSceneBoundingRect = item->d_ptr->sceneTransform.mapRect(itemBoundingRect);
- _q_adjustRect(&itemSceneBoundingRect);
- growingItemsBoundingRect |= itemSceneBoundingRect;
- }
+ if (!hasSceneRect)
+ growingItemsBoundingRect |= item->d_ptr->sceneTransform.mapRect(itemBoundingRect);
item->d_ptr->geometryChanged = 0;
}
@@ -5484,11 +5510,12 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool
break;
}
+ QRect &paintedViewBoundingRect = item->d_ptr->paintedViewBoundingRects[viewPrivate->viewport];
if (item->d_ptr->paintedViewBoundingRectsNeedRepaint) {
wasDirtyParentViewBoundingRects = true;
- QRect rect = item->d_ptr->paintedViewBoundingRects.value(viewPrivate->viewport);
- rect.translate(viewPrivate->dirtyScrollOffset);
- viewPrivate->updateRect(rect);
+ paintedViewBoundingRect.translate(viewPrivate->dirtyScrollOffset);
+ if (!viewPrivate->updateRect(paintedViewBoundingRect))
+ paintedViewBoundingRect = QRect();
}
if (!item->d_ptr->dirty)
@@ -5496,7 +5523,6 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool
if (uninitializedDirtyRect) {
dirtyRect = itemBoundingRect;
- _q_adjustRect(&dirtyRect);
if (!item->d_ptr->fullUpdatePending) {
_q_adjustRect(&item->d_ptr->needsRepaint);
dirtyRect &= item->d_ptr->needsRepaint;
@@ -5507,17 +5533,19 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool
if (dirtyRect.isEmpty())
continue; // Discard updates outside the bounding rect.
- QTransform deviceTransform = item->d_ptr->sceneTransform;
- if (view->isTransformed()) {
- if (!untransformableItem)
- deviceTransform *= view->viewportTransform();
- else
- deviceTransform = item->deviceTransform(view->viewportTransform());
+ bool valid = false;
+ if (untransformableItem) {
+ valid = updateHelper(viewPrivate, item->d_ptr, dirtyRect,
+ item->deviceTransform(view->viewportTransform()));
+ } else if (!view->isTransformed()) {
+ valid = updateHelper(viewPrivate, item->d_ptr, dirtyRect, item->d_ptr->sceneTransform);
+ } else {
+ QTransform deviceTransform = item->d_ptr->sceneTransform;
+ deviceTransform *= view->viewportTransform();
+ valid = updateHelper(viewPrivate, item->d_ptr, dirtyRect, deviceTransform);
}
- if (item->d_ptr->hasBoundingRegionGranularity)
- viewPrivate->updateRegion(deviceTransform.map(QRegion(dirtyRect.toRect())));
- else
- viewPrivate->updateRect(deviceTransform.mapRect(dirtyRect).toRect());
+ if (!valid)
+ paintedViewBoundingRect = QRect();
}
}
}
@@ -5530,12 +5558,18 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool
dirtyAncestorContainsChildren = item && item->d_ptr->fullUpdatePending
&& (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape);
}
+ const bool parentIgnoresVisible = item && item->d_ptr->ignoreVisible;
+ const bool parentIgnoresOpacity = item && item->d_ptr->ignoreOpacity;
for (int i = 0; i < children->size(); ++i) {
QGraphicsItem *child = children->at(i);
if (wasDirtyParentSceneTransform)
child->d_ptr->dirtySceneTransform = 1;
if (wasDirtyParentViewBoundingRects)
child->d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
+ if (parentIgnoresVisible)
+ child->d_ptr->ignoreVisible = 1;
+ if (parentIgnoresOpacity)
+ child->d_ptr->ignoreOpacity = 1;
if (allChildrenDirty) {
child->d_ptr->dirty = 1;
@@ -5558,7 +5592,7 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool
child->d_ptr->paintedViewBoundingRectsNeedRepaint = 0;
}
- processDirtyItemsRecursive(child, dirtyAncestorContainsChildren);
+ processDirtyItemsRecursive(child, dirtyAncestorContainsChildren, opacity);
}
} else if (wasDirtyParentSceneTransform) {
item->d_ptr->invalidateChildrenSceneTransform();
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
index b3f168c..983486f 100644
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_p.h
@@ -271,7 +271,8 @@ public:
void markDirty(QGraphicsItem *item, const QRectF &rect = QRectF(), bool invalidateChildren = false,
bool maybeDirtyClipPath = false, bool force = false, bool ignoreOpacity = false,
bool removingItemFromScene = false);
- void processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren = false);
+ void processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren = false,
+ qreal parentOpacity = qreal(1.0));
inline void resetDirtyItem(QGraphicsItem *item)
{
@@ -283,6 +284,8 @@ public:
item->d_ptr->needsRepaint = QRectF();
item->d_ptr->allChildrenDirty = 0;
item->d_ptr->fullUpdatePending = 0;
+ item->d_ptr->ignoreVisible = 0;
+ item->d_ptr->ignoreOpacity = 0;
}
QStyle *style;
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index 47a492b..6ac2914 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -846,19 +846,22 @@ void QGraphicsViewPrivate::processPendingUpdates()
dirtyRegion = QRegion();
}
-void QGraphicsViewPrivate::updateRegion(const QRegion &r)
+bool QGraphicsViewPrivate::updateRegion(const QRegion &r)
{
- if (r.isEmpty() || fullUpdatePending)
- return;
+ if (fullUpdatePending || viewportUpdateMode == QGraphicsView::NoViewportUpdate || r.isEmpty())
+ return false;
+
+ const QRect boundingRect = r.boundingRect();
+ if (!boundingRect.intersects(viewport->rect()))
+ return false; // Update region outside viewport.
- // Rect intersects viewport - update everything?
switch (viewportUpdateMode) {
case QGraphicsView::FullViewportUpdate:
fullUpdatePending = true;
viewport->update();
break;
case QGraphicsView::BoundingRectViewportUpdate:
- dirtyBoundingRect |= r.boundingRect();
+ dirtyBoundingRect |= boundingRect;
if (dirtyBoundingRect.contains(viewport->rect())) {
fullUpdatePending = true;
viewport->update();
@@ -876,18 +879,20 @@ void QGraphicsViewPrivate::updateRegion(const QRegion &r)
}
break;
}
- case QGraphicsView::NoViewportUpdate:
- // Unreachable
+ default:
break;
}
+
+ return true;
}
-void QGraphicsViewPrivate::updateRect(const QRect &r)
+bool QGraphicsViewPrivate::updateRect(const QRect &r)
{
- if (r.isEmpty() || fullUpdatePending)
- return;
+ if (fullUpdatePending || viewportUpdateMode == QGraphicsView::NoViewportUpdate
+ || !r.intersects(viewport->rect())) {
+ return false;
+ }
- // Rect intersects viewport - update everything?
switch (viewportUpdateMode) {
case QGraphicsView::FullViewportUpdate:
fullUpdatePending = true;
@@ -907,10 +912,11 @@ void QGraphicsViewPrivate::updateRect(const QRect &r)
else
dirtyRegion += r.adjusted(-2, -2, 2, 2);
break;
- case QGraphicsView::NoViewportUpdate:
- // Unreachable
+ default:
break;
}
+
+ return true;
}
QStyleOptionGraphicsItem *QGraphicsViewPrivate::allocStyleOptionsArray(int numItems)
@@ -3288,10 +3294,6 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
// Determine the exposed region
d->exposedRegion = event->region();
- if (!d->accelerateScrolling)
- d->exposedRegion = viewport()->rect();
- else if (d->viewportUpdateMode == BoundingRectViewportUpdate)
- d->exposedRegion = event->rect();
QRectF exposedSceneRect = mapToScene(d->exposedRegion.boundingRect()).boundingRect();
// Set up the painter
@@ -3305,8 +3307,10 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
painter.setRenderHints(d->renderHints, true);
// Set up viewport transform
- const QTransform viewTransform = viewportTransform();
- painter.setWorldTransform(viewTransform);
+ const bool viewTransformed = isTransformed();
+ if (viewTransformed)
+ painter.setWorldTransform(viewportTransform());
+ const QTransform viewTransform = painter.worldTransform();
// Draw background
if ((d->cacheMode & CacheBackground)
@@ -3331,16 +3335,21 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
if (!d->backgroundPixmapExposed.isEmpty()) {
QPainter backgroundPainter(&d->backgroundPixmap);
backgroundPainter.setClipRegion(d->backgroundPixmapExposed, Qt::ReplaceClip);
- backgroundPainter.setTransform(viewportTransform());
+ if (viewTransformed)
+ backgroundPainter.setTransform(viewTransform);
backgroundPainter.setCompositionMode(QPainter::CompositionMode_Source);
drawBackground(&backgroundPainter, exposedSceneRect);
d->backgroundPixmapExposed = QRegion();
}
// Blit the background from the background pixmap
- painter.setWorldTransform(QTransform());
- painter.drawPixmap(QPoint(), d->backgroundPixmap);
- painter.setWorldTransform(viewTransform);
+ if (viewTransformed) {
+ painter.setWorldTransform(QTransform());
+ painter.drawPixmap(QPoint(), d->backgroundPixmap);
+ painter.setWorldTransform(viewTransform);
+ } else {
+ painter.drawPixmap(QPoint(), d->backgroundPixmap);
+ }
} else {
if (!(d->optimizationFlags & DontSavePainterState))
painter.save();
@@ -3363,8 +3372,10 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
const int numItems = itemList.size();
QGraphicsItem **itemArray = &itemList[0]; // Relies on QList internals, but is perfectly valid.
QStyleOptionGraphicsItem *styleOptionArray = d->allocStyleOptionsArray(numItems);
- for (int i = 0; i < numItems; ++i)
- itemArray[i]->d_ptr->initStyleOption(&styleOptionArray[i], viewTransform, d->exposedRegion, allItems);
+ for (int i = 0; i < numItems; ++i) {
+ itemArray[i]->d_ptr->initStyleOption(&styleOptionArray[i], viewTransform,
+ d->exposedRegion, allItems);
+ }
// Draw the items.
drawItems(&painter, numItems, itemArray, styleOptionArray);
d->freeStyleOptionsArray(styleOptionArray);
diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h
index 903ca2b..5682138 100644
--- a/src/gui/graphicsview/qgraphicsview_p.h
+++ b/src/gui/graphicsview/qgraphicsview_p.h
@@ -171,8 +171,8 @@ public:
dirtyBoundingRect = QRect();
dirtyRegion = QRegion();
}
- void updateRect(const QRect &rect);
- void updateRegion(const QRegion &region);
+ bool updateRect(const QRect &rect);
+ bool updateRegion(const QRegion &region);
bool updateSceneSlotReimplementedChecked;
QRegion exposedRegion;
diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp
index 9b25730..f1b0d19 100644
--- a/src/gui/itemviews/qlistview.cpp
+++ b/src/gui/itemviews/qlistview.cpp
@@ -827,6 +827,8 @@ void QListView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int e
*/
void QListView::mouseMoveEvent(QMouseEvent *e)
{
+ if (!isVisible())
+ return;
Q_D(QListView);
QAbstractItemView::mouseMoveEvent(e);
if (state() == DragSelectingState
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
index fef51f9..19c5928 100644
--- a/src/gui/kernel/qapplication_x11.cpp
+++ b/src/gui/kernel/qapplication_x11.cpp
@@ -4617,6 +4617,46 @@ void fetchWacomToolId(int &deviceType, qint64 &serialId)
}
#endif
+struct qt_tablet_motion_data
+{
+ Time timestamp;
+ int tabletMotionType;
+ bool error; // found a reason to stop searching
+};
+
+static Bool qt_mouseMotion_scanner(Display *, XEvent *event, XPointer arg)
+{
+ qt_tablet_motion_data *data = (qt_tablet_motion_data *) arg;
+ if (data->error)
+ return false;
+
+ if (event->type == MotionNotify)
+ return true;
+
+ data->error = event->type != data->tabletMotionType; // we stop compression when another event gets in between.
+ return false;
+}
+
+static Bool qt_tabletMotion_scanner(Display *, XEvent *event, XPointer arg)
+{
+ qt_tablet_motion_data *data = (qt_tablet_motion_data *) arg;
+ if (data->error)
+ return false;
+
+ if (event->type == data->tabletMotionType) {
+ if (data->timestamp > 0) {
+ if ((reinterpret_cast<const XDeviceMotionEvent*>(event))->time > data->timestamp) {
+ data->error = true;
+ return false;
+ }
+ }
+ return true;
+ }
+
+ data->error = event->type != MotionNotify; // we stop compression when another event gets in between.
+ return false;
+}
+
bool QETWidget::translateXinputEvent(const XEvent *ev, QTabletDeviceData *tablet)
{
#if defined (Q_OS_IRIX)
@@ -4643,7 +4683,6 @@ bool QETWidget::translateXinputEvent(const XEvent *ev, QTabletDeviceData *tablet
qreal rotation = 0;
int deviceType = QTabletEvent::NoDevice;
int pointerType = QTabletEvent::UnknownPointer;
- XEvent xinputMotionEvent;
XEvent mouseMotionEvent;
const XDeviceMotionEvent *motion = 0;
XDeviceButtonEvent *button = 0;
@@ -4651,8 +4690,6 @@ bool QETWidget::translateXinputEvent(const XEvent *ev, QTabletDeviceData *tablet
QEvent::Type t;
Qt::KeyboardModifiers modifiers = 0;
bool reinsertMouseEvent = false;
- bool neverFoundMouseEvent = true;
- XEvent xinputMotionEventNext;
XEvent mouseMotionEventSave;
#if !defined (Q_OS_IRIX)
XID device_id;
@@ -4660,72 +4697,41 @@ bool QETWidget::translateXinputEvent(const XEvent *ev, QTabletDeviceData *tablet
if (ev->type == tablet->xinput_motion) {
motion = reinterpret_cast<const XDeviceMotionEvent*>(ev);
- for (;;) {
- // get the corresponding mouseMotionEvent for motion
- if (XCheckTypedWindowEvent(X11->display, internalWinId(), MotionNotify, &mouseMotionEvent)) {
+
+ // Do event compression. Skip over tablet+mouse move events if there are newer ones.
+ qt_tablet_motion_data tabletMotionData;
+ tabletMotionData.tabletMotionType = tablet->xinput_motion;
+ while (true) {
+ // Find first mouse event since we expect them in pairs inside Qt
+ tabletMotionData.error =false;
+ tabletMotionData.timestamp = 0;
+ if (XCheckIfEvent(X11->display, &mouseMotionEvent, &qt_mouseMotion_scanner, (XPointer) &tabletMotionData)) {
mouseMotionEventSave = mouseMotionEvent;
reinsertMouseEvent = true;
- neverFoundMouseEvent = false;
-
- if (mouseMotionEvent.xmotion.time > motion->time) {
- XEvent xinputMotionEventLoop = *ev;
-
- // xinput event is older than the mouse event --> search for the corresponding xinput event for the given mouse event
- while (mouseMotionEvent.xmotion.time > (reinterpret_cast<const XDeviceMotionEvent*>(&xinputMotionEventLoop))->time) {
- if (XCheckTypedWindowEvent(X11->display, internalWinId(), tablet->xinput_motion, &xinputMotionEventLoop)) {
- xinputMotionEvent = xinputMotionEventLoop;
- }
- else {
- break;
- }
- }
- motion = reinterpret_cast<const XDeviceMotionEvent*>(&xinputMotionEvent);
- }
-
- // get the next xinputMotionEvent, for the next loop run
- if (!XCheckTypedWindowEvent(X11->display, internalWinId(), tablet->xinput_motion, &xinputMotionEventNext)) {
- XPutBackEvent(X11->display, &mouseMotionEvent);
- reinsertMouseEvent = false;
- break;
- }
-
- if (mouseMotionEvent.xmotion.time != motion->time) {
- // reinsert in order
- if (mouseMotionEvent.xmotion.time >= motion->time) {
- XPutBackEvent(X11->display, &mouseMotionEvent);
- XPutBackEvent(X11->display, &xinputMotionEventNext);
- // next entry in queue is xinputMotionEventNext
- }
- else {
- XPutBackEvent(X11->display, &xinputMotionEventNext);
- XPutBackEvent(X11->display, &mouseMotionEvent);
- // next entry in queue is mouseMotionEvent
- }
- reinsertMouseEvent = false;
- break;
- }
- }
- else {
+ } else {
break;
}
- xinputMotionEvent = xinputMotionEventNext;
- motion = (reinterpret_cast<const XDeviceMotionEvent*>(&xinputMotionEvent));
- }
+ // Now discard any duplicate tablet events.
+ XEvent dummy;
+ tabletMotionData.error = false;
+ tabletMotionData.timestamp = mouseMotionEvent.xmotion.time;
+ while (XCheckIfEvent(X11->display, &dummy, &qt_tabletMotion_scanner, (XPointer) &tabletMotionData)) {
+ motion = reinterpret_cast<const XDeviceMotionEvent*>(&dummy);
+ }
- if (reinsertMouseEvent) {
- XPutBackEvent(X11->display, &mouseMotionEventSave);
+ // now check if there are more recent tablet motion events since we'll compress the current one with
+ // newer ones in that case
+ tabletMotionData.error = false;
+ tabletMotionData.timestamp = 0;
+ if (! XCheckIfEvent(X11->display, &dummy, &qt_tabletMotion_scanner, (XPointer) &tabletMotionData)) {
+ break; // done with compression
+ }
+ motion = reinterpret_cast<const XDeviceMotionEvent*>(&dummy);
}
- if (neverFoundMouseEvent) {
- XEvent xinputMotionEventLoop;
- bool eventFound = false;
- // xinput event without mouseMotionEvent --> search the newest xinputMotionEvent
- while (XCheckTypedWindowEvent(X11->display, internalWinId(), tablet->xinput_motion, &xinputMotionEventLoop)) {
- xinputMotionEvent = xinputMotionEventLoop;
- eventFound = true;
- }
- if (eventFound) motion = reinterpret_cast<const XDeviceMotionEvent*>(&xinputMotionEvent);
+ if (reinsertMouseEvent) {
+ XPutBackEvent(X11->display, &mouseMotionEventSave);
}
t = QEvent::TabletMove;
diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp
index 3857e30..34de252 100644
--- a/src/gui/widgets/qmenubar.cpp
+++ b/src/gui/widgets/qmenubar.cpp
@@ -1253,7 +1253,8 @@ void QMenuBar::mouseMoveEvent(QMouseEvent *e)
void QMenuBar::leaveEvent(QEvent *)
{
Q_D(QMenuBar);
- if(!hasFocus() && !d->popupState)
+ if((!hasFocus() && !d->popupState) ||
+ (d->currentAction && d->currentAction->menu() == 0))
d->setCurrentAction(0);
}
diff --git a/src/network/access/qnetworkaccesscache_p.h b/src/network/access/qnetworkaccesscache_p.h
index 3fdfbb4..439b3a0 100644
--- a/src/network/access/qnetworkaccesscache_p.h
+++ b/src/network/access/qnetworkaccesscache_p.h
@@ -64,6 +64,9 @@ QT_BEGIN_NAMESPACE
class QNetworkRequest;
class QUrl;
+// this class is not about caching files but about
+// caching objects used by QNetworkAccessManager, e.g. existing TCP connections
+// or credentials.
class QNetworkAccessCache: public QObject
{
Q_OBJECT
diff --git a/src/network/access/qnetworkaccessftpbackend.cpp b/src/network/access/qnetworkaccessftpbackend.cpp
index 9be433d..d6276a3 100644
--- a/src/network/access/qnetworkaccessftpbackend.cpp
+++ b/src/network/access/qnetworkaccessftpbackend.cpp
@@ -82,11 +82,11 @@ QNetworkAccessFtpBackendFactory::create(QNetworkAccessManager::Operation op,
return 0;
}
-class QNetworkAccessFtpFtp: public QFtp, public QNetworkAccessCache::CacheableObject
+class QNetworkAccessCachedFtpConnection: public QFtp, public QNetworkAccessCache::CacheableObject
{
// Q_OBJECT
public:
- QNetworkAccessFtpFtp()
+ QNetworkAccessCachedFtpConnection()
{
setExpires(true);
setShareable(false);
@@ -148,11 +148,11 @@ void QNetworkAccessFtpBackend::open()
}
state = LoggingIn;
- QNetworkAccessCache* cache = QNetworkAccessManagerPrivate::getCache(this);
+ QNetworkAccessCache* objectCache = QNetworkAccessManagerPrivate::getObjectCache(this);
QByteArray cacheKey = makeCacheKey(url);
- if (!cache->requestEntry(cacheKey, this,
+ if (!objectCache->requestEntry(cacheKey, this,
SLOT(ftpConnectionReady(QNetworkAccessCache::CacheableObject*)))) {
- ftp = new QNetworkAccessFtpFtp;
+ ftp = new QNetworkAccessCachedFtpConnection;
#ifndef QT_NO_NETWORKPROXY
if (proxy.type() == QNetworkProxy::FtpCachingProxy)
ftp->setProxy(proxy.hostName(), proxy.port());
@@ -160,7 +160,7 @@ void QNetworkAccessFtpBackend::open()
ftp->connectToHost(url.host(), url.port(DefaultFtpPort));
ftp->login(url.userName(), url.password());
- cache->addEntry(cacheKey, ftp);
+ objectCache->addEntry(cacheKey, ftp);
ftpConnectionReady(ftp);
}
@@ -207,7 +207,7 @@ void QNetworkAccessFtpBackend::downstreamReadyWrite()
void QNetworkAccessFtpBackend::ftpConnectionReady(QNetworkAccessCache::CacheableObject *o)
{
- ftp = static_cast<QNetworkAccessFtpFtp *>(o);
+ ftp = static_cast<QNetworkAccessCachedFtpConnection *>(o);
connect(ftp, SIGNAL(done(bool)), SLOT(ftpDone()));
connect(ftp, SIGNAL(rawCommandReply(int,QString)), SLOT(ftpRawCommandReply(int,QString)));
connect(ftp, SIGNAL(readyRead()), SLOT(ftpReadyRead()));
@@ -227,7 +227,7 @@ void QNetworkAccessFtpBackend::disconnectFromFtp()
disconnect(ftp, 0, this, 0);
QByteArray key = makeCacheKey(url());
- QNetworkAccessManagerPrivate::getCache(this)->releaseEntry(key);
+ QNetworkAccessManagerPrivate::getObjectCache(this)->releaseEntry(key);
ftp = 0;
}
@@ -278,7 +278,7 @@ void QNetworkAccessFtpBackend::ftpDone()
// we're not connected, so remove the cache entry:
QByteArray key = makeCacheKey(url());
- QNetworkAccessManagerPrivate::getCache(this)->removeEntry(key);
+ QNetworkAccessManagerPrivate::getObjectCache(this)->removeEntry(key);
disconnect(ftp, 0, this, 0);
ftp->dispose();
diff --git a/src/network/access/qnetworkaccessftpbackend_p.h b/src/network/access/qnetworkaccessftpbackend_p.h
index 9626403..bb6d766 100644
--- a/src/network/access/qnetworkaccessftpbackend_p.h
+++ b/src/network/access/qnetworkaccessftpbackend_p.h
@@ -66,7 +66,7 @@
QT_BEGIN_NAMESPACE
class QNetworkAccessFtpIODevice;
-class QNetworkAccessFtpFtp;
+class QNetworkAccessCachedFtpConnection;
class QNetworkAccessFtpBackend: public QNetworkAccessBackend
{
@@ -101,7 +101,7 @@ public slots:
private:
friend class QNetworkAccessFtpIODevice;
- QPointer<QNetworkAccessFtpFtp> ftp;
+ QPointer<QNetworkAccessCachedFtpConnection> ftp;
QIODevice *uploadDevice;
qint64 totalBytes;
int helpId, sizeId, mdtmId;
diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp
index 460cbe3..71808d4 100644
--- a/src/network/access/qnetworkaccesshttpbackend.cpp
+++ b/src/network/access/qnetworkaccesshttpbackend.cpp
@@ -270,12 +270,12 @@ static QNetworkReply::NetworkError statusCodeFromHttp(int httpStatusCode, const
return code;
}
-class QNetworkAccessHttpBackendCache: public QHttpNetworkConnection,
+class QNetworkAccessCachedHttpConnection: public QHttpNetworkConnection,
public QNetworkAccessCache::CacheableObject
{
// Q_OBJECT
public:
- QNetworkAccessHttpBackendCache(const QString &hostName, quint16 port, bool encrypt)
+ QNetworkAccessCachedHttpConnection(const QString &hostName, quint16 port, bool encrypt)
: QHttpNetworkConnection(hostName, port, encrypt)
{
setExpires(true);
@@ -311,11 +311,15 @@ QNetworkAccessHttpBackend::~QNetworkAccessHttpBackend()
void QNetworkAccessHttpBackend::disconnectFromHttp()
{
if (http) {
+ // This is abut disconnecting signals, not about disconnecting TCP connections
disconnect(http, 0, this, 0);
- QNetworkAccessCache *cache = QNetworkAccessManagerPrivate::getCache(this);
+
+ // Get the object cache that stores our QHttpNetworkConnection objects
+ QNetworkAccessCache *cache = QNetworkAccessManagerPrivate::getObjectCache(this);
cache->releaseEntry(cacheKey);
}
+ // This is abut disconnecting signals, not about disconnecting TCP connections
if (httpReply)
disconnect(httpReply, 0, this, 0);
@@ -582,16 +586,20 @@ void QNetworkAccessHttpBackend::open()
// check if we have an open connection to this host
cacheKey = makeCacheKey(this, theProxy);
- QNetworkAccessCache *cache = QNetworkAccessManagerPrivate::getCache(this);
- if ((http = static_cast<QNetworkAccessHttpBackendCache *>(cache->requestEntryNow(cacheKey))) == 0) {
+ QNetworkAccessCache *cache = QNetworkAccessManagerPrivate::getObjectCache(this);
+ // the http object is actually a QHttpNetworkConnection
+ http = static_cast<QNetworkAccessCachedHttpConnection *>(cache->requestEntryNow(cacheKey));
+ if (http == 0) {
// no entry in cache; create an object
- http = new QNetworkAccessHttpBackendCache(url.host(), url.port(), encrypt);
+ // the http object is actually a QHttpNetworkConnection
+ http = new QNetworkAccessCachedHttpConnection(url.host(), url.port(), encrypt);
#ifndef QT_NO_NETWORKPROXY
http->setTransparentProxy(transparentProxy);
http->setCacheProxy(cacheProxy);
#endif
+ // cache the QHttpNetworkConnection corresponding to this cache key
cache->addEntry(cacheKey, http);
}
diff --git a/src/network/access/qnetworkaccesshttpbackend_p.h b/src/network/access/qnetworkaccesshttpbackend_p.h
index e0801ce..dec69d0 100644
--- a/src/network/access/qnetworkaccesshttpbackend_p.h
+++ b/src/network/access/qnetworkaccesshttpbackend_p.h
@@ -66,7 +66,7 @@
QT_BEGIN_NAMESPACE
-class QNetworkAccessHttpBackendCache;
+class QNetworkAccessCachedHttpConnection;
class QNetworkAccessHttpBackendIODevice;
@@ -106,7 +106,7 @@ private slots:
private:
QHttpNetworkReply *httpReply;
- QPointer<QNetworkAccessHttpBackendCache> http;
+ QPointer<QNetworkAccessCachedHttpConnection> http;
QByteArray cacheKey;
QNetworkAccessBackendUploadIODevice *uploadDevice;
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 0ae920b..ed2f220 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -836,7 +836,7 @@ void QNetworkAccessManagerPrivate::addCredentials(const QNetworkProxy &p,
QNetworkAuthenticationCache *auth = new QNetworkAuthenticationCache;
auth->insert(QString(), authenticator->user(), authenticator->password());
- cache.addEntry(cacheKey, auth); // replace the existing one, if there's any
+ objectCache.addEntry(cacheKey, auth); // replace the existing one, if there's any
if (realm.isEmpty()) {
break;
@@ -870,13 +870,13 @@ QNetworkAccessManagerPrivate::fetchCachedCredentials(const QNetworkProxy &p,
QByteArray cacheKey = proxyAuthenticationKey(proxy, realm);
if (cacheKey.isEmpty())
return 0;
- if (!cache.hasEntry(cacheKey))
+ if (!objectCache.hasEntry(cacheKey))
return 0;
QNetworkAuthenticationCache *auth =
- static_cast<QNetworkAuthenticationCache *>(cache.requestEntryNow(cacheKey));
+ static_cast<QNetworkAuthenticationCache *>(objectCache.requestEntryNow(cacheKey));
QNetworkAuthenticationCredential *cred = auth->findClosestMatch(QString());
- cache.releaseEntry(cacheKey);
+ objectCache.releaseEntry(cacheKey);
// proxy cache credentials always have exactly one item
Q_ASSERT_X(cred, "QNetworkAccessManager",
@@ -917,15 +917,15 @@ void QNetworkAccessManagerPrivate::addCredentials(const QUrl &url,
copy.setUserName(authenticator->user());
do {
QByteArray cacheKey = authenticationKey(copy, realm);
- if (cache.hasEntry(cacheKey)) {
+ if (objectCache.hasEntry(cacheKey)) {
QNetworkAuthenticationCache *auth =
- static_cast<QNetworkAuthenticationCache *>(cache.requestEntryNow(cacheKey));
+ static_cast<QNetworkAuthenticationCache *>(objectCache.requestEntryNow(cacheKey));
auth->insert(domain, authenticator->user(), authenticator->password());
- cache.releaseEntry(cacheKey);
+ objectCache.releaseEntry(cacheKey);
} else {
QNetworkAuthenticationCache *auth = new QNetworkAuthenticationCache;
auth->insert(domain, authenticator->user(), authenticator->password());
- cache.addEntry(cacheKey, auth);
+ objectCache.addEntry(cacheKey, auth);
}
if (copy.userName().isEmpty()) {
@@ -959,19 +959,19 @@ QNetworkAccessManagerPrivate::fetchCachedCredentials(const QUrl &url,
realm = authentication->realm();
QByteArray cacheKey = authenticationKey(url, realm);
- if (!cache.hasEntry(cacheKey))
+ if (!objectCache.hasEntry(cacheKey))
return 0;
QNetworkAuthenticationCache *auth =
- static_cast<QNetworkAuthenticationCache *>(cache.requestEntryNow(cacheKey));
+ static_cast<QNetworkAuthenticationCache *>(objectCache.requestEntryNow(cacheKey));
QNetworkAuthenticationCredential *cred = auth->findClosestMatch(url.path());
- cache.releaseEntry(cacheKey);
+ objectCache.releaseEntry(cacheKey);
return cred;
}
void QNetworkAccessManagerPrivate::clearCache(QNetworkAccessManager *manager)
{
- manager->d_func()->cache.clear();
+ manager->d_func()->objectCache.clear();
}
QT_END_NAMESPACE
diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h
index c80613b..bcf9a2b 100644
--- a/src/network/access/qnetworkaccessmanager_p.h
+++ b/src/network/access/qnetworkaccessmanager_p.h
@@ -98,10 +98,12 @@ public:
QNetworkAccessBackend *findBackend(QNetworkAccessManager::Operation op, const QNetworkRequest &request);
+ // this is the cache for storing downloaded files
QAbstractNetworkCache *networkCache;
+
QNetworkCookieJar *cookieJar;
- QNetworkAccessCache cache;
+
#ifndef QT_NO_NETWORKPROXY
QNetworkProxy proxy;
QNetworkProxyFactory *proxyFactory;
@@ -109,8 +111,12 @@ public:
bool cookieJarCreated;
- static inline QNetworkAccessCache *getCache(QNetworkAccessBackend *backend)
- { return &backend->manager->cache; }
+
+ // this cache can be used by individual backends to cache e.g. their TCP connections to a server
+ // and use the connections for multiple requests.
+ QNetworkAccessCache objectCache;
+ static inline QNetworkAccessCache *getObjectCache(QNetworkAccessBackend *backend)
+ { return &backend->manager->objectCache; }
Q_AUTOTEST_EXPORT static void clearCache(QNetworkAccessManager *manager);
Q_DECLARE_PUBLIC(QNetworkAccessManager)
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index 19bfe51..d099382 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -1658,13 +1658,13 @@ bool QAbstractSocket::waitForConnected(int msecs)
}
/*!
- This function blocks until data is available for reading and the
+ This function blocks until new data is available for reading and the
\l{QIODevice::}{readyRead()} signal has been emitted. The function
will timeout after \a msecs milliseconds; the default timeout is
30000 milliseconds.
The function returns true if the readyRead() signal is emitted and
- there is data available for reading; otherwise it returns false
+ there is new data available for reading; otherwise it returns false
(if an error occurred or the operation timed out).
\sa waitForBytesWritten()
diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp
index d2cd0d6..9d8cfb0 100644
--- a/src/network/ssl/qsslcertificate.cpp
+++ b/src/network/ssl/qsslcertificate.cpp
@@ -71,9 +71,10 @@
After loading a certificate, you can find information about the
certificate, its subject, and its issuer, by calling one of the
many accessor functions, including version(), serialNumber(),
- issuerInfo() and subjectInfo(). You can call notValidBefore() and
- notValidAfter() to check when the certificate was issued, and when
- it expires. The publicKey() function returns the certificate
+ issuerInfo() and subjectInfo(). You can call effectiveDate() and
+ expiryDate() to check when the certificate starts being
+ effective and when it expires.
+ The publicKey() function returns the certificate
subject's public key as a QSslKey. You can call issuerInfo() or
subjectInfo() to get detailed information about the certificate
issuer and its subject.
diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp
index 84ad4d5..b594f5b 100644
--- a/src/opengl/qpaintengine_opengl.cpp
+++ b/src/opengl/qpaintengine_opengl.cpp
@@ -662,6 +662,7 @@ public:
, txop(QTransform::TxNone)
, inverseScale(1)
, moveToCount(0)
+ , last_created_state(0)
, shader_ctx(0)
, grad_palette(0)
, drawable_texture(0)
@@ -788,6 +789,8 @@ public:
void updateGLMatrix() const;
+ mutable QPainterState *last_created_state;
+
QGLContext *shader_ctx;
GLuint grad_palette;
@@ -2219,6 +2222,8 @@ void QOpenGLPaintEnginePrivate::updateDepthClip()
{
Q_Q(QOpenGLPaintEngine);
+ ++q->state()->depthClipId;
+
glDisable(GL_DEPTH_TEST);
glDisable(GL_SCISSOR_TEST);
@@ -5501,9 +5506,20 @@ void QOpenGLPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
void QOpenGLPaintEngine::setState(QPainterState *s)
{
Q_D(QOpenGLPaintEngine);
+ QOpenGLPaintEngineState *new_state = static_cast<QOpenGLPaintEngineState *>(s);
+ QOpenGLPaintEngineState *old_state = state();
+
QPaintEngineEx::setState(s);
+
+ // are we in a save() ?
+ if (s == d->last_created_state) {
+ d->last_created_state = 0;
+ return;
+ }
+
if (isActive()) {
- d->updateDepthClip();
+ if (old_state->depthClipId != new_state->depthClipId)
+ d->updateDepthClip();
penChanged();
brushChanged();
opacityChanged();
@@ -5515,12 +5531,15 @@ void QOpenGLPaintEngine::setState(QPainterState *s)
QPainterState *QOpenGLPaintEngine::createState(QPainterState *orig) const
{
+ const Q_D(QOpenGLPaintEngine);
+
QOpenGLPaintEngineState *s;
if (!orig)
s = new QOpenGLPaintEngineState();
else
s = new QOpenGLPaintEngineState(*static_cast<QOpenGLPaintEngineState *>(orig));
+ d->last_created_state = s;
return s;
}
@@ -5534,11 +5553,13 @@ QOpenGLPaintEngineState::QOpenGLPaintEngineState(QOpenGLPaintEngineState &other)
clipRegion = other.clipRegion;
hasClipping = other.hasClipping;
fastClip = other.fastClip;
+ depthClipId = other.depthClipId;
}
QOpenGLPaintEngineState::QOpenGLPaintEngineState()
{
hasClipping = false;
+ depthClipId = 0;
}
QOpenGLPaintEngineState::~QOpenGLPaintEngineState()
diff --git a/src/opengl/qpaintengine_opengl_p.h b/src/opengl/qpaintengine_opengl_p.h
index 891cbd6..439782b 100644
--- a/src/opengl/qpaintengine_opengl_p.h
+++ b/src/opengl/qpaintengine_opengl_p.h
@@ -69,6 +69,7 @@ public:
QRegion clipRegion;
bool hasClipping;
QRect fastClip;
+ uint depthClipId;
};
class QOpenGLPaintEngine : public QPaintEngineEx
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp
index 52f6a37..905fec3 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp
@@ -129,18 +129,14 @@ int QDirectFBPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const
if (!dfbSurface)
return 0;
- int w, h;
- dfbSurface->GetSize(dfbSurface, &w, &h);
-
switch (metric) {
case QPaintDevice::PdmWidth:
- return w;
case QPaintDevice::PdmHeight:
- return h;
+ return (metric == PdmWidth ? size().width() : size().height());
case QPaintDevice::PdmWidthMM:
- return (w * 1000) / dotsPerMeterX();
+ return (size().width() * 1000) / dotsPerMeterX();
case QPaintDevice::PdmHeightMM:
- return (h * 1000) / dotsPerMeterY();
+ return (size().height() * 1000) / dotsPerMeterY();
case QPaintDevice::PdmPhysicalDpiX:
case QPaintDevice::PdmDpiX:
return (dotsPerMeterX() * 254) / 10000; // 0.0254 meters-per-inch
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
index c239248..1c86466 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
@@ -72,9 +72,10 @@ void QDirectFBPixmapData::resize(int width, int height)
}
format = screen->pixelFormat();
- dfbSurface = QDirectFBScreen::instance()->createDFBSurface(QSize(width, height),
- format,
- QDirectFBScreen::TrackSurface);
+ dfbSurface = screen->createDFBSurface(QSize(width, height),
+ format,
+ QDirectFBScreen::TrackSurface);
+ d = screen->depth();
alpha = false;
if (!dfbSurface) {
invalidate();
@@ -195,8 +196,8 @@ void QDirectFBPixmapData::fromImage(const QImage &i,
invalidate();
return;
}
- w = metric(QPaintDevice::PdmWidth);
- h = metric(QPaintDevice::PdmHeight);
+ w = img.width();
+ h = img.height();
is_null = (w <= 0 || h <= 0);
d = metric(QPaintDevice::PdmDepth);
setSerialNumber(++global_ser_no);
@@ -209,7 +210,8 @@ void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect)
return;
}
- IDirectFBSurface *src = static_cast<const QDirectFBPixmapData*>(data)->directFBSurface();
+ const QDirectFBPixmapData *otherData = static_cast<const QDirectFBPixmapData*>(data);
+ IDirectFBSurface *src = otherData->directFBSurface();
alpha = data->hasAlphaChannel();
format = (alpha
? QDirectFBScreen::instance()->alphaPixmapFormat()
@@ -232,6 +234,9 @@ void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect)
}
const DFBRectangle blitRect = { rect.x(), rect.y(),
rect.width(), rect.height() };
+ w = rect.width();
+ h = rect.height();
+ d = otherData->d;
DFBResult result = dfbSurface->Blit(dfbSurface, src, &blitRect, 0, 0);
#if (Q_DIRECTFB_VERSION >= 0x010000)
dfbSurface->ReleaseSource(dfbSurface);
@@ -303,9 +308,6 @@ QPixmap QDirectFBPixmapData::transformed(const QTransform &transform,
return QPixmap(data);
}
- int w, h;
- dfbSurface->GetSize(dfbSurface, &w, &h);
-
const QSize size = transform.mapRect(QRect(0, 0, w, h)).size();
if (size.isEmpty())
return QPixmap();
@@ -326,6 +328,8 @@ QPixmap QDirectFBPixmapData::transformed(const QTransform &transform,
const DFBRectangle destRect = { 0, 0, size.width(), size.height() };
data->dfbSurface->StretchBlit(data->dfbSurface, dfbSurface, 0, &destRect);
+ data->w = size.width();
+ data->h = size.height();
#if (Q_DIRECTFB_VERSION >= 0x010000)
data->dfbSurface->ReleaseSource(data->dfbSurface);
#endif
@@ -338,7 +342,7 @@ QImage QDirectFBPixmapData::toImage() const
return QImage();
#ifndef QT_NO_DIRECTFB_PREALLOCATED
- QImage ret(size(), QDirectFBScreen::getImageFormat(dfbSurface));
+ QImage ret(w, h, QDirectFBScreen::getImageFormat(dfbSurface));
if (IDirectFBSurface *imgSurface = screen->createDFBSurface(ret, QDirectFBScreen::DontTrackSurface)) {
if (hasAlphaChannel()) {
imgSurface->SetBlittingFlags(imgSurface, DSBLIT_BLEND_ALPHACHANNEL);
@@ -387,6 +391,7 @@ void QDirectFBPixmapData::invalidate()
{
setSerialNumber(0);
alpha = false;
+ d = w = h = 0;
format = QImage::Format_Invalid;
}
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
index 5d89994..62fef5b 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
@@ -751,12 +751,7 @@ QPixmapData *QDirectFBScreenPrivate::createPixmapData(QPixmapData::PixelType typ
return new QDirectFBPixmapData(type);
}
-#ifdef QT_NO_DEBUG
-struct FlagDescription;
-static const FlagDescription *accelerationDescriptions = 0;
-static const FlagDescription *blitDescriptions = 0;
-static const FlagDescription *drawDescriptions = 0;
-#else
+#ifndef QT_NO_DEBUG
struct FlagDescription {
const char *name;
uint flag;
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h
index c2c9a59..4239156 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h
@@ -118,6 +118,7 @@ public:
SurfaceCreationOptions options);
void releaseDFBSurface(IDirectFBSurface *surface);
+ using QScreen::depth;
static int depth(DFBSurfacePixelFormat format);
static DFBSurfacePixelFormat getSurfacePixelFormat(QImage::Format format);
diff --git a/src/scripttools/debugging/qscriptdebugger.cpp b/src/scripttools/debugging/qscriptdebugger.cpp
index 9cca8ad..20de788 100644
--- a/src/scripttools/debugging/qscriptdebugger.cpp
+++ b/src/scripttools/debugging/qscriptdebugger.cpp
@@ -75,10 +75,6 @@
#include "qscriptdebuggerjob_p_p.h"
#include "qscriptxmlparser_p.h"
-#include "qscriptenginedebuggerfrontend_p.h"
-#include "qscriptdebuggerbackend_p.h"
-#include <QtScript/qscriptengine.h>
-
#include "private/qobject_p.h"
#include <QtScript/qscriptcontext.h>
@@ -1946,6 +1942,12 @@ QToolBar *QScriptDebugger::createStandardToolBar(QWidget *widgetParent, QObject
return tb;
}
+bool QScriptDebugger::isInteractive() const
+{
+ Q_D(const QScriptDebugger);
+ return d->interactive;
+}
+
/*!
\reimp
*/
diff --git a/src/scripttools/debugging/qscriptdebugger_p.h b/src/scripttools/debugging/qscriptdebugger_p.h
index 9ed7e0a..ba27200 100644
--- a/src/scripttools/debugging/qscriptdebugger_p.h
+++ b/src/scripttools/debugging/qscriptdebugger_p.h
@@ -172,6 +172,8 @@ public:
bool eventFilter(QObject *, QEvent *e);
+ bool isInteractive() const;
+
Q_SIGNALS:
void stopped() const;
void started() const;
diff --git a/src/scripttools/debugging/qscriptdebuggerbackend.cpp b/src/scripttools/debugging/qscriptdebuggerbackend.cpp
index 9eaf571..7f4211c 100644
--- a/src/scripttools/debugging/qscriptdebuggerbackend.cpp
+++ b/src/scripttools/debugging/qscriptdebuggerbackend.cpp
@@ -412,14 +412,15 @@ void QScriptDebuggerBackend::attachTo(QScriptEngine *engine)
detach();
d->agent = new QScriptDebuggerAgent(d, engine);
QScriptValue global = engine->globalObject();
+ d->origTraceFunction = global.property(QString::fromLatin1("print"));
global.setProperty(QString::fromLatin1("print"), traceFunction());
// global.setProperty(QString::fromLatin1("qAssert"), assertFunction());
+ d->origFileNameFunction = global.property(QString::fromLatin1("__FILE__"));
global.setProperty(QString::fromLatin1("__FILE__"), fileNameFunction(),
- QScriptValue::PropertyGetter | QScriptValue::PropertySetter
- | QScriptValue::ReadOnly);
+ QScriptValue::PropertyGetter | QScriptValue::ReadOnly);
+ d->origLineNumberFunction = global.property(QString::fromLatin1("__LINE__"));
global.setProperty(QString::fromLatin1("__LINE__"), lineNumberFunction(),
- QScriptValue::PropertyGetter | QScriptValue::PropertySetter
- | QScriptValue::ReadOnly);
+ QScriptValue::PropertyGetter | QScriptValue::ReadOnly);
engine->setAgent(d->agent);
}
@@ -433,21 +434,25 @@ void QScriptDebuggerBackend::attachTo(QScriptEngine *engine)
void QScriptDebuggerBackend::detach()
{
Q_D(QScriptDebuggerBackend);
- if (!d->agent)
- return;
- QScriptEngine *eng = d->agent->engine();
- if (eng && eng->agent() == d->agent) {
- eng->setAgent(0);
- QScriptValue global = eng->globalObject();
- if (global.property(QString::fromLatin1("print")).strictlyEquals(traceFunction()))
- global.setProperty(QString::fromLatin1("print"), QScriptValue());
-// global.setProperty(QString::fromLatin1("qAssert"), QScriptValue());
- if (global.property(QString::fromLatin1("__FILE__")).strictlyEquals(fileNameFunction()))
- global.setProperty(QString::fromLatin1("__FILE__"), QScriptValue());
- if (global.property(QString::fromLatin1("__LINE__")).strictlyEquals(lineNumberFunction()))
- global.setProperty(QString::fromLatin1("__LINE__"), QScriptValue());
- d->agent->nullifyBackendPointer();
- d->agent = 0; // agent is owned by engine
+ if (d->agent) {
+ QScriptEngine *eng = d->agent->engine();
+ if (eng && eng->agent() == d->agent) {
+ eng->setAgent(0);
+ QScriptValue global = eng->globalObject();
+ global.setProperty(QString::fromLatin1("print"), d->origTraceFunction);
+ d->origTraceFunction = QScriptValue();
+// global.setProperty(QString::fromLatin1("qAssert"), QScriptValue());
+ global.setProperty(QString::fromLatin1("__FILE__"), QScriptValue(),
+ QScriptValue::PropertyGetter);
+ global.setProperty(QString::fromLatin1("__FILE__"), d->origFileNameFunction);
+ d->origFileNameFunction = QScriptValue();
+ global.setProperty(QString::fromLatin1("__LINE__"), QScriptValue(),
+ QScriptValue::PropertyGetter);
+ global.setProperty(QString::fromLatin1("__LINE__"), d->origLineNumberFunction);
+ d->origLineNumberFunction = QScriptValue();
+ d->agent->nullifyBackendPointer();
+ d->agent = 0; // agent is owned by engine
+ }
}
d->pendingEvaluateLineNumber = -1;
diff --git a/src/scripttools/debugging/qscriptdebuggerbackend_p_p.h b/src/scripttools/debugging/qscriptdebuggerbackend_p_p.h
index de18304..a356762 100644
--- a/src/scripttools/debugging/qscriptdebuggerbackend_p_p.h
+++ b/src/scripttools/debugging/qscriptdebuggerbackend_p_p.h
@@ -57,6 +57,7 @@
#include <QtCore/qhash.h>
#include <QtCore/qlist.h>
+#include <QtScript/qscriptvalue.h>
#include "qscriptdebuggerbackend_p.h"
@@ -66,7 +67,6 @@ class QEvent;
class QString;
class QScriptContext;
class QScriptEngine;
-class QScriptValue;
class QScriptValueIterator;
class QScriptObjectSnapshot;
class QScriptDebuggerAgent;
@@ -126,6 +126,10 @@ public:
QObject *eventReceiver;
QScriptDebuggerBackend *q_ptr;
+
+ QScriptValue origTraceFunction;
+ QScriptValue origFileNameFunction;
+ QScriptValue origLineNumberFunction;
};
QT_END_NAMESPACE
diff --git a/src/scripttools/debugging/qscriptenginedebugger.cpp b/src/scripttools/debugging/qscriptenginedebugger.cpp
index 948a01a..f2245cc 100644
--- a/src/scripttools/debugging/qscriptenginedebugger.cpp
+++ b/src/scripttools/debugging/qscriptenginedebugger.cpp
@@ -126,7 +126,7 @@ public:
mode in which it accepts input from the user. The
evaluationResumed() signal is emitted when script evaluation is
resumed, i.e, when execution control is given back to the script
- engine.
+ engine. The state() function returns the debugger's current state.
When calling QScriptEngine::evaluate() it is useful to pass a
descriptive script name (file name) as second argument, as this is
@@ -226,6 +226,16 @@ public:
\value GoToLineAction Shows the "Go to Line" dialog.
*/
+/*!
+ \enum QScriptEngineDebugger::DebuggerState
+ \since 4.6
+
+ This enum specifies the current state of the debugger.
+
+ \value RunningState The debugger is running. (Script evaluation is allowed.)
+ \value SuspendedState The debugger has suspended script evaluation.
+*/
+
class QScriptEngineDebuggerPrivate
: public QObjectPrivate
{
@@ -387,6 +397,20 @@ void QScriptEngineDebugger::detach()
}
/*!
+ \since 4.6
+
+ Returns the current state of the debugger.
+
+ \sa evaluationResumed()
+ \sa evaluationSuspended()
+*/
+QScriptEngineDebugger::DebuggerState QScriptEngineDebugger::state() const
+{
+ Q_D(const QScriptEngineDebugger);
+ return !d->debugger || !d->debugger->isInteractive() ? SuspendedState : RunningState;
+}
+
+/*!
Returns a pointer to the instance of the specified standard \a
widget. The widgets available are defined by the DebuggerWidget
diff --git a/src/scripttools/debugging/qscriptenginedebugger.h b/src/scripttools/debugging/qscriptenginedebugger.h
index 0fd4963..b9061a2 100644
--- a/src/scripttools/debugging/qscriptenginedebugger.h
+++ b/src/scripttools/debugging/qscriptenginedebugger.h
@@ -92,6 +92,11 @@ public:
GoToLineAction
};
+ enum DebuggerState {
+ RunningState,
+ SuspendedState
+ };
+
QScriptEngineDebugger(QObject *parent = 0);
~QScriptEngineDebugger();
@@ -108,6 +113,8 @@ public:
QWidget *widget(DebuggerWidget widget) const;
QAction *action(DebuggerAction action) const;
+ DebuggerState state() const;
+
Q_SIGNALS:
void evaluationSuspended();
void evaluationResumed();