1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtWidgets module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39/*!
40 \class QGraphicsSceneIndex
41 \brief The QGraphicsSceneIndex class provides a base class to implement
42 a custom indexing algorithm for discovering items in QGraphicsScene.
43 \since 4.6
44 \ingroup graphicsview-api
45
46 \internal
47
48 The QGraphicsSceneIndex class provides a base class to implement
49 a custom indexing algorithm for discovering items in QGraphicsScene. You
50 need to subclass it and reimplement addItem, removeItem, estimateItems
51 and items in order to have an functional indexing.
52
53 \sa QGraphicsScene, QGraphicsView
54*/
55
56#include "qdebug.h"
57#include "qgraphicsscene.h"
58#include "qgraphicsitem_p.h"
59#include "qgraphicsscene_p.h"
60#include "qgraphicswidget.h"
61#include "qgraphicssceneindex_p.h"
62#include "qgraphicsscenebsptreeindex_p.h"
63#include <QtGui/qpainterpath.h>
64
65QT_BEGIN_NAMESPACE
66
67namespace QtPrivate { // just to keep indentation of the following functions at the same level
68
69 static bool intersect_rect(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode,
70 const QTransform &deviceTransform, const void *intersectData)
71 {
72 const QRectF sceneRect = *static_cast<const QRectF *>(intersectData);
73
74 QRectF brect = item->boundingRect();
75 _q_adjustRect(rect: &brect);
76
77 // ### Add test for this (without making things slower?)
78 Q_UNUSED(exposeRect);
79
80 bool keep = true;
81 const QGraphicsItemPrivate *itemd = QGraphicsItemPrivate::get(item);
82 if (itemd->itemIsUntransformable()) {
83 // Untransformable items; map the scene rect to item coordinates.
84 const QTransform transform = item->deviceTransform(viewportTransform: deviceTransform);
85 QRectF itemRect = (deviceTransform * transform.inverted()).mapRect(sceneRect);
86 if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect)
87 keep = itemRect.contains(r: brect) && itemRect != brect;
88 else
89 keep = itemRect.intersects(r: brect);
90 if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
91 QPainterPath itemPath;
92 itemPath.addRect(rect: itemRect);
93 keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, path: itemPath, mode);
94 }
95 } else {
96 Q_ASSERT(!itemd->dirtySceneTransform);
97 const QRectF itemSceneBoundingRect = itemd->sceneTransformTranslateOnly
98 ? brect.translated(dx: itemd->sceneTransform.dx(),
99 dy: itemd->sceneTransform.dy())
100 : itemd->sceneTransform.mapRect(brect);
101 if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect)
102 keep = sceneRect != brect && sceneRect.contains(r: itemSceneBoundingRect);
103 else
104 keep = sceneRect.intersects(r: itemSceneBoundingRect);
105 if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
106 QPainterPath rectPath;
107 rectPath.addRect(rect: sceneRect);
108 if (itemd->sceneTransformTranslateOnly)
109 rectPath.translate(dx: -itemd->sceneTransform.dx(), dy: -itemd->sceneTransform.dy());
110 else
111 rectPath = itemd->sceneTransform.inverted().map(p: rectPath);
112 keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, path: rectPath, mode);
113 }
114 }
115 return keep;
116 }
117
118 static bool intersect_point(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode,
119 const QTransform &deviceTransform, const void *intersectData)
120 {
121 const QPointF scenePoint = *static_cast<const QPointF *>(intersectData);
122
123 QRectF brect = item->boundingRect();
124 _q_adjustRect(rect: &brect);
125
126 // ### Add test for this (without making things slower?)
127 Q_UNUSED(exposeRect);
128
129 bool keep = false;
130 const QGraphicsItemPrivate *itemd = QGraphicsItemPrivate::get(item);
131 if (itemd->itemIsUntransformable()) {
132 // Untransformable items; map the scene point to item coordinates.
133 const QTransform transform = item->deviceTransform(viewportTransform: deviceTransform);
134 QPointF itemPoint = (deviceTransform * transform.inverted()).map(p: scenePoint);
135 keep = brect.contains(p: itemPoint);
136 if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
137 QPainterPath pointPath;
138 pointPath.addRect(rect: QRectF(itemPoint, QSizeF(1, 1)));
139 keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, path: pointPath, mode);
140 }
141 } else {
142 Q_ASSERT(!itemd->dirtySceneTransform);
143 QRectF sceneBoundingRect = itemd->sceneTransformTranslateOnly
144 ? brect.translated(dx: itemd->sceneTransform.dx(),
145 dy: itemd->sceneTransform.dy())
146 : itemd->sceneTransform.mapRect(brect);
147 keep = sceneBoundingRect.intersects(r: QRectF(scenePoint, QSizeF(1, 1)));
148 if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
149 QPointF p = itemd->sceneTransformTranslateOnly
150 ? QPointF(scenePoint.x() - itemd->sceneTransform.dx(),
151 scenePoint.y() - itemd->sceneTransform.dy())
152 : itemd->sceneTransform.inverted().map(p: scenePoint);
153 keep = item->contains(point: p);
154 }
155 }
156
157 return keep;
158 }
159
160 static bool intersect_path(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode,
161 const QTransform &deviceTransform, const void *intersectData)
162 {
163 const QPainterPath scenePath = *static_cast<const QPainterPath *>(intersectData);
164
165 QRectF brect = item->boundingRect();
166 _q_adjustRect(rect: &brect);
167
168 // ### Add test for this (without making things slower?)
169 Q_UNUSED(exposeRect);
170
171 bool keep = true;
172 const QGraphicsItemPrivate *itemd = QGraphicsItemPrivate::get(item);
173 if (itemd->itemIsUntransformable()) {
174 // Untransformable items; map the scene rect to item coordinates.
175 const QTransform transform = item->deviceTransform(viewportTransform: deviceTransform);
176 QPainterPath itemPath = (deviceTransform * transform.inverted()).map(p: scenePath);
177 if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect)
178 keep = itemPath.contains(rect: brect);
179 else
180 keep = itemPath.intersects(rect: brect);
181 if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape))
182 keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, path: itemPath, mode);
183 } else {
184 Q_ASSERT(!itemd->dirtySceneTransform);
185 const QRectF itemSceneBoundingRect = itemd->sceneTransformTranslateOnly
186 ? brect.translated(dx: itemd->sceneTransform.dx(),
187 dy: itemd->sceneTransform.dy())
188 : itemd->sceneTransform.mapRect(brect);
189 if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect)
190 keep = scenePath.contains(rect: itemSceneBoundingRect);
191 else
192 keep = scenePath.intersects(rect: itemSceneBoundingRect);
193 if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
194 QPainterPath itemPath = itemd->sceneTransformTranslateOnly
195 ? scenePath.translated(dx: -itemd->sceneTransform.dx(),
196 dy: -itemd->sceneTransform.dy())
197 : itemd->sceneTransform.inverted().map(p: scenePath);
198 keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, path: itemPath, mode);
199 }
200 }
201 return keep;
202 }
203
204} // namespace QtPrivate
205
206/*!
207 Constructs a private scene index.
208*/
209QGraphicsSceneIndexPrivate::QGraphicsSceneIndexPrivate(QGraphicsScene *scene) : scene(scene)
210{
211}
212
213/*!
214 Destructor of private scene index.
215*/
216QGraphicsSceneIndexPrivate::~QGraphicsSceneIndexPrivate()
217{
218}
219
220/*!
221 \internal
222
223 Checks if item collides with the path and mode, but also checks that if it
224 doesn't collide, maybe its frame rect will.
225*/
226bool QGraphicsSceneIndexPrivate::itemCollidesWithPath(const QGraphicsItem *item,
227 const QPainterPath &path,
228 Qt::ItemSelectionMode mode)
229{
230 if (item->collidesWithPath(path, mode))
231 return true;
232 if (item->isWidget()) {
233 // Check if this is a window, and if its frame rect collides.
234 const QGraphicsWidget *widget = static_cast<const QGraphicsWidget *>(item);
235 if (widget->isWindow()) {
236 QRectF frameRect = widget->windowFrameRect();
237 QPainterPath framePath;
238 framePath.addRect(rect: frameRect);
239 bool intersects = path.intersects(rect: frameRect);
240 if (mode == Qt::IntersectsItemShape || mode == Qt::IntersectsItemBoundingRect)
241 return intersects || path.contains(pt: frameRect.topLeft())
242 || framePath.contains(pt: path.elementAt(i: 0));
243 return !intersects && path.contains(pt: frameRect.topLeft());
244 }
245 }
246 return false;
247}
248
249/*!
250 \internal
251 This function returns the items in ascending order.
252*/
253void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRectF exposeRect,
254 QGraphicsSceneIndexIntersector intersect,
255 QList<QGraphicsItem *> *items,
256 const QTransform &viewTransform,
257 Qt::ItemSelectionMode mode,
258 qreal parentOpacity, const void *intersectData) const
259{
260 Q_ASSERT(item);
261 if (!item->d_ptr->visible)
262 return;
263
264 const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity);
265 const bool itemIsFullyTransparent = QGraphicsItemPrivate::isOpacityNull(opacity);
266 const bool itemHasChildren = !item->d_ptr->children.isEmpty();
267 if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity()))
268 return;
269
270 // Update the item's scene transform if dirty.
271 const bool itemIsUntransformable = item->d_ptr->itemIsUntransformable();
272 const bool wasDirtyParentSceneTransform = item->d_ptr->dirtySceneTransform && !itemIsUntransformable;
273 if (wasDirtyParentSceneTransform) {
274 item->d_ptr->updateSceneTransformFromParent();
275 Q_ASSERT(!item->d_ptr->dirtySceneTransform);
276 }
277
278 const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape
279 || item->d_ptr->flags & QGraphicsItem::ItemContainsChildrenInShape);
280 bool processItem = !itemIsFullyTransparent;
281 if (processItem) {
282 processItem = intersect(item, exposeRect, mode, viewTransform, intersectData);
283 if (!processItem && (!itemHasChildren || itemClipsChildrenToShape)) {
284 if (wasDirtyParentSceneTransform)
285 item->d_ptr->invalidateChildrenSceneTransform();
286 return;
287 }
288 } // else we know for sure this item has children we must process.
289
290 int i = 0;
291 if (itemHasChildren) {
292 // Sort children.
293 item->d_ptr->ensureSortedChildren();
294
295 // Clip to shape.
296 if (itemClipsChildrenToShape && !itemIsUntransformable) {
297 QPainterPath mappedShape = item->d_ptr->sceneTransformTranslateOnly
298 ? item->shape().translated(dx: item->d_ptr->sceneTransform.dx(),
299 dy: item->d_ptr->sceneTransform.dy())
300 : item->d_ptr->sceneTransform.map(p: item->shape());
301 exposeRect &= mappedShape.controlPointRect();
302 }
303
304 // Process children behind
305 for (i = 0; i < item->d_ptr->children.size(); ++i) {
306 QGraphicsItem *child = item->d_ptr->children.at(i);
307 if (wasDirtyParentSceneTransform)
308 child->d_ptr->dirtySceneTransform = 1;
309 if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent))
310 break;
311 if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
312 continue;
313 recursive_items_helper(item: child, exposeRect, intersect, items, viewTransform,
314 mode, parentOpacity: opacity, intersectData);
315 }
316 }
317
318 // Process item
319 if (processItem)
320 items->append(t: item);
321
322 // Process children in front
323 if (itemHasChildren) {
324 for (; i < item->d_ptr->children.size(); ++i) {
325 QGraphicsItem *child = item->d_ptr->children.at(i);
326 if (wasDirtyParentSceneTransform)
327 child->d_ptr->dirtySceneTransform = 1;
328 if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
329 continue;
330 recursive_items_helper(item: child, exposeRect, intersect, items, viewTransform,
331 mode, parentOpacity: opacity, intersectData);
332 }
333 }
334}
335
336void QGraphicsSceneIndexPrivate::init()
337{
338 if (!scene)
339 return;
340
341 QObject::connect(sender: scene, SIGNAL(sceneRectChanged(QRectF)),
342 receiver: q_func(), SLOT(updateSceneRect(QRectF)));
343}
344
345/*!
346 Constructs an abstract scene index for a given \a scene.
347*/
348QGraphicsSceneIndex::QGraphicsSceneIndex(QGraphicsScene *scene)
349: QObject(*new QGraphicsSceneIndexPrivate(scene), scene)
350{
351 d_func()->init();
352}
353
354/*!
355 \internal
356*/
357QGraphicsSceneIndex::QGraphicsSceneIndex(QGraphicsSceneIndexPrivate &dd, QGraphicsScene *scene)
358 : QObject(dd, scene)
359{
360 d_func()->init();
361}
362
363/*!
364 Destroys the scene index.
365*/
366QGraphicsSceneIndex::~QGraphicsSceneIndex()
367{
368
369}
370
371/*!
372 Returns the scene of this index.
373*/
374QGraphicsScene* QGraphicsSceneIndex::scene() const
375{
376 Q_D(const QGraphicsSceneIndex);
377 return d->scene;
378}
379
380/*!
381 \fn QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QPointF &pos,
382 Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform
383 &deviceTransform) const
384
385 Returns all visible items that, depending on \a mode, are at the specified
386 \a pos and return a list sorted using \a order.
387
388 The default value for \a mode is Qt::IntersectsItemShape; all items whose
389 exact shape intersects with \a pos are returned.
390
391 \a deviceTransform is the transformation apply to the view.
392
393 This method use the estimation of the index (estimateItems) and refine the
394 list to get an exact result. If you want to implement your own refinement
395 algorithm you can reimplement this method.
396
397 \sa estimateItems()
398
399*/
400QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSelectionMode mode,
401 Qt::SortOrder order, const QTransform &deviceTransform) const
402{
403
404 Q_D(const QGraphicsSceneIndex);
405 QList<QGraphicsItem *> itemList;
406 d->items_helper(rect: QRectF(pos, QSizeF(1, 1)), intersect: &QtPrivate::intersect_point, items: &itemList, viewTransform: deviceTransform, mode, order, intersectData: &pos);
407 return itemList;
408}
409
410/*!
411 \fn QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QRectF &rect,
412 Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform
413 &deviceTransform) const
414
415 \overload
416
417 Returns all visible items that, depending on \a mode, are either inside or
418 intersect with the specified \a rect and return a list sorted using \a order.
419
420 The default value for \a mode is Qt::IntersectsItemShape; all items whose
421 exact shape intersects with or is contained by \a rect are returned.
422
423 \a deviceTransform is the transformation apply to the view.
424
425 This method use the estimation of the index (estimateItems) and refine
426 the list to get an exact result. If you want to implement your own
427 refinement algorithm you can reimplement this method.
428
429 \sa estimateItems()
430
431*/
432QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSelectionMode mode,
433 Qt::SortOrder order, const QTransform &deviceTransform) const
434{
435 Q_D(const QGraphicsSceneIndex);
436 QRectF exposeRect = rect;
437 _q_adjustRect(rect: &exposeRect);
438 QList<QGraphicsItem *> itemList;
439 d->items_helper(rect: exposeRect, intersect: &QtPrivate::intersect_rect, items: &itemList, viewTransform: deviceTransform, mode, order, intersectData: &rect);
440 return itemList;
441}
442
443/*!
444 \fn QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QPolygonF
445 &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const
446 QTransform &deviceTransform) const
447
448 \overload
449
450 Returns all visible items that, depending on \a mode, are either inside or
451 intersect with the specified \a polygon and return a list sorted using \a order.
452
453 The default value for \a mode is Qt::IntersectsItemShape; all items whose
454 exact shape intersects with or is contained by \a polygon are returned.
455
456 \a deviceTransform is the transformation apply to the view.
457
458 This method use the estimation of the index (estimateItems) and refine
459 the list to get an exact result. If you want to implement your own
460 refinement algorithm you can reimplement this method.
461
462 \sa estimateItems()
463
464*/
465QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode,
466 Qt::SortOrder order, const QTransform &deviceTransform) const
467{
468 Q_D(const QGraphicsSceneIndex);
469 QList<QGraphicsItem *> itemList;
470 QRectF exposeRect = polygon.boundingRect();
471 _q_adjustRect(rect: &exposeRect);
472 QPainterPath path;
473 path.addPolygon(polygon);
474 d->items_helper(rect: exposeRect, intersect: &QtPrivate::intersect_path, items: &itemList, viewTransform: deviceTransform, mode, order, intersectData: &path);
475 return itemList;
476}
477
478/*!
479 \fn QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QPainterPath
480 &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform
481 &deviceTransform) const
482
483 \overload
484
485 Returns all visible items that, depending on \a mode, are either inside or
486 intersect with the specified \a path and return a list sorted using \a order.
487
488 The default value for \a mode is Qt::IntersectsItemShape; all items whose
489 exact shape intersects with or is contained by \a path are returned.
490
491 \a deviceTransform is the transformation apply to the view.
492
493 This method use the estimation of the index (estimateItems) and refine
494 the list to get an exact result. If you want to implement your own
495 refinement algorithm you can reimplement this method.
496
497 \sa estimateItems()
498
499*/
500QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QPainterPath &path, Qt::ItemSelectionMode mode,
501 Qt::SortOrder order, const QTransform &deviceTransform) const
502{
503 Q_D(const QGraphicsSceneIndex);
504 QList<QGraphicsItem *> itemList;
505 QRectF exposeRect = path.controlPointRect();
506 _q_adjustRect(rect: &exposeRect);
507 d->items_helper(rect: exposeRect, intersect: &QtPrivate::intersect_path, items: &itemList, viewTransform: deviceTransform, mode, order, intersectData: &path);
508 return itemList;
509}
510
511/*!
512 This virtual function return an estimation of items at position \a point.
513 This method return a list sorted using \a order.
514*/
515QList<QGraphicsItem *> QGraphicsSceneIndex::estimateItems(const QPointF &point, Qt::SortOrder order) const
516{
517 return estimateItems(rect: QRectF(point, QSize(1, 1)), order);
518}
519
520QList<QGraphicsItem *> QGraphicsSceneIndex::estimateTopLevelItems(const QRectF &rect, Qt::SortOrder order) const
521{
522 Q_D(const QGraphicsSceneIndex);
523 Q_UNUSED(rect);
524 QGraphicsScenePrivate *scened = d->scene->d_func();
525 scened->ensureSortedTopLevelItems();
526 if (order == Qt::DescendingOrder) {
527 QList<QGraphicsItem *> sorted;
528 const int numTopLevelItems = scened->topLevelItems.size();
529 sorted.reserve(alloc: numTopLevelItems);
530 for (int i = numTopLevelItems - 1; i >= 0; --i)
531 sorted << scened->topLevelItems.at(i);
532 return sorted;
533 }
534 return scened->topLevelItems;
535}
536
537/*!
538 \fn QList<QGraphicsItem *> QGraphicsSceneIndex::items(Qt::SortOrder order = Qt::DescendingOrder) const
539
540 This pure virtual function all items in the index and sort them using
541 \a order.
542*/
543
544
545/*!
546 Notifies the index that the scene's scene rect has changed. \a rect
547 is thew new scene rect.
548
549 \sa QGraphicsScene::sceneRect()
550*/
551void QGraphicsSceneIndex::updateSceneRect(const QRectF &rect)
552{
553 Q_UNUSED(rect);
554}
555
556/*!
557 This virtual function removes all items in the scene index.
558*/
559void QGraphicsSceneIndex::clear()
560{
561 const QList<QGraphicsItem *> allItems = items();
562 for (int i = 0 ; i < allItems.size(); ++i)
563 removeItem(item: allItems.at(i));
564}
565
566/*!
567 \fn virtual void QGraphicsSceneIndex::addItem(QGraphicsItem *item) = 0
568
569 This pure virtual function inserts an \a item to the scene index.
570
571 \sa removeItem(), deleteItem()
572*/
573
574/*!
575 \fn virtual void QGraphicsSceneIndex::removeItem(QGraphicsItem *item) = 0
576
577 This pure virtual function removes an \a item to the scene index.
578
579 \sa addItem(), deleteItem()
580*/
581
582/*!
583 This method is called when an \a item has been deleted.
584 The default implementation call removeItem. Be carefull,
585 if your implementation of removeItem use pure virtual method
586 of QGraphicsItem like boundingRect(), then you should reimplement
587 this method.
588
589 \sa addItem(), removeItem()
590*/
591void QGraphicsSceneIndex::deleteItem(QGraphicsItem *item)
592{
593 removeItem(item);
594}
595
596/*!
597 This virtual function is called by QGraphicsItem to notify the index
598 that some part of the \a item 's state changes. By reimplementing this
599 function, your can react to a change, and in some cases, (depending on \a
600 change,) adjustments in the index can be made.
601
602 \a change is the parameter of the item that is changing. \a value is the
603 value that changed; the type of the value depends on \a change.
604
605 The default implementation does nothing.
606
607 \sa QGraphicsItem::GraphicsItemChange
608*/
609void QGraphicsSceneIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const void *const value)
610{
611 Q_UNUSED(item);
612 Q_UNUSED(change);
613 Q_UNUSED(value);
614}
615
616/*!
617 Notify the index for a geometry change of an \a item.
618
619 \sa QGraphicsItem::prepareGeometryChange()
620*/
621void QGraphicsSceneIndex::prepareBoundingRectChange(const QGraphicsItem *item)
622{
623 Q_UNUSED(item);
624}
625
626QT_END_NAMESPACE
627
628#include "moc_qgraphicssceneindex_p.cpp"
629

source code of qtbase/src/widgets/graphicsview/qgraphicssceneindex.cpp