diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2010-05-07 20:49:46 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2010-05-07 20:49:46 (GMT) |
commit | 5c073ef002273b4c4b01e0d4d1594e9c17699245 (patch) | |
tree | 043346f1c01a66bebd0d083df816bf6099e86af2 | |
parent | 6ff95852da22ba8843a2913c92aa37af36236ca0 (diff) | |
parent | cb3f3858555bb5b385ee42bb51c4011b21779506 (diff) | |
download | Qt-5c073ef002273b4c4b01e0d4d1594e9c17699245.zip Qt-5c073ef002273b4c4b01e0d4d1594e9c17699245.tar.gz Qt-5c073ef002273b4c4b01e0d4d1594e9c17699245.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2:
Mark QFileDialog::Options as a Q_FLAGS
fix tst_QDockWidget::taskQTBUG_9758_undockedGeometry on Linux
Fixed scrolling bugs in widget graphics effect backend.
Fixed source pixmap bug in widget graphics effect backend.
Fix crash with stylesheet if widget change style in the changeEvent
Fix textdrawing under GL on N900.
Fixed bug in QIODevice::read after first reading 0 bytes.
Fix auto-test failure on Mac/Linux/QWS.
Some EGL implementations does not return a EGLNativeDisplayType
Fixed the sizing of the dock area with fixed size dock widgets
QSortFilterProxyModel: Warning or assert failure
Performance issue with QGraphicsItem::ItemClipsChildrenToShape.
Fixes crash in QGraphicsItem::mouseMove for untransformable items.
Pack Graphics View booleans in quint32 bit fields.
Fixes regression: SVG image loading would fail from QBuffer with pos!=0
Fix a bug in QGraphicsItem::scroll.
Fixed the position of the dock widget when undocked
26 files changed, 522 insertions, 182 deletions
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index bb11d6b..223df9b 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -810,6 +810,9 @@ qint64 QIODevice::read(char *data, qint64 maxSize) } } + if (!maxSize) + return readSoFar; + if ((d->openMode & Unbuffered) == 0 && maxSize < QIODEVICE_BUFFERSIZE) { // In buffered mode, we try to fill up the QIODevice buffer before // we do anything else. diff --git a/src/gui/dialogs/qfiledialog.h b/src/gui/dialogs/qfiledialog.h index 97fac4e..16cb317 100644 --- a/src/gui/dialogs/qfiledialog.h +++ b/src/gui/dialogs/qfiledialog.h @@ -67,6 +67,7 @@ class Q_GUI_EXPORT QFileDialog : public QDialog { Q_OBJECT Q_ENUMS(ViewMode FileMode AcceptMode Option) + Q_FLAGS(Options) Q_PROPERTY(ViewMode viewMode READ viewMode WRITE setViewMode) Q_PROPERTY(FileMode fileMode READ fileMode WRITE setFileMode) Q_PROPERTY(AcceptMode acceptMode READ acceptMode WRITE setAcceptMode) diff --git a/src/gui/effects/qgraphicseffect.cpp b/src/gui/effects/qgraphicseffect.cpp index ce4ce6a..5e4e49e 100644 --- a/src/gui/effects/qgraphicseffect.cpp +++ b/src/gui/effects/qgraphicseffect.cpp @@ -326,7 +326,7 @@ QPixmap QGraphicsEffectSource::pixmap(Qt::CoordinateSystem system, QPoint *offse } QPixmap pm; - if (d->m_cachedSystem == system && d->m_cachedMode == mode) + if (item && d->m_cachedSystem == system && d->m_cachedMode == mode) QPixmapCache::find(d->m_cacheKey, &pm); if (pm.isNull()) { diff --git a/src/gui/egl/qegl_qws.cpp b/src/gui/egl/qegl_qws.cpp index 56383a5..50db397 100644 --- a/src/gui/egl/qegl_qws.cpp +++ b/src/gui/egl/qegl_qws.cpp @@ -94,7 +94,7 @@ void QEglProperties::setPaintDeviceFormat(QPaintDevice *dev) EGLNativeDisplayType QEgl::nativeDisplay() { - return EGL_DEFAULT_DISPLAY; + return EGLNativeDisplayType(EGL_DEFAULT_DISPLAY); } EGLNativeWindowType QEgl::nativeWindow(QWidget* widget) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 326f130..65edb2a 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1812,7 +1812,7 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations | ItemIsSelectable); bool fullUpdate = (quint32(flags) & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask); if (fullUpdate) - d_ptr->paintedViewBoundingRectsNeedRepaint = 1; + d_ptr->updatePaintedViewBoundingRects(/*children=*/true); // Keep the old flags to compare the diff. GraphicsItemFlags oldFlags = GraphicsItemFlags(d_ptr->flags); @@ -5432,6 +5432,24 @@ void QGraphicsItemPrivate::removeExtraItemCache() unsetExtra(ExtraCacheData); } +void QGraphicsItemPrivate::updatePaintedViewBoundingRects(bool updateChildren) +{ + if (!scene) + return; + + for (int i = 0; i < scene->d_func()->views.size(); ++i) { + QGraphicsViewPrivate *viewPrivate = scene->d_func()->views.at(i)->d_func(); + QRect rect = paintedViewBoundingRects.value(viewPrivate->viewport); + rect.translate(viewPrivate->dirtyScrollOffset); + viewPrivate->updateRect(rect); + } + + if (updateChildren) { + for (int i = 0; i < children.size(); ++i) + children.at(i)->d_ptr->updatePaintedViewBoundingRects(true); + } +} + // Traverses all the ancestors up to the top-level and updates the pointer to // always point to the top-most item that has a dirty scene transform. // It then backtracks to the top-most dirty item and start calculating the @@ -5635,8 +5653,9 @@ void QGraphicsItem::scroll(qreal dx, qreal dy, const QRectF &rect) // Adjust with 2 pixel margin. Notice the loss of precision // when converting to QRect. int adjust = 2; + QRectF scrollRect = !rect.isNull() ? rect : boundingRect(); QRectF br = boundingRect().adjusted(-adjust, -adjust, adjust, adjust); - QRect irect = rect.toRect().translated(-br.x(), -br.y()); + QRect irect = scrollRect.toRect().translated(-br.x(), -br.y()); pix.scroll(dx, dy, irect); @@ -5644,11 +5663,11 @@ void QGraphicsItem::scroll(qreal dx, qreal dy, const QRectF &rect) // Translate the existing expose. foreach (QRectF exposedRect, c->exposed) - c->exposed += exposedRect.translated(dx, dy) & rect; + c->exposed += exposedRect.translated(dx, dy) & scrollRect; // Calculate exposure. QRegion exposed; - QRect r = rect.toRect(); + QRect r = scrollRect.toRect(); exposed += r; exposed -= r.translated(dx, dy); foreach (QRect rect, exposed.rects()) @@ -7131,7 +7150,11 @@ void QGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) // calculate their diff by mapping viewport coordinates // directly to parent coordinates. // COMBINE - QTransform viewToParentTransform = (item->d_func()->transformData->computedFullTransform().translate(item->d_ptr->pos.x(), item->d_ptr->pos.y())) + QTransform itemTransform; + if (item->d_ptr->transformData) + itemTransform = item->d_ptr->transformData->computedFullTransform(); + itemTransform.translate(item->d_ptr->pos.x(), item->d_ptr->pos.y()); + QTransform viewToParentTransform = itemTransform * (item->sceneTransform() * view->viewportTransform()).inverted(); currentParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->screenPos()))); buttonDownParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->buttonDownScreenPos(Qt::LeftButton)))); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 569a329..e812f29 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -377,6 +377,7 @@ public: QGraphicsItemCache *extraItemCache() const; void removeExtraItemCache(); + void updatePaintedViewBoundingRects(bool updateChildren); void ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem); inline void ensureSceneTransform() { diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 0d4e48a..dfba7c9 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -290,13 +290,19 @@ QGraphicsScenePrivate::QGraphicsScenePrivate() updateAll(false), calledEmitUpdated(false), processDirtyItemsEmitted(false), - selectionChanging(0), needSortTopLevelItems(true), holesInTopLevelSiblingIndex(false), topLevelSequentialOrdering(true), scenePosDescendantsUpdatePending(false), stickyFocus(false), hasFocus(false), + lastMouseGrabberItemHasImplicitMouseGrab(false), + allItemsIgnoreHoverEvents(true), + allItemsUseDefaultCursor(true), + painterStateProtection(true), + sortCacheEnabled(false), + allItemsIgnoreTouchEvents(true), + selectionChanging(0), rectAdjust(2), focusItem(0), lastFocusItem(0), @@ -306,16 +312,10 @@ QGraphicsScenePrivate::QGraphicsScenePrivate() activationRefCount(0), childExplicitActivation(0), lastMouseGrabberItem(0), - lastMouseGrabberItemHasImplicitMouseGrab(false), dragDropItem(0), enterWidget(0), lastDropAction(Qt::IgnoreAction), - allItemsIgnoreHoverEvents(true), - allItemsUseDefaultCursor(true), - painterStateProtection(true), - sortCacheEnabled(false), - style(0), - allItemsIgnoreTouchEvents(true) + style(0) { } @@ -5116,9 +5116,15 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool // Process children. if (itemHasChildren && item->d_ptr->dirtyChildren) { + const bool itemClipsChildrenToShape = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape; + if (itemClipsChildrenToShape) { + // Make sure child updates are clipped to the item's bounding rect. + for (int i = 0; i < views.size(); ++i) + views.at(i)->d_func()->setUpdateClip(item); + } if (!dirtyAncestorContainsChildren) { dirtyAncestorContainsChildren = item->d_ptr->fullUpdatePending - && (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape); + && itemClipsChildrenToShape; } const bool allChildrenDirty = item->d_ptr->allChildrenDirty; const bool parentIgnoresVisible = item->d_ptr->ignoreVisible; @@ -5141,6 +5147,12 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool } processDirtyItemsRecursive(child, dirtyAncestorContainsChildren, opacity); } + + if (itemClipsChildrenToShape) { + // Reset updateClip. + for (int i = 0; i < views.size(); ++i) + views.at(i)->d_func()->setUpdateClip(0); + } } else if (wasDirtyParentSceneTransform) { item->d_ptr->invalidateChildrenSceneTransform(); } diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 0a85f0e..77bf450 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -97,24 +97,36 @@ public: int lastItemCount; QRectF sceneRect; - bool hasSceneRect; - bool dirtyGrowingItemsBoundingRect; + + quint32 hasSceneRect : 1; + quint32 dirtyGrowingItemsBoundingRect : 1; + quint32 updateAll : 1; + quint32 calledEmitUpdated : 1; + quint32 processDirtyItemsEmitted : 1; + quint32 needSortTopLevelItems : 1; + quint32 holesInTopLevelSiblingIndex : 1; + quint32 topLevelSequentialOrdering : 1; + quint32 scenePosDescendantsUpdatePending : 1; + quint32 stickyFocus : 1; + quint32 hasFocus : 1; + quint32 lastMouseGrabberItemHasImplicitMouseGrab : 1; + quint32 allItemsIgnoreHoverEvents : 1; + quint32 allItemsUseDefaultCursor : 1; + quint32 painterStateProtection : 1; + quint32 sortCacheEnabled : 1; // for compatibility + quint32 allItemsIgnoreTouchEvents : 1; + quint32 padding : 15; + QRectF growingItemsBoundingRect; void _q_emitUpdated(); QList<QRectF> updatedRects; - bool updateAll; - bool calledEmitUpdated; - bool processDirtyItemsEmitted; QPainterPath selectionArea; int selectionChanging; QSet<QGraphicsItem *> selectedItems; QVector<QGraphicsItem *> unpolishedItems; QList<QGraphicsItem *> topLevelItems; - bool needSortTopLevelItems; - bool holesInTopLevelSiblingIndex; - bool topLevelSequentialOrdering; QMap<QGraphicsItem *, QPointF> movingItemsInitialPositions; void registerTopLevelItem(QGraphicsItem *item); @@ -125,7 +137,6 @@ public: void _q_processDirtyItems(); QSet<QGraphicsItem *> scenePosItems; - bool scenePosDescendantsUpdatePending; void setScenePosItemEnabled(QGraphicsItem *item, bool enabled); void registerScenePosItem(QGraphicsItem *item); void unregisterScenePosItem(QGraphicsItem *item); @@ -136,9 +147,6 @@ public: QBrush backgroundBrush; QBrush foregroundBrush; - quint32 stickyFocus : 1; - quint32 hasFocus : 1; - quint32 padding : 30; quint32 rectAdjust; QGraphicsItem *focusItem; QGraphicsItem *lastFocusItem; @@ -155,7 +163,6 @@ public: void removePopup(QGraphicsWidget *widget, bool itemIsDying = false); QGraphicsItem *lastMouseGrabberItem; - bool lastMouseGrabberItemHasImplicitMouseGrab; QList<QGraphicsItem *> mouseGrabberItems; void grabMouse(QGraphicsItem *item, bool implicit = false); void ungrabMouse(QGraphicsItem *item, bool itemIsDying = false); @@ -172,8 +179,6 @@ public: QList<QGraphicsItem *> cachedItemsUnderMouse; QList<QGraphicsItem *> hoverItems; QPointF lastSceneMousePos; - bool allItemsIgnoreHoverEvents; - bool allItemsUseDefaultCursor; void enableMouseTrackingOnViews(); QMap<Qt::MouseButton, QPointF> mouseGrabberButtonDownPos; QMap<Qt::MouseButton, QPointF> mouseGrabberButtonDownScenePos; @@ -187,8 +192,6 @@ public: void addView(QGraphicsView *view); void removeView(QGraphicsView *view); - bool painterStateProtection; - QMultiMap<QGraphicsItem *, QGraphicsItem *> sceneEventFilters; void installSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter); void removeSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter); @@ -210,8 +213,6 @@ public: void mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent); QGraphicsWidget *windowForItem(const QGraphicsItem *item) const; - bool sortCacheEnabled; // for compatibility - void drawItemHelper(QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget, bool painterStateProtection); @@ -295,7 +296,6 @@ public: int findClosestTouchPointId(const QPointF &scenePos); void touchEventHandler(QTouchEvent *touchEvent); bool sendTouchBeginEvent(QGraphicsItem *item, QTouchEvent *touchEvent); - bool allItemsIgnoreTouchEvents; void enableTouchEventsOnViews(); QList<QGraphicsObject *> cachedTargetItems; diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 0bba7e9..0f951ef 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -327,16 +327,21 @@ QGraphicsViewPrivate::QGraphicsViewPrivate() dragMode(QGraphicsView::NoDrag), sceneInteractionAllowed(true), hasSceneRect(false), connectedToScene(false), - mousePressButton(Qt::NoButton), + useLastMouseEvent(false), identityMatrix(true), dirtyScroll(true), accelerateScrolling(true), + keepLastCenterPoint(true), + transforming(false), + handScrolling(false), + mustAllocateStyleOptions(false), + mustResizeBackgroundPixmap(true), + fullUpdatePending(true), + hasUpdateClip(false), + mousePressButton(Qt::NoButton), leftIndent(0), topIndent(0), lastMouseEvent(QEvent::None, QPoint(), Qt::NoButton, 0, 0), - useLastMouseEvent(false), - keepLastCenterPoint(true), alignment(Qt::AlignCenter), - transforming(false), transformationAnchor(QGraphicsView::AnchorViewCenter), resizeAnchor(QGraphicsView::NoAnchor), viewportUpdateMode(QGraphicsView::MinimalViewportUpdate), optimizationFlags(0), @@ -345,14 +350,11 @@ QGraphicsViewPrivate::QGraphicsViewPrivate() rubberBanding(false), rubberBandSelectionMode(Qt::IntersectsItemShape), #endif - handScrolling(false), handScrollMotions(0), cacheMode(0), - mustAllocateStyleOptions(false), - mustResizeBackgroundPixmap(true), + handScrollMotions(0), cacheMode(0), #ifndef QT_NO_CURSOR hasStoredOriginalCursor(false), #endif lastDragDropEvent(0), - fullUpdatePending(true), updateSceneSlotReimplementedChecked(false) { styleOptions.reserve(QGRAPHICSVIEW_PREALLOC_STYLE_OPTIONS); @@ -879,6 +881,52 @@ static inline void QRect_unite(QRect *rect, const QRect &other) } } +/* + Calling this function results in update rects being clipped to the item's + bounding rect. Note that updates prior to this function call is not clipped. + The clip is removed by passing 0. +*/ +void QGraphicsViewPrivate::setUpdateClip(QGraphicsItem *item) +{ + Q_Q(QGraphicsView); + // We simply ignore the request if the update mode is either FullViewportUpdate + // or NoViewportUpdate; in that case there's no point in clipping anything. + if (!item || viewportUpdateMode == QGraphicsView::NoViewportUpdate + || viewportUpdateMode == QGraphicsView::FullViewportUpdate) { + hasUpdateClip = false; + return; + } + + // Calculate the clip (item's bounding rect in view coordinates). + // Optimized version of: + // QRect clip = item->deviceTransform(q->viewportTransform()) + // .mapRect(item->boundingRect()).toAlignedRect(); + QRect clip; + if (item->d_ptr->itemIsUntransformable()) { + QTransform xform = item->deviceTransform(q->viewportTransform()); + clip = xform.mapRect(item->boundingRect()).toAlignedRect(); + } else if (item->d_ptr->sceneTransformTranslateOnly && identityMatrix) { + QRectF r(item->boundingRect()); + r.translate(item->d_ptr->sceneTransform.dx() - horizontalScroll(), + item->d_ptr->sceneTransform.dy() - verticalScroll()); + clip = r.toAlignedRect(); + } else if (!q->isTransformed()) { + clip = item->d_ptr->sceneTransform.mapRect(item->boundingRect()).toAlignedRect(); + } else { + QTransform xform = item->d_ptr->sceneTransform; + xform *= q->viewportTransform(); + clip = xform.mapRect(item->boundingRect()).toAlignedRect(); + } + + if (hasUpdateClip) { + // Intersect with old clip. + updateClip &= clip; + } else { + updateClip = clip; + hasUpdateClip = true; + } +} + bool QGraphicsViewPrivate::updateRegion(const QRectF &rect, const QTransform &xform) { if (rect.isEmpty()) @@ -909,6 +957,8 @@ bool QGraphicsViewPrivate::updateRegion(const QRectF &rect, const QTransform &xf viewRect.adjust(-1, -1, 1, 1); else viewRect.adjust(-2, -2, 2, 2); + if (hasUpdateClip) + viewRect &= updateClip; dirtyRegion += viewRect; } @@ -930,7 +980,10 @@ bool QGraphicsViewPrivate::updateRect(const QRect &r) viewport->update(); break; case QGraphicsView::BoundingRectViewportUpdate: - QRect_unite(&dirtyBoundingRect, r); + if (hasUpdateClip) + QRect_unite(&dirtyBoundingRect, r & updateClip); + else + QRect_unite(&dirtyBoundingRect, r); if (containsViewport(dirtyBoundingRect, viewport->width(), viewport->height())) { fullUpdatePending = true; viewport->update(); @@ -938,7 +991,10 @@ bool QGraphicsViewPrivate::updateRect(const QRect &r) break; case QGraphicsView::SmartViewportUpdate: // ### DEPRECATE case QGraphicsView::MinimalViewportUpdate: - dirtyRegion += r; + if (hasUpdateClip) + dirtyRegion += r & updateClip; + else + dirtyRegion += r; break; default: break; diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h index aeff28a..7bd9ecb 100644 --- a/src/gui/graphicsview/qgraphicsview_p.h +++ b/src/gui/graphicsview/qgraphicsview_p.h @@ -77,11 +77,25 @@ public: QPainter::RenderHints renderHints; QGraphicsView::DragMode dragMode; - bool sceneInteractionAllowed; + + quint32 sceneInteractionAllowed : 1; + quint32 hasSceneRect : 1; + quint32 connectedToScene : 1; + quint32 useLastMouseEvent : 1; + quint32 identityMatrix : 1; + quint32 dirtyScroll : 1; + quint32 accelerateScrolling : 1; + quint32 keepLastCenterPoint : 1; + quint32 transforming : 1; + quint32 handScrolling : 1; + quint32 mustAllocateStyleOptions : 1; + quint32 mustResizeBackgroundPixmap : 1; + quint32 fullUpdatePending : 1; + quint32 hasUpdateClip : 1; + quint32 padding : 18; + QRectF sceneRect; - bool hasSceneRect; void updateLastCenterPoint(); - bool connectedToScene; qint64 horizontalScroll() const; qint64 verticalScroll() const; @@ -89,6 +103,7 @@ public: QRectF mapRectToScene(const QRect &rect) const; QRectF mapRectFromScene(const QRectF &rect) const; + QRect updateClip; QPointF mousePressItemPoint; QPointF mousePressScenePoint; QPoint mousePressViewPoint; @@ -98,26 +113,20 @@ public: QPoint dirtyScrollOffset; Qt::MouseButton mousePressButton; QTransform matrix; - bool identityMatrix; qint64 scrollX, scrollY; - bool dirtyScroll; void updateScroll(); - bool accelerateScrolling; qreal leftIndent; qreal topIndent; // Replaying mouse events QMouseEvent lastMouseEvent; - bool useLastMouseEvent; void replayLastMouseEvent(); void storeMouseEvent(QMouseEvent *event); void mouseMoveEventHandler(QMouseEvent *event); QPointF lastCenterPoint; - bool keepLastCenterPoint; Qt::Alignment alignment; - bool transforming; QGraphicsView::ViewportAnchor transformationAnchor; QGraphicsView::ViewportAnchor resizeAnchor; @@ -131,20 +140,17 @@ public: bool rubberBanding; Qt::ItemSelectionMode rubberBandSelectionMode; #endif - bool handScrolling; int handScrollMotions; QGraphicsView::CacheMode cacheMode; QVector<QStyleOptionGraphicsItem> styleOptions; - bool mustAllocateStyleOptions; QStyleOptionGraphicsItem *allocStyleOptionsArray(int numItems); void freeStyleOptionsArray(QStyleOptionGraphicsItem *array); QBrush backgroundBrush; QBrush foregroundBrush; QPixmap backgroundPixmap; - bool mustResizeBackgroundPixmap; QRegion backgroundPixmapExposed; #ifndef QT_NO_CURSOR @@ -161,7 +167,6 @@ public: QRect mapToViewRect(const QGraphicsItem *item, const QRectF &rect) const; QRegion mapToViewRegion(const QGraphicsItem *item, const QRectF &rect) const; - bool fullUpdatePending; QRegion dirtyRegion; QRect dirtyBoundingRect; void processPendingUpdates(); @@ -192,6 +197,8 @@ public: #endif } + void setUpdateClip(QGraphicsItem *); + inline bool updateRectF(const QRectF &rect) { if (rect.isEmpty()) diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp index dce5c6a..b12cd45 100644 --- a/src/gui/itemviews/qsortfilterproxymodel.cpp +++ b/src/gui/itemviews/qsortfilterproxymodel.cpp @@ -1099,7 +1099,7 @@ void QSortFilterProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &sourc if (!source_top_left.isValid() || !source_bottom_right.isValid()) return; QModelIndex source_parent = source_top_left.parent(); - IndexMap::const_iterator it = create_mapping(source_parent); + IndexMap::const_iterator it = source_index_mapping.find(source_parent); if (it == source_index_mapping.constEnd()) { // Don't care, since we don't have mapping for this index return; diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 20d1d30..c058280 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -2535,7 +2535,7 @@ void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate, bool Q_Q(QWidget); QStyle *oldStyle = q->style(); #ifndef QT_NO_STYLE_STYLESHEET - QStyle *origStyle = 0; + QWeakPointer<QStyle> origStyle; #endif #ifdef Q_WS_MAC @@ -2549,7 +2549,7 @@ void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate, bool createExtra(); #ifndef QT_NO_STYLE_STYLESHEET - origStyle = extra->style; + origStyle = extra->style.data(); #endif extra->style = newStyle; } @@ -2578,23 +2578,23 @@ void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate, bool } } - QEvent e(QEvent::StyleChange); - QApplication::sendEvent(q, &e); -#ifdef QT3_SUPPORT - q->styleChange(*oldStyle); -#endif - #ifndef QT_NO_STYLE_STYLESHEET if (!qobject_cast<QStyleSheetStyle*>(newStyle)) { - if (const QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(origStyle)) { + if (const QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(origStyle.data())) { cssStyle->clearWidgetFont(q); } } #endif + QEvent e(QEvent::StyleChange); + QApplication::sendEvent(q, &e); +#ifdef QT3_SUPPORT + q->styleChange(*oldStyle); +#endif + #ifndef QT_NO_STYLE_STYLESHEET // dereference the old stylesheet style - if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(origStyle)) + if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(origStyle.data())) proxy->deref(); #endif } @@ -5583,52 +5583,23 @@ QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint * pixmapOffset = painterTransform.map(pixmapOffset); } - QRect effectRect; - if (mode == QGraphicsEffect::PadToEffectiveBoundingRect) { + if (mode == QGraphicsEffect::PadToEffectiveBoundingRect) effectRect = m_widget->graphicsEffect()->boundingRectFor(sourceRect).toAlignedRect(); - - } else if (mode == QGraphicsEffect::PadToTransparentBorder) { + else if (mode == QGraphicsEffect::PadToTransparentBorder) effectRect = sourceRect.adjusted(-1, -1, 1, 1).toAlignedRect(); - - } else { + else effectRect = sourceRect.toAlignedRect(); - } - if (offset) *offset = effectRect.topLeft(); - if (deviceCoordinates) { - // Clip to device rect. - int left, top, right, bottom; - effectRect.getCoords(&left, &top, &right, &bottom); - if (left < 0) { - if (offset) - offset->rx() += -left; - effectRect.setX(0); - } - if (top < 0) { - if (offset) - offset->ry() += -top; - effectRect.setY(0); - } - // NB! We use +-1 for historical reasons (see QRect documentation). - QPaintDevice *device = context->painter->device(); - const int deviceWidth = device->width(); - const int deviceHeight = device->height(); - if (right + 1 > deviceWidth) - effectRect.setRight(deviceWidth - 1); - if (bottom + 1 > deviceHeight) - effectRect.setBottom(deviceHeight -1); - } - pixmapOffset -= effectRect.topLeft(); QPixmap pixmap(effectRect.size()); pixmap.fill(Qt::transparent); - m_widget->render(&pixmap, pixmapOffset); + m_widget->render(&pixmap, pixmapOffset, QRegion(), QWidget::DrawChildren); return pixmap; } #endif //QT_NO_GRAPHICSEFFECT diff --git a/src/gui/painting/qtextureglyphcache_p.h b/src/gui/painting/qtextureglyphcache_p.h index 390fe51..a818978 100644 --- a/src/gui/painting/qtextureglyphcache_p.h +++ b/src/gui/painting/qtextureglyphcache_p.h @@ -125,7 +125,7 @@ protected: }; -class QImageTextureGlyphCache : public QTextureGlyphCache +class Q_GUI_EXPORT QImageTextureGlyphCache : public QTextureGlyphCache { public: QImageTextureGlyphCache(QFontEngineGlyphCache::Type type, const QTransform &matrix) diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp index 806654c..171000b 100644 --- a/src/gui/widgets/qdockarealayout.cpp +++ b/src/gui/widgets/qdockarealayout.cpp @@ -225,7 +225,7 @@ static const int zero = 0; QDockAreaLayoutInfo::QDockAreaLayoutInfo() : sep(&zero), dockPos(QInternal::LeftDock), o(Qt::Horizontal), mainWindow(0) #ifndef QT_NO_TABBAR - , tabbed(false), tabBar(0), tabBarShape(QTabBar::RoundedSouth), tabBarVisible(false) + , tabbed(false), tabBar(0), tabBarShape(QTabBar::RoundedSouth) #endif { } @@ -235,7 +235,7 @@ QDockAreaLayoutInfo::QDockAreaLayoutInfo(const int *_sep, QInternal::DockPositio QMainWindow *window) : sep(_sep), dockPos(_dockPos), o(_o), mainWindow(window) #ifndef QT_NO_TABBAR - , tabbed(false), tabBar(0), tabBarShape(static_cast<QTabBar::Shape>(tbshape)), tabBarVisible(false) + , tabbed(false), tabBar(0), tabBarShape(static_cast<QTabBar::Shape>(tbshape)) #endif { #ifdef QT_NO_TABBAR @@ -296,8 +296,8 @@ QSize QDockAreaLayoutInfo::minimumSize() const rperp(o, result) = b; #ifndef QT_NO_TABBAR - if (tabbed) { - QSize tbm = tabBarMinimumSize(); + QSize tbm = tabBarMinimumSize(); + if (!tbm.isNull()) { switch (tabBarShape) { case QTabBar::RoundedNorth: case QTabBar::RoundedSouth: @@ -369,8 +369,8 @@ QSize QDockAreaLayoutInfo::maximumSize() const rperp(o, result) = b; #ifndef QT_NO_TABBAR - if (tabbed) { - QSize tbh = tabBarSizeHint(); + QSize tbh = tabBarSizeHint(); + if (!tbh.isNull()) { switch (tabBarShape) { case QTabBar::RoundedNorth: case QTabBar::RoundedSouth: @@ -1500,7 +1500,7 @@ void QDockAreaLayoutInfo::apply(bool animate) QRect tab_rect; QSize tbh = tabBarSizeHint(); - if (tabBarVisible) { + if (!tbh.isNull()) { switch (tabBarShape) { case QTabBar::RoundedNorth: case QTabBar::TriangularNorth: @@ -2079,10 +2079,11 @@ void QDockAreaLayoutInfo::updateSeparatorWidgets() const #endif //QT_NO_TABBAR #ifndef QT_NO_TABBAR -void QDockAreaLayoutInfo::updateTabBar() const +//returns whether the tabbar is visible or not +bool QDockAreaLayoutInfo::updateTabBar() const { if (!tabbed) - return; + return false; QDockAreaLayoutInfo *that = const_cast<QDockAreaLayoutInfo*>(this); @@ -2150,12 +2151,8 @@ void QDockAreaLayoutInfo::updateTabBar() const tabBar->blockSignals(blocked); - that->tabBarVisible = ( (gap ? 1 : 0) + tabBar->count()) > 1; - - if (changed || !tabBarMin.isValid() | !tabBarHint.isValid()) { - that->tabBarMin = tabBar->minimumSizeHint(); - that->tabBarHint = tabBar->sizeHint(); - } + //returns if the tabbar is visible or not + return ( (gap ? 1 : 0) + tabBar->count()) > 1; } void QDockAreaLayoutInfo::setTabBarShape(int shape) @@ -2163,11 +2160,8 @@ void QDockAreaLayoutInfo::setTabBarShape(int shape) if (shape == tabBarShape) return; tabBarShape = shape; - if (tabBar != 0) { + if (tabBar != 0) tabBar->setShape(static_cast<QTabBar::Shape>(shape)); - tabBarMin = QSize(); - tabBarHint = QSize(); - } for (int i = 0; i < item_list.count(); ++i) { QDockAreaLayoutItem &item = item_list[i]; @@ -2178,22 +2172,18 @@ void QDockAreaLayoutInfo::setTabBarShape(int shape) QSize QDockAreaLayoutInfo::tabBarMinimumSize() const { - if (!tabbed) + if (!updateTabBar()) return QSize(0, 0); - updateTabBar(); - - return tabBarMin; + return tabBar->minimumSizeHint(); } QSize QDockAreaLayoutInfo::tabBarSizeHint() const { - if (!tabbed) + if (!updateTabBar()) return QSize(0, 0); - updateTabBar(); - - return tabBarHint; + return tabBar->sizeHint(); } QSet<QTabBar*> QDockAreaLayoutInfo::usedTabBars() const @@ -2240,7 +2230,7 @@ QRect QDockAreaLayoutInfo::tabContentRect() const QRect result = rect; QSize tbh = tabBarSizeHint(); - if (tabBarVisible) { + if (!tbh.isNull()) { switch (tabBarShape) { case QTabBar::RoundedNorth: case QTabBar::TriangularNorth: diff --git a/src/gui/widgets/qdockarealayout_p.h b/src/gui/widgets/qdockarealayout_p.h index 0088f00..9cb77ba 100644 --- a/src/gui/widgets/qdockarealayout_p.h +++ b/src/gui/widgets/qdockarealayout_p.h @@ -208,11 +208,9 @@ public: QRect tabContentRect() const; bool tabbed; QTabBar *tabBar; - QSize tabBarMin, tabBarHint; int tabBarShape; - bool tabBarVisible; - void updateTabBar() const; + bool updateTabBar() const; void setTabBarShape(int shape); QSize tabBarMinimumSize() const; QSize tabBarSizeHint() const; diff --git a/src/gui/widgets/qdockwidget.cpp b/src/gui/widgets/qdockwidget.cpp index 54189de..ae00710 100644 --- a/src/gui/widgets/qdockwidget.cpp +++ b/src/gui/widgets/qdockwidget.cpp @@ -1270,11 +1270,7 @@ void QDockWidget::setFloating(bool floating) d->setWindowState(floating, false, floating ? r : QRect()); if (floating && r.isNull()) { - QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(this->layout()); - QRect titleArea = layout->titleArea(); - int h = layout->verticalTitleBar ? titleArea.width() : titleArea.height(); - QPoint p = mapToGlobal(QPoint(h, h)); - move(p); + setAttribute(Qt::WA_Moved, false); //we want it at the default position } } diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp index 994c1c9..452d37d 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp @@ -42,6 +42,10 @@ #include "qtextureglyphcache_gl_p.h" #include "qpaintengineex_opengl2_p.h" +#if defined QT_OPENGL_ES_2 && !defined(QT_NO_EGL) +#include "private/qeglcontext_p.h" +#endif + QT_BEGIN_NAMESPACE #ifdef Q_WS_WIN @@ -49,12 +53,27 @@ extern Q_GUI_EXPORT bool qt_cleartype_enabled; #endif QGLTextureGlyphCache::QGLTextureGlyphCache(QGLContext *context, QFontEngineGlyphCache::Type type, const QTransform &matrix) - : QTextureGlyphCache(type, matrix) + : QImageTextureGlyphCache(type, matrix) , ctx(context) , m_width(0) , m_height(0) + , m_broken_fbo_readback(false) { - glGenFramebuffers(1, &m_fbo); + // broken FBO readback is a bug in the SGX 1.3 and 1.4 drivers for the N900 where + // copying between FBO's is broken if the texture is either GL_ALPHA or POT. The + // workaround is to use a system-memory copy of the glyph cache for this device. + // Switching to NPOT and GL_RGBA would both cost a lot more graphics memory and + // be slower, so that is not desireable. +#if defined QT_OPENGL_ES_2 && !defined(QT_NO_EGL) + if (QByteArray((char*) glGetString(GL_RENDERER)).contains("SGX")) { + QGLContextPrivate *ctxd = context->d_func(); + m_broken_fbo_readback = QByteArray((char *) eglQueryString(ctxd->eglContext->display(), EGL_VERSION)).contains("1.3"); + } +#endif + + if (!m_broken_fbo_readback) + glGenFramebuffers(1, &m_fbo); + connect(QGLSignalProxy::instance(), SIGNAL(aboutToDestroyContext(const QGLContext*)), SLOT(contextDestroyed(const QGLContext*))); } @@ -63,7 +82,9 @@ QGLTextureGlyphCache::~QGLTextureGlyphCache() { if (ctx) { QGLShareContextScope scope(ctx); - glDeleteFramebuffers(1, &m_fbo); + + if (!m_broken_fbo_readback) + glDeleteFramebuffers(1, &m_fbo); if (m_width || m_height) glDeleteTextures(1, &m_texture); @@ -72,6 +93,12 @@ QGLTextureGlyphCache::~QGLTextureGlyphCache() void QGLTextureGlyphCache::createTextureData(int width, int height) { + // create in QImageTextureGlyphCache baseclass is meant to be called + // only to create the initial image and does not preserve the content, + // so we don't call when this function is called from resize. + if (m_broken_fbo_readback && image().isNull()) + QImageTextureGlyphCache::createTextureData(width, height); + glGenTextures(1, &m_texture); glBindTexture(GL_TEXTURE_2D, m_texture); @@ -93,14 +120,22 @@ void QGLTextureGlyphCache::createTextureData(int width, int height) void QGLTextureGlyphCache::resizeTextureData(int width, int height) { - // ### the QTextureGlyphCache API needs to be reworked to allow - // ### resizeTextureData to fail - int oldWidth = m_width; int oldHeight = m_height; GLuint oldTexture = m_texture; createTextureData(width, height); + + if (m_broken_fbo_readback) { + QImageTextureGlyphCache::resizeTextureData(width, height); + Q_ASSERT(image().depth() == 8); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, oldWidth, oldHeight, GL_ALPHA, GL_UNSIGNED_BYTE, image().constBits()); + glDeleteTextures(1, &oldTexture); + return; + } + + // ### the QTextureGlyphCache API needs to be reworked to allow + // ### resizeTextureData to fail glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_fbo); @@ -159,20 +194,7 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height) glBindTexture(GL_TEXTURE_2D, m_texture); -#ifdef QT_OPENGL_ES_2 - QDataBuffer<uchar> buffer(4*oldWidth*oldHeight); - buffer.resize(4*oldWidth*oldHeight); - glReadPixels(0, 0, oldWidth, oldHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data()); - - // do an in-place conversion from GL_RGBA to GL_ALPHA - for (int i=0; i<oldWidth*oldHeight; ++i) - buffer.data()[i] = buffer.at(4*i + 3); - - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, oldWidth, oldHeight, - GL_ALPHA, GL_UNSIGNED_BYTE, buffer.data()); -#else glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight); -#endif glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, 0); @@ -187,6 +209,21 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height) void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph) { + if (m_broken_fbo_readback) { + QImageTextureGlyphCache::fillTexture(c, glyph); + + glBindTexture(GL_TEXTURE_2D, m_texture); + const QImage &texture = image(); + const uchar *bits = texture.constBits(); + bits += c.y * texture.bytesPerLine() + c.x; + for (int i=0; i<c.h; ++i) { + glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, c.w, 1, GL_ALPHA, GL_UNSIGNED_BYTE, bits); + bits += texture.bytesPerLine(); + } + + return; + } + QImage mask = textureMapForGlyph(glyph); const int maskWidth = mask.width(); const int maskHeight = mask.height(); @@ -235,17 +272,6 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph) } } -int QGLTextureGlyphCache::glyphMargin() const -{ -#if defined(Q_WS_MAC) - return 2; -#elif defined (Q_WS_X11) - return 0; -#else - return m_type == QFontEngineGlyphCache::Raster_RGBMask ? 2 : 0; -#endif -} - int QGLTextureGlyphCache::glyphPadding() const { return 1; diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h index 75c2bb1..efb7435 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h @@ -62,7 +62,7 @@ QT_BEGIN_NAMESPACE class QGL2PaintEngineExPrivate; -class Q_OPENGL_EXPORT QGLTextureGlyphCache : public QObject, public QTextureGlyphCache +class Q_OPENGL_EXPORT QGLTextureGlyphCache : public QObject, public QImageTextureGlyphCache { Q_OBJECT public: @@ -72,7 +72,6 @@ public: virtual void createTextureData(int width, int height); virtual void resizeTextureData(int width, int height); virtual void fillTexture(const Coord &c, glyph_t glyph); - virtual int glyphMargin() const; virtual int glyphPadding() const; inline GLuint texture() const { return m_texture; } @@ -116,6 +115,8 @@ private: int m_height; QGLShaderProgram *m_program; + + bool m_broken_fbo_readback; }; QT_END_NAMESPACE diff --git a/src/plugins/imageformats/svg/qsvgiohandler.cpp b/src/plugins/imageformats/svg/qsvgiohandler.cpp index 8155569..7b8463d 100644 --- a/src/plugins/imageformats/svg/qsvgiohandler.cpp +++ b/src/plugins/imageformats/svg/qsvgiohandler.cpp @@ -82,15 +82,19 @@ bool QSvgIOHandlerPrivate::load(QIODevice *device) if (q->format().isEmpty()) q->canRead(); + // # The SVG renderer doesn't handle trailing, unrelated data, so we must + // assume that all available data in the device is to be read. bool res = false; QBuffer *buf = qobject_cast<QBuffer *>(device); if (buf) { - res = r.load(buf->data()); + const QByteArray &ba = buf->data(); + res = r.load(QByteArray::fromRawData(ba.constData() + buf->pos(), ba.size() - buf->pos())); + buf->seek(ba.size()); } else if (q->format() == "svgz") { - res = r.load(device->readAll()); // ### can't stream svgz + res = r.load(device->readAll()); } else { xmlReader.setDevice(device); - res = r.load(&xmlReader); //### doesn't leave pos() correctly + res = r.load(&xmlReader); } if (res) { diff --git a/tests/auto/qbuffer/tst_qbuffer.cpp b/tests/auto/qbuffer/tst_qbuffer.cpp index fcef6a3..dd5ca91 100644 --- a/tests/auto/qbuffer/tst_qbuffer.cpp +++ b/tests/auto/qbuffer/tst_qbuffer.cpp @@ -76,6 +76,7 @@ private slots: void atEnd(); void readLineBoundaries(); void writeAfterQByteArrayResize(); + void read_null(); protected slots: void readyReadSlot(); @@ -529,5 +530,30 @@ void tst_QBuffer::writeAfterQByteArrayResize() QCOMPARE(buffer.buffer().size(), 1000); } +void tst_QBuffer::read_null() +{ + QByteArray buffer; + buffer.resize(32000); + for (int i = 0; i < buffer.size(); ++i) + buffer[i] = char(i & 0xff); + + QBuffer in(&buffer); + in.open(QIODevice::ReadOnly); + + QByteArray chunk; + + chunk.resize(16380); + in.read(chunk.data(), 16380); + + QCOMPARE(chunk, buffer.mid(0, chunk.size())); + + in.read(chunk.data(), 0); + + chunk.resize(8); + in.read(chunk.data(), chunk.size()); + + QCOMPARE(chunk, buffer.mid(16380, chunk.size())); +} + QTEST_MAIN(tst_QBuffer) #include "tst_qbuffer.moc" diff --git a/tests/auto/qdockwidget/tst_qdockwidget.cpp b/tests/auto/qdockwidget/tst_qdockwidget.cpp index a734985..3ac0ce7 100644 --- a/tests/auto/qdockwidget/tst_qdockwidget.cpp +++ b/tests/auto/qdockwidget/tst_qdockwidget.cpp @@ -96,6 +96,7 @@ private slots: void task248604_infiniteResize(); void task258459_visibilityChanged(); void taskQTBUG_1665_closableChanged(); + void taskQTBUG_9758_undockedGeometry(); }; // Testing get/set functions @@ -653,7 +654,7 @@ void tst_QDockWidget::dockLocationChanged() QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)), Qt::TopDockWidgetArea); spy.clear(); - + dw.setFloating(true); QTest::qWait(100); dw.setFloating(false); @@ -878,6 +879,26 @@ void tst_QDockWidget::taskQTBUG_1665_closableChanged() QVERIFY(!(dock.windowFlags() & Qt::WindowCloseButtonHint)); } +void tst_QDockWidget::taskQTBUG_9758_undockedGeometry() +{ + QMainWindow window; + QDockWidget dock1(&window); + QDockWidget dock2(&window); + window.addDockWidget(Qt::RightDockWidgetArea, &dock1); + window.addDockWidget(Qt::RightDockWidgetArea, &dock2); + window.tabifyDockWidget(&dock1, &dock2); + dock1.hide(); + dock2.hide(); + window.show(); + dock1.setFloating(true); + dock1.show(); + QTest::qWaitForWindowShown(&dock1); + + QVERIFY(dock1.x() >= 0); + QVERIFY(dock1.y() >= 0); +} + + QTEST_MAIN(tst_QDockWidget) #include "tst_qdockwidget.moc" diff --git a/tests/auto/qfiledialog/tst_qfiledialog.cpp b/tests/auto/qfiledialog/tst_qfiledialog.cpp index 38a1ee7..ca7c445 100644 --- a/tests/auto/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/qfiledialog/tst_qfiledialog.cpp @@ -529,10 +529,6 @@ void tst_QFiledialog::completer() #endif ++expected; } -#if !defined(Q_OS_WIN) - if (inputStartsWithRootPath) - expected++; -#endif } QTest::qWait(1000); diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index 1df9a37..b8df7f6 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -218,6 +218,7 @@ private slots: void update(); void update2_data(); void update2(); + void update_ancestorClipsChildrenToShape(); void inputMethodSensitivity(); void inputContextReset(); void indirectPainting(); @@ -3758,6 +3759,62 @@ void tst_QGraphicsView::update2() #endif } +void tst_QGraphicsView::update_ancestorClipsChildrenToShape() +{ + QGraphicsScene scene(-150, -150, 300, 300); + + /* + Add three rects: + + +------------------+ + | child | + | +--------------+ | + | | parent | | + | | +-----------+ | + | | |grandParent| | + | | +-----------+ | + | +--------------+ | + +------------------+ + + ... where both the parent and the grand parent clips children to shape. + */ + QApplication::processEvents(); // Get rid of pending update. + + QGraphicsRectItem *grandParent = static_cast<QGraphicsRectItem *>(scene.addRect(0, 0, 50, 50)); + grandParent->setBrush(Qt::black); + grandParent->setFlag(QGraphicsItem::ItemClipsChildrenToShape); + + QGraphicsRectItem *parent = static_cast<QGraphicsRectItem *>(scene.addRect(-50, -50, 100, 100)); + parent->setBrush(QColor(0, 0, 255, 125)); + parent->setParentItem(grandParent); + parent->setFlag(QGraphicsItem::ItemClipsChildrenToShape); + + QGraphicsRectItem *child = static_cast<QGraphicsRectItem *>(scene.addRect(-100, -100, 200, 200)); + child->setBrush(QColor(255, 0, 0, 125)); + child->setParentItem(parent); + + CustomView view(&scene); + view.show(); + QTest::qWaitForWindowShown(&view); + QTRY_VERIFY(view.painted); + + view.lastUpdateRegions.clear(); + view.painted = false; + + // Call child->update() and make sure the updated area is within the ancestors' clip. + QRectF expected = child->deviceTransform(view.viewportTransform()).mapRect(child->boundingRect()); + expected &= grandParent->deviceTransform(view.viewportTransform()).mapRect(grandParent->boundingRect()); + + child->update(); + QTRY_VERIFY(view.painted); + +#ifndef QT_MAC_USE_COCOA //cocoa doesn't support drawing regions + QTRY_VERIFY(view.painted); + QCOMPARE(view.lastUpdateRegions.size(), 1); + QCOMPARE(view.lastUpdateRegions.at(0), QRegion(expected.toAlignedRect())); +#endif +} + class FocusItem : public QGraphicsRectItem { public: diff --git a/tests/auto/qimagereader/tst_qimagereader.cpp b/tests/auto/qimagereader/tst_qimagereader.cpp index 1b4c502..aadee5b 100644 --- a/tests/auto/qimagereader/tst_qimagereader.cpp +++ b/tests/auto/qimagereader/tst_qimagereader.cpp @@ -114,6 +114,9 @@ private slots: void readFromFileAfterJunk_data(); void readFromFileAfterJunk(); + void devicePosition_data(); + void devicePosition(); + void setBackgroundColor_data(); void setBackgroundColor(); @@ -1117,7 +1120,7 @@ void tst_QImageReader::readFromFileAfterJunk() QByteArray imageData = imageFile.readAll(); QVERIFY(!imageData.isNull()); - int iterations = 10; + int iterations = 3; if (format == "ppm" || format == "pbm" || format == "pgm" || format == "svg" || format == "svgz") iterations = 1; @@ -1147,6 +1150,64 @@ void tst_QImageReader::readFromFileAfterJunk() } } +void tst_QImageReader::devicePosition_data() +{ + QTest::addColumn<QString>("fileName"); + QTest::addColumn<QByteArray>("format"); + + QTest::newRow("pbm") << QString("image.pbm") << QByteArray("pbm"); + QTest::newRow("pgm") << QString("image.pgm") << QByteArray("pgm"); + QTest::newRow("ppm-1") << QString("image.ppm") << QByteArray("ppm"); +#ifdef QTEST_HAVE_JPEG + QTest::newRow("jpeg-1") << QString("beavis.jpg") << QByteArray("jpeg"); + QTest::newRow("jpeg-2") << QString("YCbCr_cmyk.jpg") << QByteArray("jpeg"); + QTest::newRow("jpeg-3") << QString("YCbCr_rgb.jpg") << QByteArray("jpeg"); +#endif +#if defined QTEST_HAVE_GIF + QTest::newRow("gif-1") << QString("earth.gif") << QByteArray("gif"); +#endif + QTest::newRow("xbm") << QString("gnus.xbm") << QByteArray("xbm"); + QTest::newRow("xpm") << QString("marble.xpm") << QByteArray("xpm"); + QTest::newRow("bmp-1") << QString("colorful.bmp") << QByteArray("bmp"); + QTest::newRow("bmp-2") << QString("font.bmp") << QByteArray("bmp"); + QTest::newRow("png") << QString("kollada.png") << QByteArray("png"); +// QTest::newRow("mng-1") << QString("images/ball.mng") << QByteArray("mng"); +// QTest::newRow("mng-2") << QString("images/fire.mng") << QByteArray("mng"); +#if defined QTEST_HAVE_SVG + QTest::newRow("svg") << QString("rect.svg") << QByteArray("svg"); + QTest::newRow("svgz") << QString("rect.svgz") << QByteArray("svgz"); +#endif +} + +void tst_QImageReader::devicePosition() +{ + QFETCH(QString, fileName); + QFETCH(QByteArray, format); + + QImage expected(prefix + fileName); + QVERIFY(!expected.isNull()); + + QFile imageFile(prefix + fileName); + QVERIFY(imageFile.open(QFile::ReadOnly)); + QByteArray imageData = imageFile.readAll(); + QVERIFY(!imageData.isNull()); + int imageDataSize = imageData.size(); + + const char *preStr = "prebeef\n"; + int preLen = qstrlen(preStr); + imageData.prepend(preStr); + if (format != "svg" && format != "svgz") // Doesn't handle trailing data + imageData.append("\npostbeef"); + QBuffer buf(&imageData); + buf.open(QIODevice::ReadOnly); + buf.seek(preLen); + QImageReader reader(&buf, format); + QCOMPARE(expected, reader.read()); + if (format != "ppm" && format != "gif") // Known not to work + QCOMPARE(buf.pos(), qint64(preLen+imageDataSize)); +} + + void tst_QImageReader::description_data() { QTest::addColumn<QString>("fileName"); diff --git a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp index 2339b21..992c95e 100644 --- a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp @@ -138,6 +138,7 @@ private slots: void taskQTBUG_6205_doubleProxySelectionSetSourceModel(); void taskQTBUG_7537_appearsAndSort(); void taskQTBUG_7716_unnecessaryDynamicSorting(); + void taskQTBUG_10287_unnecessaryMapCreation(); void testMultipleProxiesWithSelection(); @@ -3038,5 +3039,65 @@ void tst_QSortFilterProxyModel::testMultipleProxiesWithSelection() } +class Model10287 : public QStandardItemModel +{ + Q_OBJECT + +public: + Model10287(QObject *parent = 0) + : QStandardItemModel(0, 1, parent) + { + parentItem = new QStandardItem("parent"); + parentItem->setData(false, Qt::UserRole); + appendRow(parentItem); + + childItem = new QStandardItem("child"); + childItem->setData(true, Qt::UserRole); + parentItem->appendRow(childItem); + + childItem2 = new QStandardItem("child2"); + childItem2->setData(true, Qt::UserRole); + parentItem->appendRow(childItem2); + } + + void removeChild() + { + childItem2->setData(false, Qt::UserRole); + parentItem->removeRow(0); + } + +private: + QStandardItem *parentItem, *childItem, *childItem2; +}; + +class Proxy10287 : public QSortFilterProxyModel +{ + Q_OBJECT + +public: + Proxy10287(QAbstractItemModel *model, QObject *parent = 0) + : QSortFilterProxyModel(parent) + { + setSourceModel(model); + setDynamicSortFilter(true); + } + +protected: + virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const + { + // Filter based on UserRole in model + QModelIndex i = sourceModel()->index(source_row, 0, source_parent); + return i.data(Qt::UserRole).toBool(); + } +}; + +void tst_QSortFilterProxyModel::taskQTBUG_10287_unnecessaryMapCreation() +{ + Model10287 m; + Proxy10287 p(&m); + m.removeChild(); + // No assert failure, it passes. +} + QTEST_MAIN(tst_QSortFilterProxyModel) #include "tst_qsortfilterproxymodel.moc" diff --git a/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp index e0512a9..e370309 100644 --- a/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp +++ b/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp @@ -98,6 +98,7 @@ private slots: void complexWidgetFocus(); void task188195_baseBackground(); void task232085_spinBoxLineEditBg(); + void changeStyleInChangeEvent(); //at the end because it mess with the style. void widgetStyle(); @@ -1256,7 +1257,7 @@ void tst_QStyleSheetStyle::proxyStyle() QStyleOptionViewItemV4 opt; opt.initFrom(w); opt.features |= QStyleOptionViewItemV2::HasCheckIndicator; - QVERIFY(pb5->style()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, + QVERIFY(pb5->style()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &opt, pb5).width() == 3); delete w; delete proxy; @@ -1579,6 +1580,34 @@ void tst_QStyleSheetStyle::task232085_spinBoxLineEditBg() .toLocal8Bit().constData()); } +class ChangeEventWidget : public QWidget +{ public: + void changeEvent(QEvent * event) + { + if(event->type() == QEvent::StyleChange) { + static bool recurse = false; + if (!recurse) { + recurse = true; + QStyle *style = new QMotifStyle; + style->setParent(this); + setStyle(style); + recurse = false; + } + } + QWidget::changeEvent(event); + } +}; + +void tst_QStyleSheetStyle::changeStyleInChangeEvent() +{ //must not crash; + ChangeEventWidget wid; + wid.ensurePolished(); + wid.setStyleSheet(" /* */ "); + wid.ensurePolished(); + wid.setStyleSheet(" /* ** */ "); + wid.ensurePolished(); +} + QTEST_MAIN(tst_QStyleSheetStyle) #include "tst_qstylesheetstyle.moc" |