diff options
author | Andy Maloney <asmaloney@gmail.com> | 2015-01-04 13:41:25 -0500 |
---|---|---|
committer | Andy Maloney <asmaloney@gmail.com> | 2015-01-13 13:04:40 +0100 |
commit | 75f2a0b4ef721b135c42d8e08d70bbdd0ed04c4c (patch) | |
tree | a6dca5a8babb7fedc2ac89609bc59c8a3fd89235 /src/widgets/graphicsview | |
parent | f0f5beb0e5db5538b38f07e6ecab89cc292ef609 (diff) |
Extend selections in QGraphicsView when selection extension key down
If the user has some objects selected and holds down the "extend selection"
key (Control on Windows, Command on Mac OS X), clicking and dragging a
rubber band selection deselects the current selection. This is
counter-intuitive and confusing for users.
This commit fixes the behavior so users can extend selections using the
rubber band when the proper key is held down.
Task-number: QTBUG-6523
Change-Id: Ieda4aaa50adb351c0405f5cb8aae23332eec58a9
Reviewed-by: Andreas Aardal Hanssen <andreas@hanssen.name>
Diffstat (limited to 'src/widgets/graphicsview')
-rw-r--r-- | src/widgets/graphicsview/qgraphicsscene.cpp | 38 | ||||
-rw-r--r-- | src/widgets/graphicsview/qgraphicsscene.h | 2 | ||||
-rw-r--r-- | src/widgets/graphicsview/qgraphicsview.cpp | 15 | ||||
-rw-r--r-- | src/widgets/graphicsview/qgraphicsview_p.h | 1 |
4 files changed, 49 insertions, 7 deletions
diff --git a/src/widgets/graphicsview/qgraphicsscene.cpp b/src/widgets/graphicsview/qgraphicsscene.cpp index 8765b8114d..aa42445b2a 100644 --- a/src/widgets/graphicsview/qgraphicsscene.cpp +++ b/src/widgets/graphicsview/qgraphicsscene.cpp @@ -1468,6 +1468,8 @@ void QGraphicsScenePrivate::mousePressEventHandler(QGraphicsSceneMouseEvent *mou QGraphicsView *view = mouseEvent->widget() ? qobject_cast<QGraphicsView *>(mouseEvent->widget()->parentWidget()) : 0; bool dontClearSelection = view && view->dragMode() == QGraphicsView::ScrollHandDrag; + bool extendSelection = (mouseEvent->modifiers() & Qt::ControlModifier) != 0; + dontClearSelection |= extendSelection; if (!dontClearSelection) { // Clear the selection if the originating view isn't in scroll // hand drag mode. The view will clear the selection if no drag @@ -2263,6 +2265,28 @@ void QGraphicsScene::setSelectionArea(const QPainterPath &path, const QTransform void QGraphicsScene::setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode, const QTransform &deviceTransform) { + setSelectionArea(path, Qt::ReplaceSelection, mode, deviceTransform); +} + +/*! + \overload + \since 5.5 + + Sets the selection area to \a path using \a mode to determine if items are + included in the selection area. + + \a deviceTransform is the transformation that applies to the view, and needs to + be provided if the scene contains items that ignore transformations. + + \a selectionOperation determines what to do with the currently selected items. + + \sa clearSelection(), selectionArea() +*/ +void QGraphicsScene::setSelectionArea(const QPainterPath &path, + Qt::ItemSelectionOperation selectionOperation, + Qt::ItemSelectionMode mode, + const QTransform &deviceTransform) +{ Q_D(QGraphicsScene); // Note: with boolean path operations, we can improve performance here @@ -2287,10 +2311,16 @@ void QGraphicsScene::setSelectionArea(const QPainterPath &path, Qt::ItemSelectio } } - // Unselect all items outside path. - foreach (QGraphicsItem *item, unselectItems) { - item->setSelected(false); - changed = true; + switch (selectionOperation) { + case Qt::ReplaceSelection: + // Deselect all items outside path. + foreach (QGraphicsItem *item, unselectItems) { + item->setSelected(false); + changed = true; + } + break; + default: + break; } // Reenable emitting selectionChanged() for individual items. diff --git a/src/widgets/graphicsview/qgraphicsscene.h b/src/widgets/graphicsview/qgraphicsscene.h index 6cd5da00c8..03df18fbce 100644 --- a/src/widgets/graphicsview/qgraphicsscene.h +++ b/src/widgets/graphicsview/qgraphicsscene.h @@ -177,6 +177,8 @@ public: QPainterPath selectionArea() const; void setSelectionArea(const QPainterPath &path, const QTransform &deviceTransform); void setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape, const QTransform &deviceTransform = QTransform()); + void setSelectionArea(const QPainterPath &path, Qt::ItemSelectionOperation selectionOperation, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape, const QTransform &deviceTransform = QTransform()); + // ### Qt6 merge the last 2 functions and add a default: Qt::ItemSelectionOperation selectionOperation = Qt::ReplaceSelection QGraphicsItemGroup *createItemGroup(const QList<QGraphicsItem *> &items); void destroyItemGroup(QGraphicsItemGroup *group); diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp index 5484ecb96e..b92655013e 100644 --- a/src/widgets/graphicsview/qgraphicsview.cpp +++ b/src/widgets/graphicsview/qgraphicsview.cpp @@ -350,6 +350,7 @@ QGraphicsViewPrivate::QGraphicsViewPrivate() #ifndef QT_NO_RUBBERBAND rubberBanding(false), rubberBandSelectionMode(Qt::IntersectsItemShape), + rubberBandSelectionOperation(Qt::ReplaceSelection), #endif handScrollMotions(0), cacheMode(0), #ifndef QT_NO_CURSOR @@ -735,6 +736,7 @@ void QGraphicsViewPrivate::updateRubberBand(const QMouseEvent *event) // if we didn't get the release events). if (!event->buttons()) { rubberBanding = false; + rubberBandSelectionOperation = Qt::ReplaceSelection; if (!rubberBandRect.isNull()) { rubberBandRect = QRect(); emit q->rubberBandChanged(rubberBandRect, QPointF(), QPointF()); @@ -768,7 +770,7 @@ void QGraphicsViewPrivate::updateRubberBand(const QMouseEvent *event) selectionArea.addPolygon(q->mapToScene(rubberBandRect)); selectionArea.closeSubpath(); if (scene) - scene->setSelectionArea(selectionArea, rubberBandSelectionMode, q->viewportTransform()); + scene->setSelectionArea(selectionArea, rubberBandSelectionOperation, rubberBandSelectionMode, q->viewportTransform()); } #endif @@ -3289,8 +3291,14 @@ void QGraphicsView::mousePressEvent(QMouseEvent *event) d->rubberBanding = true; d->rubberBandRect = QRect(); if (d->scene) { - // Initiating a rubber band always clears the selection. - d->scene->clearSelection(); + bool extendSelection = (event->modifiers() & Qt::ControlModifier) != 0; + + if (extendSelection) { + d->rubberBandSelectionOperation = Qt::AddToSelection; + } else { + d->rubberBandSelectionOperation = Qt::ReplaceSelection; + d->scene->clearSelection(); + } } } } else @@ -3347,6 +3355,7 @@ void QGraphicsView::mouseReleaseEvent(QMouseEvent *event) d->updateAll(); } d->rubberBanding = false; + d->rubberBandSelectionOperation = Qt::ReplaceSelection; if (!d->rubberBandRect.isNull()) { d->rubberBandRect = QRect(); emit rubberBandChanged(d->rubberBandRect, QPointF(), QPointF()); diff --git a/src/widgets/graphicsview/qgraphicsview_p.h b/src/widgets/graphicsview/qgraphicsview_p.h index ca87b932e2..546f34ba81 100644 --- a/src/widgets/graphicsview/qgraphicsview_p.h +++ b/src/widgets/graphicsview/qgraphicsview_p.h @@ -134,6 +134,7 @@ public: void updateRubberBand(const QMouseEvent *event); bool rubberBanding; Qt::ItemSelectionMode rubberBandSelectionMode; + Qt::ItemSelectionOperation rubberBandSelectionOperation; #endif int handScrollMotions; |