diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2011-05-13 00:03:52 +1000 |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2011-05-13 00:03:52 +1000 |
commit | 46ecdac5c9ffb33c22d57f9249fe133aca871a3d (patch) | |
tree | 234ad13c153be1b2548d88edfca00d2a7215f445 | |
parent | c31a354bd192bfd24b0ba88add439347ac73659c (diff) | |
parent | 38ed8c2dddfe55c4a940adb534fa41ecae02af69 (diff) |
Merge branch 'master' of git://scm.dev.nokia.troll.no/qt/qtbase-staging
* 'master' of git://scm.dev.nokia.troll.no/qt/qtbase-staging:
Make QLineControl send accessibility updates.
Revert "Fix double painting when adding an item into a linear layout"
Fix licence headers again for MR 900
Improve invalidate() testcase.
Avoid flicker when invalidate is propagated in a widget/layout hierarchy
Fix licence headers again for MR 900
18 files changed, 615 insertions, 176 deletions
diff --git a/doc/src/snippets/code/src_gui_itemviews_qidentityproxymodel.cpp b/doc/src/snippets/code/src_gui_itemviews_qidentityproxymodel.cpp index 8bd65208cb..6bf6c895f6 100644 --- a/doc/src/snippets/code/src_gui_itemviews_qidentityproxymodel.cpp +++ b/doc/src/snippets/code/src_gui_itemviews_qidentityproxymodel.cpp @@ -1,8 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Klarälvdalens Datakonsult AB, -** a KDAB Group company, info@kdab.com, -** author Stephen Kelly <stephen.kelly@kdab.com> +** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com> ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h index 871ca58995..1e9e55e16f 100644 --- a/src/gui/accessible/qaccessible.h +++ b/src/gui/accessible/qaccessible.h @@ -111,8 +111,8 @@ public: TableSummaryChanged, TextAttributeChanged, TextCaretMoved, - TextChanged, - TextColumnChanged, + // TextChanged, deprecated, use TextUpdated + TextColumnChanged = TextCaretMoved + 2, TextInserted, TextRemoved, TextUpdated, diff --git a/src/gui/graphicsview/qgraphicslayout.cpp b/src/gui/graphicsview/qgraphicslayout.cpp index 5bd298061d..a67ae48cc7 100644 --- a/src/gui/graphicsview/qgraphicslayout.cpp +++ b/src/gui/graphicsview/qgraphicslayout.cpp @@ -269,12 +269,20 @@ void QGraphicsLayout::activate() return; Q_ASSERT(!parentItem->isLayout()); - setGeometry(parentItem->contentsRect()); // relayout children + if (QGraphicsLayout::instantInvalidatePropagation()) { + QGraphicsWidget *parentWidget = static_cast<QGraphicsWidget*>(parentItem); + if (!parentWidget->parentLayoutItem()) { + // we've reached the topmost widget, resize it + bool wasResized = parentWidget->testAttribute(Qt::WA_Resized); + parentWidget->resize(parentWidget->size()); + parentWidget->setAttribute(Qt::WA_Resized, wasResized); + } - // ### bug, should be parentItem ? - parentLayoutItem()->updateGeometry(); // bubble up; will set activated to false - // ### too many resizes? maybe we should walk up the chain to the - // ### top-level layouted layoutItem and call activate there. + setGeometry(parentItem->contentsRect()); // relayout children + } else { + setGeometry(parentItem->contentsRect()); // relayout children + parentLayoutItem()->updateGeometry(); + } } /*! @@ -300,32 +308,36 @@ bool QGraphicsLayout::isActivated() const */ void QGraphicsLayout::invalidate() { - // only mark layouts as invalid (activated = false) if we can post a LayoutRequest event. - QGraphicsLayoutItem *layoutItem = this; - while (layoutItem && layoutItem->isLayout()) { - // we could call updateGeometry(), but what if that method - // does not call the base implementation? In addition, updateGeometry() - // does more than we need. - layoutItem->d_func()->sizeHintCacheDirty = true; - layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true; - layoutItem = layoutItem->parentLayoutItem(); - } - if (layoutItem) { - layoutItem->d_func()->sizeHintCacheDirty = true; - layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true; - } - - bool postIt = layoutItem ? !layoutItem->isLayout() : false; - if (postIt) { - layoutItem = this; - while (layoutItem && layoutItem->isLayout() - && static_cast<QGraphicsLayout*>(layoutItem)->d_func()->activated) { - static_cast<QGraphicsLayout*>(layoutItem)->d_func()->activated = false; + if (QGraphicsLayout::instantInvalidatePropagation()) { + updateGeometry(); + } else { + // only mark layouts as invalid (activated = false) if we can post a LayoutRequest event. + QGraphicsLayoutItem *layoutItem = this; + while (layoutItem && layoutItem->isLayout()) { + // we could call updateGeometry(), but what if that method + // does not call the base implementation? In addition, updateGeometry() + // does more than we need. + layoutItem->d_func()->sizeHintCacheDirty = true; + layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true; layoutItem = layoutItem->parentLayoutItem(); } - if (layoutItem && !layoutItem->isLayout()) { - // If a layout has a parent that is not a layout it must be a QGraphicsWidget. - QApplication::postEvent(static_cast<QGraphicsWidget *>(layoutItem), new QEvent(QEvent::LayoutRequest)); + if (layoutItem) { + layoutItem->d_func()->sizeHintCacheDirty = true; + layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true; + } + + bool postIt = layoutItem ? !layoutItem->isLayout() : false; + if (postIt) { + layoutItem = this; + while (layoutItem && layoutItem->isLayout() + && static_cast<QGraphicsLayout*>(layoutItem)->d_func()->activated) { + static_cast<QGraphicsLayout*>(layoutItem)->d_func()->activated = false; + layoutItem = layoutItem->parentLayoutItem(); + } + if (layoutItem && !layoutItem->isLayout()) { + // If a layout has a parent that is not a layout it must be a QGraphicsWidget. + QApplication::postEvent(static_cast<QGraphicsWidget *>(layoutItem), new QEvent(QEvent::LayoutRequest)); + } } } } @@ -335,12 +347,27 @@ void QGraphicsLayout::invalidate() */ void QGraphicsLayout::updateGeometry() { - QGraphicsLayoutItem::updateGeometry(); - if (QGraphicsLayoutItem *parentItem = parentLayoutItem()) { - if (parentItem->isLayout()) { + Q_D(QGraphicsLayout); + if (QGraphicsLayout::instantInvalidatePropagation()) { + d->activated = false; + QGraphicsLayoutItem::updateGeometry(); + + QGraphicsLayoutItem *parentItem = parentLayoutItem(); + if (!parentItem) + return; + + if (parentItem->isLayout()) + static_cast<QGraphicsLayout *>(parentItem)->invalidate(); + else parentItem->updateGeometry(); - } else { - invalidate(); + } else { + QGraphicsLayoutItem::updateGeometry(); + if (QGraphicsLayoutItem *parentItem = parentLayoutItem()) { + if (parentItem->isLayout()) { + parentItem->updateGeometry(); + } else { + invalidate(); + } } } } @@ -446,6 +473,50 @@ void QGraphicsLayout::addChildLayoutItem(QGraphicsLayoutItem *layoutItem) d->addChildLayoutItem(layoutItem); } +static bool g_instantInvalidatePropagation = false; + +/*! + \internal + \since 4.8 + \see instantInvalidatePropagation + + Calling this function with \a enable set to true will enable a feature that + makes propagation of invalidation up to ancestor layout items to be done in + one go. It will propagate up the parentLayoutItem() hierarchy until it has + reached the root. If the root item is a QGraphicsWidget, it will *post* a + layout request to it. When the layout request is consumed it will traverse + down the hierarchy of layouts and widgets and activate all layouts that is + invalid (not activated). This is the recommended behaviour. + + If not set it will also propagate up the parentLayoutItem() hierarchy, but + it will stop at the \i first \i widget it encounters, and post a layout + request to the widget. When the layout request is consumed, this might + cause it to continue propagation up to the parentLayoutItem() of the + widget. It will continue in this fashion until it has reached a widget with + no parentLayoutItem(). This strategy might cause drawing artifacts, since + it is not done in one go, and the consumption of layout requests might be + interleaved by consumption of paint events, which might cause significant + flicker. + Note, this is not the recommended behavior, but for compatibility reasons + this is the default behaviour. +*/ +void QGraphicsLayout::setInstantInvalidatePropagation(bool enable) +{ + g_instantInvalidatePropagation = enable; +} + +/*! + \internal + \since 4.8 + \see setInstantInvalidatePropagation + + returns true if the complete widget/layout hierarchy is rearranged in one go. +*/ +bool QGraphicsLayout::instantInvalidatePropagation() +{ + return g_instantInvalidatePropagation; +} + QT_END_NAMESPACE #endif //QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicslayout.h b/src/gui/graphicsview/qgraphicslayout.h index c622fb881e..60311744a2 100644 --- a/src/gui/graphicsview/qgraphicslayout.h +++ b/src/gui/graphicsview/qgraphicslayout.h @@ -76,6 +76,8 @@ public: virtual QGraphicsLayoutItem *itemAt(int i) const = 0; virtual void removeAt(int index) = 0; + static void setInstantInvalidatePropagation(bool enable); + static bool instantInvalidatePropagation(); protected: QGraphicsLayout(QGraphicsLayoutPrivate &, QGraphicsLayoutItem *); void addChildLayoutItem(QGraphicsLayoutItem *layoutItem); diff --git a/src/gui/graphicsview/qgraphicslayout_p.cpp b/src/gui/graphicsview/qgraphicslayout_p.cpp index c325602cc6..05e6cdf599 100644 --- a/src/gui/graphicsview/qgraphicslayout_p.cpp +++ b/src/gui/graphicsview/qgraphicslayout_p.cpp @@ -180,9 +180,14 @@ void QGraphicsLayoutPrivate::activateRecursive(QGraphicsLayoutItem *item) { if (item->isLayout()) { QGraphicsLayout *layout = static_cast<QGraphicsLayout *>(item); - if (layout->d_func()->activated) - layout->invalidate(); - + if (layout->d_func()->activated) { + if (QGraphicsLayout::instantInvalidatePropagation()) { + return; + } else { + layout->invalidate(); // ### LOOKS SUSPICIOUSLY WRONG!!??? + } + } + for (int i = layout->count() - 1; i >= 0; --i) { QGraphicsLayoutItem *childItem = layout->itemAt(i); if (childItem) diff --git a/src/gui/graphicsview/qgraphicslinearlayout.cpp b/src/gui/graphicsview/qgraphicslinearlayout.cpp index 5591638395..40f9b1de71 100644 --- a/src/gui/graphicsview/qgraphicslinearlayout.cpp +++ b/src/gui/graphicsview/qgraphicslinearlayout.cpp @@ -275,17 +275,13 @@ void QGraphicsLinearLayout::insertItem(int index, QGraphicsLayoutItem *item) qWarning("QGraphicsLinearLayout::insertItem: cannot insert itself"); return; } - Q_ASSERT(item); - - //the order of the following instructions is very important because - //invalidating the layout before adding the child item will make the layout happen - //before we try to paint the item - invalidate(); d->addChildLayoutItem(item); + Q_ASSERT(item); d->fixIndex(&index); d->engine.insertRow(index, d->orientation); new QGridLayoutItem(&d->engine, item, d->gridRow(index), d->gridColumn(index), 1, 1, 0, index); + invalidate(); } /*! diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 675a5c5c77..141e305acd 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -354,8 +354,10 @@ void QGraphicsWidget::setGeometry(const QRectF &rect) newGeom = rect; newGeom.setSize(rect.size().expandedTo(effectiveSizeHint(Qt::MinimumSize)) .boundedTo(effectiveSizeHint(Qt::MaximumSize))); - if (newGeom == d->geom) - return; + + if (newGeom == d->geom) { + goto relayoutChildrenAndReturn; + } // setPos triggers ItemPositionChange, which can adjust position wd->inSetGeometry = 1; @@ -363,8 +365,9 @@ void QGraphicsWidget::setGeometry(const QRectF &rect) wd->inSetGeometry = 0; newGeom.moveTopLeft(pos()); - if (newGeom == d->geom) - return; + if (newGeom == d->geom) { + goto relayoutChildrenAndReturn; + } // Update and prepare to change the geometry (remove from index) if the size has changed. if (wd->scene) { @@ -375,35 +378,54 @@ void QGraphicsWidget::setGeometry(const QRectF &rect) } // Update the layout item geometry - bool moved = oldPos != pos(); - if (moved) { - // Send move event. - QGraphicsSceneMoveEvent event; - event.setOldPos(oldPos); - event.setNewPos(pos()); - QApplication::sendEvent(this, &event); - if (wd->inSetPos) { - //set the new pos - d->geom.moveTopLeft(pos()); - emit geometryChanged(); - return; + { + bool moved = oldPos != pos(); + if (moved) { + // Send move event. + QGraphicsSceneMoveEvent event; + event.setOldPos(oldPos); + event.setNewPos(pos()); + QApplication::sendEvent(this, &event); + if (wd->inSetPos) { + //set the new pos + d->geom.moveTopLeft(pos()); + emit geometryChanged(); + goto relayoutChildrenAndReturn; + } + } + QSizeF oldSize = size(); + QGraphicsLayoutItem::setGeometry(newGeom); + // Send resize event + bool resized = newGeom.size() != oldSize; + if (resized) { + QGraphicsSceneResizeEvent re; + re.setOldSize(oldSize); + re.setNewSize(newGeom.size()); + if (oldSize.width() != newGeom.size().width()) + emit widthChanged(); + if (oldSize.height() != newGeom.size().height()) + emit heightChanged(); + QGraphicsLayout *lay = wd->layout; + if (QGraphicsLayout::instantInvalidatePropagation()) { + if (!lay || lay->isActivated()) { + QApplication::sendEvent(this, &re); + } + } else { + QApplication::sendEvent(this, &re); + } } } - QSizeF oldSize = size(); - QGraphicsLayoutItem::setGeometry(newGeom); - // Send resize event - bool resized = newGeom.size() != oldSize; - if (resized) { - QGraphicsSceneResizeEvent re; - re.setOldSize(oldSize); - re.setNewSize(newGeom.size()); - if (oldSize.width() != newGeom.size().width()) - emit widthChanged(); - if (oldSize.height() != newGeom.size().height()) - emit heightChanged(); - QApplication::sendEvent(this, &re); - } + emit geometryChanged(); +relayoutChildrenAndReturn: + if (QGraphicsLayout::instantInvalidatePropagation()) { + if (QGraphicsLayout *lay = wd->layout) { + if (!lay->isActivated()) { + QEvent layoutRequest(QEvent::LayoutRequest); + QApplication::sendEvent(this, &layoutRequest); + } + } + } } /*! @@ -1052,16 +1074,31 @@ void QGraphicsWidget::updateGeometry() QGraphicsLayoutItem *parentItem = parentLayoutItem(); if (parentItem && parentItem->isLayout()) { - parentItem->updateGeometry(); + if (QGraphicsLayout::instantInvalidatePropagation()) { + static_cast<QGraphicsLayout *>(parentItem)->invalidate(); + } else { + parentItem->updateGeometry(); + } } else { if (parentItem) { + // This is for custom layouting QGraphicsWidget *parentWid = parentWidget(); //### if (parentWid->isVisible()) QApplication::postEvent(parentWid, new QEvent(QEvent::LayoutRequest)); + } else { + /** + * If this is the topmost widget, post a LayoutRequest event to the widget. + * When the event is received, it will start flowing all the way down to the leaf + * widgets in one go. This will make a relayout flicker-free. + */ + if (QGraphicsLayout::instantInvalidatePropagation()) + QApplication::postEvent(static_cast<QGraphicsWidget *>(this), new QEvent(QEvent::LayoutRequest)); + } + if (!QGraphicsLayout::instantInvalidatePropagation()) { + bool wasResized = testAttribute(Qt::WA_Resized); + resize(size()); // this will restrict the size + setAttribute(Qt::WA_Resized, wasResized); } - bool wasResized = testAttribute(Qt::WA_Resized); - resize(size()); // this will restrict the size - setAttribute(Qt::WA_Resized, wasResized); } } diff --git a/src/gui/itemviews/qidentityproxymodel.cpp b/src/gui/itemviews/qidentityproxymodel.cpp index 9396e6199a..60f7d98bd8 100644 --- a/src/gui/itemviews/qidentityproxymodel.cpp +++ b/src/gui/itemviews/qidentityproxymodel.cpp @@ -1,13 +1,18 @@ /**************************************************************************** ** -** Copyright (C) 2011 Klarälvdalens Datakonsult AB, -** a KDAB Group company, info@kdab.com, -** author Stephen Kelly <stephen.kelly@kdab.com> +** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com> ** All rights reserved. -** Contact: Nokia Corporation (info@qt.nokia.com) +** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. ** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software @@ -20,17 +25,17 @@ ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** ** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/gui/itemviews/qidentityproxymodel.h b/src/gui/itemviews/qidentityproxymodel.h index b60aa0b7c9..4b3176a5b5 100644 --- a/src/gui/itemviews/qidentityproxymodel.h +++ b/src/gui/itemviews/qidentityproxymodel.h @@ -1,13 +1,18 @@ /**************************************************************************** ** -** Copyright (C) 2011 Klarälvdalens Datakonsult AB, -** a KDAB Group company, info@kdab.com, -** author Stephen Kelly <stephen.kelly@kdab.com> +** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com> ** All rights reserved. -** Contact: Nokia Corporation (info@qt.nokia.com) +** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. ** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software @@ -20,17 +25,17 @@ ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** ** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp index 40ebb65d0a..2a15555b89 100644 --- a/src/gui/widgets/qlinecontrol.cpp +++ b/src/gui/widgets/qlinecontrol.cpp @@ -651,7 +651,12 @@ void QLineControl::internalSetText(const QString &txt, int pos, bool edited) m_modifiedState = m_undoState = 0; m_cursor = (pos < 0 || pos > m_text.length()) ? m_text.length() : pos; m_textDirty = (oldText != m_text); - finishChange(-1, true, edited); + bool changed = finishChange(-1, true, edited); + +#ifndef QT_NO_ACCESSIBILITY + if (changed) + QAccessible::updateAccessibility(parent(), 0, QAccessible::TextUpdated); +#endif } @@ -1238,6 +1243,9 @@ void QLineControl::emitCursorPositionChanged() const int oldLast = m_lastCursorPos; m_lastCursorPos = m_cursor; cursorPositionChanged(oldLast, m_cursor); +#ifndef QT_NO_ACCESSIBILITY + QAccessible::updateAccessibility(parent(), 0, QAccessible::TextCaretMoved); +#endif } } diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h index 6918b83b90..9764ba9c59 100644 --- a/src/gui/widgets/qlinecontrol_p.h +++ b/src/gui/widgets/qlinecontrol_p.h @@ -61,10 +61,10 @@ #include "QtGui/qtextlayout.h" #include "QtGui/qstyleoption.h" #include "QtCore/qpointer.h" -#include "QtGui/qlineedit.h" #include "QtGui/qclipboard.h" #include "QtCore/qpoint.h" #include "QtGui/qcompleter.h" +#include "QtGui/qaccessible.h" QT_BEGIN_HEADER diff --git a/src/gui/widgets/qlineedit_p.cpp b/src/gui/widgets/qlineedit_p.cpp index 23ac61384f..03716d4c66 100644 --- a/src/gui/widgets/qlineedit_p.cpp +++ b/src/gui/widgets/qlineedit_p.cpp @@ -153,6 +153,7 @@ void QLineEditPrivate::init(const QString& txt) { Q_Q(QLineEdit); control = new QLineControl(txt); + control->setParent(q); control->setFont(q->font()); QObject::connect(control, SIGNAL(textChanged(QString)), q, SIGNAL(textChanged(QString))); diff --git a/src/gui/widgets/qlineedit_p.h b/src/gui/widgets/qlineedit_p.h index 32f6077438..31697764e9 100644 --- a/src/gui/widgets/qlineedit_p.h +++ b/src/gui/widgets/qlineedit_p.h @@ -84,7 +84,6 @@ public: ~QLineEditPrivate() { - delete control; } QLineControl *control; diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index e7c63d540e..447385a7d8 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -1091,6 +1091,9 @@ void tst_QGraphicsAnchorLayout::setSpacing() #ifdef Q_WS_MAC QTest::qWait(200); #endif + + // 21x21 + QCOMPARE(p->size(), QSizeF(41, 41)); QCOMPARE(a->geometry(), QRectF(0, 0, 20, 20)); QCOMPARE(b->geometry(), QRectF(21, 0, 20, 20)); QCOMPARE(c->geometry(), QRectF(0, 21, 41, 20)); diff --git a/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp b/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp index 979f03df64..29ea07460e 100644 --- a/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp +++ b/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp @@ -62,6 +62,7 @@ private slots: void compressLayoutRequest(); void automaticReparenting(); void verifyActivate(); + void invalidate(); void constructors(); void alternativeLayoutItems(); void ownership(); @@ -95,6 +96,14 @@ void tst_QGraphicsLayout::sizeHints() } +enum FunctionType { + SetGeometry = 0, + Invalidate, + NumFunctionTypes +}; + + + class TestGraphicsWidget : public QGraphicsWidget { public: TestGraphicsWidget(QGraphicsWidget *parent = 0) : QGraphicsWidget(parent) @@ -108,9 +117,28 @@ public: int eventCount(QEvent::Type type) { return m_eventCount.value(int(type)); } + void clearEventCount() { m_eventCount.clear(); } + + void clearCounters() { + m_eventCount.clear(); + functionCount.clear(); + } + + void setGeometry(const QRectF &rect) + { + QGraphicsWidget::setGeometry(rect); + ++(functionCount[SetGeometry]); + } + + void callUpdateGeometry() + { + // updateGeometry() is protected + QGraphicsWidget::updateGeometry(); + } + QMap<FunctionType, int> functionCount; private: QMap<int, int> m_eventCount; }; @@ -122,6 +150,8 @@ void tst_QGraphicsLayout::compressLayoutRequest() TestGraphicsWidget *tw = new TestGraphicsWidget(); scene.addItem(tw); view.show(); + + QTest::qWaitForWindowShown(&view); QGraphicsLinearLayout *lout = new QGraphicsLinearLayout(tw); for (int i = 0; i < 4; ++i) { QGraphicsWidget *gw = new QGraphicsWidget(tw); @@ -217,17 +247,27 @@ class TestLayout : public QGraphicsLinearLayout TestLayout(QGraphicsLayoutItem *parent = 0) : QGraphicsLinearLayout(parent) { - m_count = 0; + setContentsMargins(0,0,0,0); + setSpacing(0); } - void setGeometry(const QRectF &rect) { - - ++m_count; + void setGeometry(const QRectF &rect) + { + ++(functionCount[SetGeometry]); QGraphicsLinearLayout::setGeometry(rect); } + void invalidate() + { + ++(functionCount[Invalidate]); + QGraphicsLinearLayout::invalidate(); + } + + void clearCounters() { + functionCount.clear(); + } - int m_count; + QMap<FunctionType, int> functionCount; }; void tst_QGraphicsLayout::verifyActivate() @@ -242,13 +282,278 @@ void tst_QGraphicsLayout::verifyActivate() lout->addItem(w); window->setLayout(lout); - QCOMPARE(lout->m_count, 0); + QCOMPARE(lout->functionCount[SetGeometry], 0); window->setVisible(false); - QCOMPARE(lout->m_count, 0); + QCOMPARE(lout->functionCount[SetGeometry], 0); window->setVisible(true); // on polish or the first time a widget is shown, the widget is resized. - QCOMPARE(lout->m_count, 1); + QCOMPARE(lout->functionCount[SetGeometry], 1); + +} + +static void clearAllCounters(TestGraphicsWidget *widget) +{ + if (!widget) + return; + widget->clearCounters(); + TestLayout *layout = static_cast<TestLayout *>(widget->layout()); + if (layout) { + layout->clearCounters(); + for (int i = layout->count() - 1; i >=0; --i) { + QGraphicsLayoutItem *item = layout->itemAt(i); + if (item->isLayout()) { + // ### Not used ATM + //TestLayout *lay = static_cast<TestLayout*>(static_cast<QGraphicsLayout*>(item)); + //clearAllCounters(lay); + } else { + TestGraphicsWidget *wid = static_cast<TestGraphicsWidget *>(item); + clearAllCounters(wid); + } + } + } +} + +static void activateAndReset(TestGraphicsWidget *widget) +{ + QApplication::sendPostedEvents(); + QApplication::processEvents(); + if (widget->layout()) + widget->layout()->activate(); + clearAllCounters(widget); +} + + +void tst_QGraphicsLayout::invalidate() +{ + QGraphicsLayout::setInstantInvalidatePropagation(true); + QGraphicsScene scene; + QGraphicsView view(&scene); + + TestGraphicsWidget *a = new TestGraphicsWidget; + a->setData(0, QString("a")); + scene.addItem(a); + TestLayout *alay = new TestLayout(a); + TestGraphicsWidget *b = new TestGraphicsWidget; + b->setData(0, QString("b")); + alay->addItem(b); + TestLayout *blay = new TestLayout(b); + TestGraphicsWidget *e = new TestGraphicsWidget; + e->setData(0, QString("e")); + blay->addItem(e); + + + TestGraphicsWidget *c = new TestGraphicsWidget; + c->setData(0, QString("c")); + alay->addItem(c); + TestLayout *clay = new TestLayout(c); + TestGraphicsWidget *f = new TestGraphicsWidget; + f->setData(0, QString("f")); + clay->addItem(f); + + TestGraphicsWidget *d = new TestGraphicsWidget; + d->setData(0, QString("d")); + alay->addItem(d); + TestLayout *dlay = new TestLayout(d); + TestGraphicsWidget *g = new TestGraphicsWidget; + g->setData(0, QString("g")); + dlay->addItem(g); + + view.show(); + + { + clearAllCounters(a); + + QCoreApplication::sendPostedEvents(); + QCoreApplication::processEvents(); + + alay->activate(); + QCOMPARE(alay->isActivated(), true); + QCOMPARE(blay->isActivated(), true); + QCOMPARE(clay->isActivated(), true); + QCOMPARE(dlay->isActivated(), true); + } + + { + clearAllCounters(a); + e->callUpdateGeometry(); + QCOMPARE(alay->isActivated(), false); + QCOMPARE(blay->isActivated(), false); + QCOMPARE(clay->isActivated(), true); + QCOMPARE(dlay->isActivated(), true); + QCOMPARE(a->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0); + + // should only invalidate ascendants of e + QCOMPARE(blay->functionCount[Invalidate], 1); + QCOMPARE(alay->functionCount[Invalidate], 1); + // not siblings + QCOMPARE(clay->functionCount[Invalidate], 0); + QCOMPARE(dlay->functionCount[Invalidate], 0); + + QApplication::sendPostedEvents(); + QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(b->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0); + } + + { + activateAndReset(a); + f->callUpdateGeometry(); + QCOMPARE(alay->isActivated(), false); + QCOMPARE(blay->isActivated(), true); + QCOMPARE(clay->isActivated(), false); + QCOMPARE(dlay->isActivated(), true); + + QCoreApplication::sendPostedEvents(); + QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0); + + QCOMPARE(a->functionCount[SetGeometry], 1); + QCOMPARE(alay->functionCount[SetGeometry], 1); + + QCOMPARE(b->functionCount[SetGeometry], 1); + QCOMPARE(c->functionCount[SetGeometry], 1); + QCOMPARE(d->functionCount[SetGeometry], 1); + // Since nothing really changed, blay and dlay don't need + // to be resized. + QCOMPARE(blay->functionCount[SetGeometry], 0); + QCOMPARE(clay->functionCount[SetGeometry], 1); + QCOMPARE(dlay->functionCount[SetGeometry], 0); + + QCOMPARE(f->functionCount[SetGeometry], 1); + + QCOMPARE(a->size(), QSizeF(150, 50)); + } + + { + activateAndReset(a); + f->setPreferredSize(QSizeF(60,50)); + QCOMPARE(alay->isActivated(), false); + QCOMPARE(blay->isActivated(), true); + QCOMPARE(clay->isActivated(), false); + QCOMPARE(dlay->isActivated(), true); + + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0); + QCoreApplication::sendPostedEvents(); + QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0); + + QCOMPARE(a->functionCount[SetGeometry], 1); + QCOMPARE(alay->functionCount[SetGeometry], 1); + + QCOMPARE(b->functionCount[SetGeometry], 1); + QCOMPARE(c->functionCount[SetGeometry], 1); + QCOMPARE(d->functionCount[SetGeometry], 1); + // f actually got wider, need to rearrange its siblings + QCOMPARE(blay->functionCount[SetGeometry], 1); + QCOMPARE(clay->functionCount[SetGeometry], 1); + QCOMPARE(dlay->functionCount[SetGeometry], 1); + + QCOMPARE(e->functionCount[SetGeometry], 1); + QCOMPARE(f->functionCount[SetGeometry], 1); + QCOMPARE(g->functionCount[SetGeometry], 1); + + QVERIFY(e->size().width() < f->size().width()); + QVERIFY(g->size().width() < f->size().width()); + } + + { + // resize f so much that it'll force a resize of the top widget + // this will currently generate two setGeometry() calls on the child layout + // of the top widget. + activateAndReset(a); + f->setPreferredSize(QSizeF()); + f->setMinimumSize(QSizeF(200,50)); + QCOMPARE(alay->isActivated(), false); + QCOMPARE(blay->isActivated(), true); + QCOMPARE(clay->isActivated(), false); + QCOMPARE(dlay->isActivated(), true); + + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0); + QCoreApplication::sendPostedEvents(); + QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0); + + QCOMPARE(a->functionCount[SetGeometry], 1); + + /* well, ideally one call to setGeometry(), but it will currently + * get two calls to setGeometry(): + * 1. The first LayoutRequest will call activate() - that will call + * setGeometry() on the layout. This geometry will be based on + * the widget geometry which is not correct at this moment. + * (it is still 150 wide) + * 2. Next, we check if the widget is top level, and then we call + * parentWidget->resize(parentWidget->size()); + * This will be adjusted to be minimum 200 pixels wide. + * The new size will then be propagated down to the layout + * + */ + QCOMPARE(alay->functionCount[SetGeometry], 2); + + QCOMPARE(b->functionCount[SetGeometry], 2); + QCOMPARE(c->functionCount[SetGeometry], 2); + QCOMPARE(d->functionCount[SetGeometry], 2); + // f actually got wider, need to rearrange its siblings + QCOMPARE(blay->functionCount[SetGeometry], 1); + QCOMPARE(clay->functionCount[SetGeometry], 1); + QCOMPARE(dlay->functionCount[SetGeometry], 1); + + QCOMPARE(e->functionCount[SetGeometry], 1); + QCOMPARE(f->functionCount[SetGeometry], 1); + QCOMPARE(g->functionCount[SetGeometry], 1); + + QVERIFY(e->size().width() < f->size().width()); + QVERIFY(g->size().width() < f->size().width()); + } + + { + f->setPreferredSize(QSizeF()); + f->setMinimumSize(QSizeF()); + a->adjustSize(); + activateAndReset(a); + // update two different leaf widgets, + // eventCount and functionCount should never be >= 2 + e->callUpdateGeometry(); + g->callUpdateGeometry(); + QCOMPARE(alay->isActivated(), false); + QCOMPARE(blay->isActivated(), false); + QCOMPARE(clay->isActivated(), true); + QCOMPARE(dlay->isActivated(), false); + + QCoreApplication::sendPostedEvents(); + QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(b->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(d->eventCount(QEvent::LayoutRequest), 1); + + QCOMPARE(a->functionCount[SetGeometry], 1); + QCOMPARE(alay->functionCount[SetGeometry], 1); + + QCOMPARE(b->functionCount[SetGeometry], 1); + QCOMPARE(c->functionCount[SetGeometry], 1); + QCOMPARE(d->functionCount[SetGeometry], 1); + // f actually got wider, need to rearrange its siblings + QCOMPARE(blay->functionCount[SetGeometry], 1); + QCOMPARE(clay->functionCount[SetGeometry], 0); + QCOMPARE(dlay->functionCount[SetGeometry], 1); + + QCOMPARE(e->functionCount[SetGeometry], 1); + QCOMPARE(f->functionCount[SetGeometry], 0); + QCOMPARE(g->functionCount[SetGeometry], 1); + + } + + QGraphicsLayout::setInstantInvalidatePropagation(false); } class Layout : public QGraphicsLayout diff --git a/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp b/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp index 62ba1b4981..8f8ac67d09 100644 --- a/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp +++ b/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp @@ -94,6 +94,7 @@ private slots: void itemSpacing(); void setStretchFactor_data(); void setStretchFactor(); + void testStretch(); void defaultStretchFactors_data(); void defaultStretchFactors(); void sizeHint_data(); @@ -667,6 +668,10 @@ void tst_QGraphicsLinearLayout::invalidate() layout.setContentsMargins(0, 0, 0, 0); view.show(); widget->show(); + //QTest::qWait(1000); + QTest::qWaitForWindowShown(&view); + qApp->processEvents(); + layout.layoutRequest = 0; layout.setContentsMargins(1, 2, 3, 4); QApplication::sendPostedEvents(0, 0); @@ -1130,6 +1135,41 @@ void tst_QGraphicsLinearLayout::setStretchFactor() delete widget; } +void tst_QGraphicsLinearLayout::testStretch() +{ + QGraphicsScene scene; + QGraphicsView *view = new QGraphicsView(&scene); + QGraphicsWidget *form = new QGraphicsWidget(0, Qt::Window); + + scene.addItem(form); + form->setMinimumSize(600, 600); + form->setMaximumSize(600, 600); + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Horizontal, form); + QGraphicsWidget *w1 = new RectWidget; + w1->setPreferredSize(100,100); + w1->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + QGraphicsWidget *w2 = new RectWidget; + w2->setPreferredSize(200,200); + w2->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + layout->setSpacing(0); + layout->setContentsMargins(0, 0, 0, 0); + layout->addItem(w1); + layout->addStretch(2); + layout->addItem(w2); + QCOMPARE(layout->count(), 2); + QVERIFY(layout->itemAt(0) == w1); + QVERIFY(layout->itemAt(1) == w2); + layout->activate(); + + //view->setSceneRect(-50, -50, 800, 800); + //view->show(); + //QTest::qWaitForWindowShown(view); + //QTest::qWait(5000); + QCOMPARE(form->geometry().size(), QSizeF(600,600)); + QCOMPARE(w1->geometry(), QRectF(0, 0, 100, 100)); + QCOMPARE(w2->geometry(), QRectF(400, 0, 200, 200)); +} + void tst_QGraphicsLinearLayout::defaultStretchFactors_data() { QTest::addColumn<Qt::Orientation>("orientation"); diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp index e8e2e23a9e..887026caf4 100644 --- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp @@ -186,7 +186,6 @@ private slots: void task250119_shortcutContext(); void QT_BUG_6544_tabFocusFirstUnsetWhenRemovingItems(); void QT_BUG_12056_tabFocusFirstUnsetWhenRemovingItems(); - void QT_BUG_13865_doublePaintWhenAddingASubItem(); }; @@ -3367,46 +3366,6 @@ void tst_QGraphicsWidget::QT_BUG_12056_tabFocusFirstUnsetWhenRemovingItems() //This should not crash } - -struct GreenWidget : public QGraphicsWidget -{ - GreenWidget() : count(0) - { - } - - void paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * ) - { - count++; - painter->setPen(Qt::green); - painter->drawRect(option->rect.adjusted(0,0,-1,-1)); - } - - int count; -}; - -void tst_QGraphicsWidget::QT_BUG_13865_doublePaintWhenAddingASubItem() -{ - QGraphicsScene scene; - QGraphicsView view(&scene); - QGraphicsWidget *widget = new QGraphicsWidget; - widget->resize(100, 100); - scene.addItem(widget); - QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(widget); - - view.show(); - QTest::qWaitForWindowShown(&view); - QApplication::processEvents(); - - - GreenWidget *sub = new GreenWidget; - layout->addItem(sub); - - QTest::qWait(100); - QCOMPARE(sub->count, 1); //it should only be painted once - -} - - QTEST_MAIN(tst_QGraphicsWidget) #include "tst_qgraphicswidget.moc" diff --git a/tests/auto/qidentityproxymodel/tst_qidentityproxymodel.cpp b/tests/auto/qidentityproxymodel/tst_qidentityproxymodel.cpp index bbcdb4c0a7..cfc3f1a6a8 100644 --- a/tests/auto/qidentityproxymodel/tst_qidentityproxymodel.cpp +++ b/tests/auto/qidentityproxymodel/tst_qidentityproxymodel.cpp @@ -1,13 +1,18 @@ /**************************************************************************** ** -** Copyright (C) 2011 Klarälvdalens Datakonsult AB, -** a KDAB Group company, info@kdab.com, -** author Stephen Kelly <stephen.kelly@kdab.com> +** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com> ** All rights reserved. -** Contact: Nokia Corporation (info@qt.nokia.com) +** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. ** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software @@ -20,17 +25,17 @@ ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** ** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. +** $QT_END_LICENSE$ ** ****************************************************************************/ |