summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Bastian <thierryb@filewave.com>2012-08-29 13:10:23 +0200
committerQt by Nokia <qt-info@nokia.com>2012-08-31 14:47:18 +0200
commita5a1121315d55f5af9d1ff4c926dd0d18e39f9df (patch)
tree29f7bde6d1370b91306e4bdd791976d14089e70e
parentf9040233ef609f6aad3e2eed7dd07788bf7b5f03 (diff)
Fixed the QTreeView expansion/collpasing when animated
If you had a QTreeView with expandable items, if you tried to expand and while the animation was still running you'd try to collpase the node, the display would be completely broken: the items below that items would not be visible any more except for a fraction of a second when expanding or collapsing it again. The problem is in the fact that when starting an animation the QTreeView stores the state before animating. And it does that even if an animation is already running. So the stateBeforeAnimation becomes AnimatingState and when the animation finishes, AnimatingState is the state that is restored breaking the painting. Unit test is included. qtbase-sha1: 1e97dbaf6ca807397e3ec77a3611763769499d17 Change-Id: I62e16101b70153f78022f6195fd9de6db0cd4878 Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
-rw-r--r--src/gui/itemviews/qtreeview.cpp8
-rw-r--r--tests/auto/qtreeview/tst_qtreeview.cpp41
2 files changed, 47 insertions, 2 deletions
diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp
index bc9d54c482..40234e0b6b 100644
--- a/src/gui/itemviews/qtreeview.cpp
+++ b/src/gui/itemviews/qtreeview.cpp
@@ -2884,7 +2884,9 @@ void QTreeViewPrivate::expand(int item, bool emitSignal)
if (emitSignal && animationsEnabled)
prepareAnimatedOperation(item, QVariantAnimation::Forward);
#endif //QT_NO_ANIMATION
- stateBeforeAnimation = state;
+ //if already animating, stateBeforeAnimation is set to the correct value
+ if (state != QAbstractItemView::AnimatingState)
+ stateBeforeAnimation = state;
q->setState(QAbstractItemView::ExpandingState);
const QModelIndex index = viewItems.at(item).index;
storeExpanded(index);
@@ -2975,7 +2977,9 @@ void QTreeViewPrivate::collapse(int item, bool emitSignal)
prepareAnimatedOperation(item, QVariantAnimation::Backward);
#endif //QT_NO_ANIMATION
- stateBeforeAnimation = state;
+ //if already animating, stateBeforeAnimation is set to the correct value
+ if (state != QAbstractItemView::AnimatingState)
+ stateBeforeAnimation = state;
q->setState(QAbstractItemView::CollapsingState);
expandedIndexes.erase(it);
viewItems[item].expanded = false;
diff --git a/tests/auto/qtreeview/tst_qtreeview.cpp b/tests/auto/qtreeview/tst_qtreeview.cpp
index 7ef5406547..716fbd523a 100644
--- a/tests/auto/qtreeview/tst_qtreeview.cpp
+++ b/tests/auto/qtreeview/tst_qtreeview.cpp
@@ -76,8 +76,11 @@ static void initStandardTreeModel(QStandardItemModel *model)
model->insertRow(2, item);
}
+class tst_QTreeView;
struct PublicView : public QTreeView
{
+ friend class tst_QTreeView;
+
inline void executeDelayedItemsLayout()
{ QTreeView::executeDelayedItemsLayout(); }
@@ -246,6 +249,10 @@ private slots:
void taskQTBUG_11466_keyboardNavigationRegression();
void taskQTBUG_13567_removeLastItemRegression();
void taskQTBUG_25333_adjustViewOptionsForIndex();
+
+#ifndef QT_NO_ANIMATION
+ void quickExpandCollapse();
+#endif
};
class QtTestModel: public QAbstractItemModel
@@ -4050,6 +4057,40 @@ void tst_QTreeView::taskQTBUG_25333_adjustViewOptionsForIndex()
}
+#ifndef QT_NO_ANIMATION
+void tst_QTreeView::quickExpandCollapse()
+{
+ //this unit tests makes sure the state after the animation is restored correctly
+ //after starting a 2nd animation while the first one was still on-going
+ //this tests that the stateBeforeAnimation is not set to AnimatingState
+ PublicView tree;
+ tree.setAnimated(true);
+ QStandardItemModel model;
+ QStandardItem *root = new QStandardItem("root");
+ root->appendRow(new QStandardItem("subnode"));
+ model.appendRow(root);
+ tree.setModel(&model);
+
+ QModelIndex rootIndex = root->index();
+ QVERIFY(rootIndex.isValid());
+
+ tree.show();
+ QTest::qWaitForWindowShown(&tree);
+
+ int initialState = tree.state();
+
+ tree.expand(rootIndex);
+ QCOMPARE(tree.state(), (int)PublicView::AnimatingState);
+
+ tree.collapse(rootIndex);
+ QCOMPARE(tree.state(), (int)PublicView::AnimatingState);
+
+ QTest::qWait(500); //the animation lasts for 250ms max so 500 should be enough
+
+ QCOMPARE(tree.state(), initialState);
+}
+#endif
+
QTEST_MAIN(tst_QTreeView)
#include "tst_qtreeview.moc"