summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp18
-rw-r--r--src/gui/itemviews/qsortfilterproxymodel.cpp2
-rw-r--r--tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp43
-rw-r--r--tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp36
4 files changed, 98 insertions, 1 deletions
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/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/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;
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