From cf1e3150247d6694e8c00b924627c66e798f2382 Mon Sep 17 00:00:00 2001 From: Pierre Rossi Date: Tue, 6 Apr 2010 19:59:08 +0200 Subject: Fixes a proxymodel sorting odity. Sort order was modified when sorted according to an empty column always in the same order Reviewed-by: Thierry --- src/gui/itemviews/qsortfilterproxymodel.cpp | 2 +- .../tst_qsortfilterproxymodel.cpp | 36 ++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp index b12cd45..f9b6b94 100644 --- a/src/gui/itemviews/qsortfilterproxymodel.cpp +++ b/src/gui/itemviews/qsortfilterproxymodel.cpp @@ -2392,7 +2392,7 @@ bool QSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex QVariant r = (right.model() ? right.model()->data(right, d->sort_role) : QVariant()); switch (l.userType()) { case QVariant::Invalid: - return (r.type() == QVariant::Invalid); + return (r.type() != QVariant::Invalid); case QVariant::Int: return l.toInt() < r.toInt(); case QVariant::UInt: diff --git a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp index 992c95e..53fefee 100644 --- a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp @@ -127,6 +127,8 @@ private slots: void sortColumnTracking1(); void sortColumnTracking2(); + void sortStable(); + void task236755_hiddenColumns(); void task247867_insertRowsSort(); void task248868_staticSorting(); @@ -2442,6 +2444,40 @@ void tst_QSortFilterProxyModel::sortColumnTracking2() QCOMPARE(proxyModel.data(proxyModel.index(strings.count()-1,0)).toString(),QString::fromLatin1("zz")); } +void tst_QSortFilterProxyModel::sortStable() +{ + QStandardItemModel* model = new QStandardItemModel(5, 2); + for (int r=0; r<5; r++) { + for (int c=0; c<2; c++) { + QStandardItem* item = new QStandardItem( + QString("Row:%0, Column:%1").arg(r).arg(c) ); + for( int i=0; i<3; i++ ) { + QStandardItem* child = new QStandardItem( + QString("Item %0").arg(i) ); + item->appendRow( child ); + } + model->setItem(r, c, item); + } + } + model->setHorizontalHeaderItem( 0, new QStandardItem( "Name" )); + model->setHorizontalHeaderItem( 1, new QStandardItem( "Value" ) ); + + + QSortFilterProxyModel *filterModel = new QSortFilterProxyModel(model); + filterModel->setSourceModel(model); + + QTreeView *view = new QTreeView; + view->setModel(filterModel); + QModelIndex firstRoot = filterModel->index(0,0); + view->expand(firstRoot); + view->setSortingEnabled(true); + + view->model()->sort(1, Qt::DescendingOrder); + QVariant lastItemData =filterModel->index(2,0, firstRoot).data(); + view->model()->sort(1, Qt::DescendingOrder); + QCOMPARE(lastItemData, filterModel->index(2,0, firstRoot).data()); +} + void tst_QSortFilterProxyModel::task236755_hiddenColumns() { class MyStandardItemModel : public QStandardItemModel -- cgit v0.12 From 11a8c52498e8dc74fdfef48e953055338c8f18d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Wed, 26 May 2010 15:53:06 +0200 Subject: Redraw issues when removing a fully transparent QGraphicsItem from the scene. This only happened with fully transparent ancestors (item's effectiveOpacity() == 0.0). Problem was that we didn't take into account the ancestors' opacity when removing an item from the scene. More specifically: The calculated effective opacity for the item was zero and we ignored update requests. We have to ignore the opacity if any of the ancestors' ignoreOpacity bit is 1, which means the opacity is set to 0 and the update request has not yet been processed. Auto test included. Task-number: QTBUG-10778 --- src/gui/graphicsview/qgraphicsscene.cpp | 18 ++++++++++ tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp | 43 ++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index ae0abf9..22c3f92 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4889,6 +4889,24 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b if (updateAll) return; + if (removingItemFromScene && !ignoreOpacity && !item->d_ptr->ignoreOpacity) { + // If any of the item's ancestors ignore opacity, it means that the opacity + // was set to 0 (and the update request has not yet been processed). That + // also means that we have to ignore the opacity for the item itself; otherwise + // things like: parent->setOpacity(0); scene->removeItem(child) won't work. + // Note that we only do this when removing items from the scene. In all other + // cases the ignoreOpacity bit propagates properly in processDirtyItems, but + // since the item is removed immediately it won't be processed there. + QGraphicsItem *p = item->d_ptr->parent; + while (p) { + if (p->d_ptr->ignoreOpacity) { + item->d_ptr->ignoreOpacity = true; + break; + } + p = p->d_ptr->parent; + } + } + if (item->d_ptr->discardUpdateRequest(/*ignoreVisibleBit=*/force, /*ignoreDirtyBit=*/removingItemFromScene || invalidateChildren, /*ignoreOpacity=*/ignoreOpacity)) { diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index a155222..67a41ca 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -275,6 +275,7 @@ private slots: void polishItems2(); void isActive(); void siblingIndexAlwaysValid(); + void removeFullyTransparentItem(); // task specific tests below me void task139710_bspTreeCrash(); @@ -4333,6 +4334,48 @@ void tst_QGraphicsScene::siblingIndexAlwaysValid() } +void tst_QGraphicsScene::removeFullyTransparentItem() +{ + QGraphicsScene scene; + + QGraphicsItem *parent = scene.addRect(0, 0, 100, 100); + parent->setFlag(QGraphicsItem::ItemHasNoContents); + + QGraphicsItem *child = scene.addRect(0, 0, 100, 100); + child->setParentItem(parent); + + CustomView view; + view.setScene(&scene); + view.show(); + QTest::qWaitForWindowShown(&view); + + // NB! The parent has the ItemHasNoContents flag set, which means + // the parent itself doesn't generate any update requests, only the + // child can possibly trigger an update. Also note that the child + // is removed before processing events. + view.repaints = 0; + parent->setOpacity(0); + QVERIFY(qFuzzyIsNull(child->effectiveOpacity())); + scene.removeItem(child); + QVERIFY(!scene.items().contains(child)); + QTRY_VERIFY(view.repaints > 0); + + // Re-add child. There's nothing new to display (child is still + // effectively hidden), so it shouldn't trigger an update. + view.repaints = 0; + child->setParentItem(parent); + QVERIFY(scene.items().contains(child)); + QVERIFY(qFuzzyIsNull(child->effectiveOpacity())); + QApplication::processEvents(); + QCOMPARE(view.repaints, 0); + + // Nothing is visible on the screen, removing child item shouldn't trigger an update. + scene.removeItem(child); + QApplication::processEvents(); + QCOMPARE(view.repaints, 0); + delete child; +} + void tst_QGraphicsScene::taskQTBUG_5904_crashWithDeviceCoordinateCache() { QGraphicsScene scene; -- cgit v0.12