Fix rubberband selection in rotated GraphicsView

Selection rectangle was incorrectly mapped to scene space when the
view was rotated. It became a rotated rectangle instead of the correct
polygon (rhombus).

Task-number: QTBUG-42008
Change-Id: Ib7b366bec7e1f83109e03c434268ad6897138f30
Reviewed-by: Thorbjørn Lund Martsum <tmartsum@gmail.com>
bb10
aavit 2014-10-20 14:09:58 +02:00 committed by Thorbjørn Lund Martsum
parent 74a51d590f
commit 9911550fa7
2 changed files with 44 additions and 1 deletions

View File

@ -765,7 +765,7 @@ void QGraphicsViewPrivate::updateRubberBand(const QMouseEvent *event)
}
// Set the new selection area
QPainterPath selectionArea;
selectionArea.addPolygon(mapToScene(rubberBandRect));
selectionArea.addPolygon(q->mapToScene(rubberBandRect));
selectionArea.closeSubpath();
if (scene)
scene->setSelectionArea(selectionArea, rubberBandSelectionMode, q->viewportTransform());

View File

@ -160,6 +160,7 @@ private slots:
void dragMode_scrollHand();
void dragMode_rubberBand();
void rubberBandSelectionMode();
void rotated_rubberBand();
void backgroundBrush();
void foregroundBrush();
void matrix();
@ -935,6 +936,48 @@ void tst_QGraphicsView::rubberBandSelectionMode()
QCOMPARE(scene.selectedItems(), QList<QGraphicsItem *>() << rect);
}
void tst_QGraphicsView::rotated_rubberBand()
{
QWidget toplevel;
setFrameless(&toplevel);
QGraphicsScene scene;
const int dim = 3;
for (int i = 0; i < dim; i++) {
for (int j = 0; j < dim; j ++) {
QGraphicsRectItem *rect = new QGraphicsRectItem(i * 20, j * 20, 10, 10);
rect->setFlag(QGraphicsItem::ItemIsSelectable);
rect->setData(0, (i == j));
scene.addItem(rect);
}
}
QGraphicsView view(&scene, &toplevel);
QCOMPARE(view.rubberBandSelectionMode(), Qt::IntersectsItemShape);
view.setDragMode(QGraphicsView::RubberBandDrag);
view.resize(120, 120);
view.rotate(45);
toplevel.show();
QVERIFY(QTest::qWaitForWindowExposed(&toplevel));
// Disable mouse tracking to prevent the window system from sending mouse
// move events to the viewport while we are synthesizing events. If
// QGraphicsView gets a mouse move event with no buttons down, it'll
// terminate the rubber band.
view.viewport()->setMouseTracking(false);
QCOMPARE(scene.selectedItems(), QList<QGraphicsItem *>());
int midWidth = view.viewport()->width() / 2;
sendMousePress(view.viewport(), QPoint(midWidth - 2, 0), Qt::LeftButton);
sendMouseMove(view.viewport(), QPoint(midWidth + 2, view.viewport()->height()),
Qt::LeftButton, Qt::LeftButton);
QCOMPARE(scene.selectedItems().count(), dim);
foreach (const QGraphicsItem *item, scene.items()) {
QCOMPARE(item->isSelected(), item->data(0).toBool());
}
sendMouseRelease(view.viewport(), QPoint(), Qt::LeftButton);
}
void tst_QGraphicsView::backgroundBrush()
{
QGraphicsScene scene;