QtBase  v6.3.1
qgraphicsitem.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2021 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 
792 #include "qgraphicsitem.h"
793 
794 #include "qgraphicsscene.h"
795 #include "qgraphicsscene_p.h"
796 #include "qgraphicssceneevent.h"
797 #include "qgraphicsview.h"
798 #include "qgraphicswidget.h"
799 #include "qgraphicsproxywidget.h"
801 #include <QtCore/qbitarray.h>
802 #include <QtCore/qpoint.h>
803 #include <QtCore/qstack.h>
804 #include <QtCore/qtimer.h>
805 #include <QtCore/qvariant.h>
806 #include <QtCore/qvarlengtharray.h>
807 #include <QtCore/qnumeric.h>
808 #include <QtWidgets/qapplication.h>
809 #include <QtGui/qbitmap.h>
810 #include <QtGui/qpainter.h>
811 #include <QtGui/qpainterpath.h>
812 #include <QtGui/qpixmapcache.h>
813 #include <QtWidgets/qstyleoption.h>
814 #include <QtGui/qevent.h>
815 #include <QtGui/qinputmethod.h>
816 #if QT_CONFIG(graphicseffect)
817 #include <QtWidgets/qgraphicseffect.h>
818 #endif
819 
820 #include <private/qgraphicsitem_p.h>
821 #include <private/qgraphicswidget_p.h>
822 #include <private/qwidgettextcontrol_p.h>
823 #include <private/qtextdocumentlayout_p.h>
824 #include <private/qtextengine_p.h>
825 #include <private/qwidget_p.h>
826 #include <private/qapplication_p.h>
827 #include <private/qgesturemanager_p.h>
828 #include <private/qdebug_p.h>
829 
831 
832 static inline void _q_adjustRect(QRect *rect)
833 {
834  Q_ASSERT(rect);
835  if (!rect->width())
836  rect->adjust(0, 0, 1, 0);
837  if (!rect->height())
838  rect->adjust(0, 0, 0, 1);
839 }
840 
841 /*
842  ### Move this into QGraphicsItemPrivate
843  */
845 {
846 public:
848 };
850 
851 
857 static QPainterPath qt_graphicsItem_shapeFromPath(const QPainterPath &path, const QPen &pen)
858 {
859  // We unfortunately need this hack as QPainterPathStroker will set a width of 1.0
860  // if we pass a value of 0.0 to QPainterPathStroker::setWidth()
861  const qreal penWidthZero = qreal(0.00000001);
862 
863  if (path == QPainterPath() || pen == Qt::NoPen)
864  return path;
866  ps.setCapStyle(pen.capStyle());
867  if (pen.widthF() <= 0.0)
868  ps.setWidth(penWidthZero);
869  else
870  ps.setWidth(pen.widthF());
871  ps.setJoinStyle(pen.joinStyle());
872  ps.setMiterLimit(pen.miterLimit());
873  QPainterPath p = ps.createStroke(path);
874  p.addPath(path);
875  return p;
876 }
877 
882  : z(0),
883  opacity(1.),
884  scene(nullptr),
885  parent(nullptr),
886  transformData(nullptr),
887  graphicsEffect(nullptr),
888  index(-1),
889  siblingIndex(-1),
890  itemDepth(-1),
891  focusProxy(nullptr),
892  subFocusItem(nullptr),
893  focusScopeItem(nullptr),
894  imHints(Qt::ImhNone),
895  panelModality(QGraphicsItem::NonModal),
896  acceptedMouseButtons(0x1f),
897  visible(true),
898  explicitlyHidden(false),
899  enabled(true),
900  explicitlyDisabled(false),
901  selected(false),
902  acceptsHover(false),
903  acceptDrops(false),
904  isMemberOfGroup(false),
905  handlesChildEvents(false),
906  itemDiscovered(false),
907  hasCursor(false),
908  ancestorFlags(0),
909  cacheMode(0),
910  hasBoundingRegionGranularity(false),
911  isWidget(false),
912  dirty(false),
913  dirtyChildren(false),
914  localCollisionHack(false),
915  inSetPosHelper(false),
916  needSortChildren(false),
917  allChildrenDirty(false),
918  fullUpdatePending(false),
919  flags(0),
920  paintedViewBoundingRectsNeedRepaint(false),
921  dirtySceneTransform(true),
922  geometryChanged(true),
923  inDestructor(false),
924  isObject(false),
925  ignoreVisible(false),
926  ignoreOpacity(false),
927  acceptTouchEvents(false),
928  acceptedTouchBeginEvent(false),
929  filtersDescendantEvents(false),
930  sceneTransformTranslateOnly(false),
931  notifyBoundingRectChanged(false),
932  notifyInvalidated(false),
933  mouseSetsFocus(true),
934  explicitActivate(false),
935  wantsActive(false),
936  holesInSiblingIndex(false),
937  sequentialOrdering(true),
938  updateDueToGraphicsEffect(false),
939  scenePosDescendants(false),
940  pendingPolish(false),
941  mayHaveChildWithGraphicsEffect(false),
942  isDeclarativeItem(false),
943  sendParentChangeNotification(false),
944  dirtyChildrenBoundingRect(true),
945  globalStackingOrder(-1),
946  q_ptr(nullptr)
947 {
948 }
949 
954 {
955 }
956 
965  AncestorFlag flag, bool enabled, bool root)
966 {
967  Q_Q(QGraphicsItem);
968  if (root) {
969  // For root items only. This is the item that has either enabled or
970  // disabled \a childFlag, or has been reparented.
971  switch (int(childFlag)) {
972  case -2:
974  enabled = q->filtersChildEvents();
975  break;
976  case -1:
978  enabled = q->handlesChildEvents();
979  break;
981  flag = AncestorClipsChildren;
983  break;
987  break;
991  break;
992  default:
993  return;
994  }
995 
996  if (parent) {
997  // Inherit the enabled-state from our parents.
998  if ((parent->d_ptr->ancestorFlags & flag)
999  || (int(parent->d_ptr->flags & childFlag) == childFlag)
1000  || (int(childFlag) == -1 && parent->d_ptr->handlesChildEvents)
1001  || (int(childFlag) == -2 && parent->d_ptr->filtersDescendantEvents)) {
1002  enabled = true;
1003  ancestorFlags |= flag;
1004  } else {
1005  ancestorFlags &= ~flag;
1006  }
1007  } else {
1008  // Top-level root items don't have any ancestors, so there are no
1009  // ancestor flags either.
1010  ancestorFlags = 0;
1011  }
1012  } else {
1013  // Don't set or propagate the ancestor flag if it's already correct.
1014  if (((ancestorFlags & flag) && enabled) || (!(ancestorFlags & flag) && !enabled))
1015  return;
1016 
1017  // Set the flag.
1018  if (enabled)
1019  ancestorFlags |= flag;
1020  else
1021  ancestorFlags &= ~flag;
1022 
1023  // Don't process children if the item has the main flag set on itself.
1024  if ((int(childFlag) != -1 && int(flags & childFlag) == childFlag)
1025  || (int(childFlag) == -1 && handlesChildEvents)
1026  || (int(childFlag) == -2 && filtersDescendantEvents))
1027  return;
1028  }
1029 
1030  for (int i = 0; i < children.size(); ++i)
1031  children.at(i)->d_ptr->updateAncestorFlag(childFlag, flag, enabled, false);
1032 }
1033 
1035 {
1036  int flags = 0;
1037  if (parent) {
1038  // Inherit the parent's ancestor flags.
1040  flags = pd->ancestorFlags;
1041 
1042  // Add in flags from the parent.
1043  if (pd->filtersDescendantEvents)
1045  if (pd->handlesChildEvents)
1053  }
1054 
1055  if (ancestorFlags == flags)
1056  return; // No change; stop propagation.
1057  ancestorFlags = flags;
1058 
1059  // Propagate to children recursively.
1060  for (int i = 0; i < children.size(); ++i)
1062 }
1063 
1070 {
1071  Q_Q(QGraphicsItem);
1073  if (!qgraphicsitem_cast<QGraphicsItemGroup *>(q)) {
1074  for (QGraphicsItem *child : qAsConst(children))
1075  child->d_func()->setIsMemberOfGroup(enabled);
1076  }
1077 }
1078 
1085 {
1086  Q_Q(QGraphicsItem);
1087  switch (event->type()) {
1092  QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
1093  mouseEvent->setPos(item->mapFromItem(q, mouseEvent->pos()));
1094  mouseEvent->setLastPos(item->mapFromItem(q, mouseEvent->pos()));
1095  for (int i = 0x1; i <= 0x10; i <<= 1) {
1096  if (mouseEvent->buttons() & i) {
1098  mouseEvent->setButtonDownPos(button, item->mapFromItem(q, mouseEvent->buttonDownPos(button)));
1099  }
1100  }
1101  break;
1102  }
1104  QGraphicsSceneWheelEvent *wheelEvent = static_cast<QGraphicsSceneWheelEvent *>(event);
1105  wheelEvent->setPos(item->mapFromItem(q, wheelEvent->pos()));
1106  break;
1107  }
1110  contextEvent->setPos(item->mapFromItem(q, contextEvent->pos()));
1111  break;
1112  }
1114  QGraphicsSceneHoverEvent *hoverEvent = static_cast<QGraphicsSceneHoverEvent *>(event);
1115  hoverEvent->setPos(item->mapFromItem(q, hoverEvent->pos()));
1116  break;
1117  }
1118  default:
1119  break;
1120  }
1121 }
1122 
1132 {
1133  Q_Q(const QGraphicsItem);
1134  if (!itemIsUntransformable())
1135  return sceneTransform.inverted();
1136  const QGraphicsView *view = viewport
1137  ? qobject_cast<QGraphicsView *>(viewport->parentWidget())
1138  : nullptr;
1139  if (view == nullptr)
1140  return sceneTransform.inverted();
1141  // ### More ping pong than needed.
1142  const QTransform viewportTransform = view->viewportTransform();
1143  return viewportTransform * q->deviceTransform(viewportTransform).inverted();
1144 }
1145 
1147  const QWidget *viewport) const
1148 {
1150 }
1151 
1161 {
1162  // COMBINE
1163  if (viewTransform && itemIsUntransformable()) {
1164  *x = q_ptr->deviceTransform(*viewTransform);
1165  } else {
1166  if (transformData)
1168  if (!pos.isNull())
1169  *x *= QTransform::fromTranslate(pos.x(), pos.y());
1170  }
1171 }
1172 
1183 {
1184  // COMBINE
1185  if (viewTransform && itemIsUntransformable()) {
1186  *x = q_ptr->deviceTransform(*viewTransform);
1187  } else {
1188  x->translate(pos.x(), pos.y());
1189  if (transformData)
1191  }
1192 }
1193 
1195 {
1196  if (parent) {
1200  parent->d_ptr->sceneTransform.dy() + pos.y());
1201  } else {
1204  }
1205  if (transformData) {
1208  } else {
1210  }
1211  } else if (!transformData) {
1214  } else if (transformData->onlyTransform) {
1216  if (!pos.isNull())
1219  } else if (pos.isNull()) {
1222  } else {
1226  }
1227  dirtySceneTransform = 0;
1228 }
1229 
1237 void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const QVariant *newParentVariant,
1238  const QVariant *thisPointerVariant)
1239 {
1240  Q_Q(QGraphicsItem);
1241  if (newParent == parent)
1242  return;
1243 
1244  if (isWidget)
1245  static_cast<QGraphicsWidgetPrivate *>(this)->fixFocusChainBeforeReparenting((newParent &&
1246  newParent->isWidget()) ? static_cast<QGraphicsWidget *>(newParent) : nullptr,
1247  scene);
1248  if (scene) {
1249  // Deliver the change to the index
1250  if (scene->d_func()->indexMethod != QGraphicsScene::NoIndex)
1251  scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParent);
1252 
1253  // Disable scene pos notifications for old ancestors
1255  scene->d_func()->setScenePosItemEnabled(q, false);
1256  }
1257 
1258  if (subFocusItem && parent) {
1259  // Make sure none of the old parents point to this guy.
1261  }
1262 
1263  // We anticipate geometry changes. If the item is deleted, it will be
1264  // removed from the index at a later stage, and the whole scene will be
1265  // updated.
1266  if (!inDestructor)
1268 
1269  if (parent) {
1270  // Remove from current parent
1272  if (thisPointerVariant)
1274  }
1275 
1276  // Update toplevelitem list. If this item is being deleted, its parent
1277  // will be 0 but we don't want to register/unregister it in the TLI list.
1278  if (scene && !inDestructor) {
1279  if (parent && !newParent) {
1280  scene->d_func()->registerTopLevelItem(q);
1281  } else if (!parent && newParent) {
1282  scene->d_func()->unregisterTopLevelItem(q);
1283  }
1284  }
1285 
1286  // Ensure any last parent focus scope does not point to this item or any of
1287  // its descendents.
1288  QGraphicsItem *p = parent;
1289  QGraphicsItem *parentFocusScopeItem = nullptr;
1290  while (p) {
1291  if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) {
1292  // If this item's focus scope's focus scope item points
1293  // to this item or a descendent, then clear it.
1295  if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) {
1296  parentFocusScopeItem = fsi;
1297  p->d_ptr->focusScopeItem = nullptr;
1298  fsi->d_ptr->focusScopeItemChange(false);
1299  }
1300  break;
1301  }
1302  p = p->d_ptr->parent;
1303  }
1304 
1305  // Update graphics effect optimization flag
1306  if (newParent && (graphicsEffect || mayHaveChildWithGraphicsEffect))
1308 
1309  // Update focus scope item ptr in new scope.
1310  QGraphicsItem *newFocusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem;
1311  if (newFocusScopeItem && newParent) {
1312  QGraphicsItem *p = newParent;
1313  while (p) {
1314  if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) {
1315  if (subFocusItem && subFocusItem != q_ptr) {
1316  // Find the subFocusItem's topmost focus scope within the new parent's focusscope
1317  QGraphicsItem *ancestorScope = nullptr;
1319  while (p2 && p2 != p) {
1320  if (p2->d_ptr->flags & QGraphicsItem::ItemIsFocusScope)
1321  ancestorScope = p2;
1322  if (p2->d_ptr->flags & QGraphicsItem::ItemIsPanel)
1323  break;
1324  if (p2 == q_ptr)
1325  break;
1326  p2 = p2->d_ptr->parent;
1327  }
1328  if (ancestorScope)
1329  newFocusScopeItem = ancestorScope;
1330  }
1331 
1332  p->d_ptr->focusScopeItem = newFocusScopeItem;
1333  newFocusScopeItem->d_ptr->focusScopeItemChange(true);
1334  // Ensure the new item is no longer the subFocusItem. The
1335  // only way to set focus on a child of a focus scope is
1336  // by setting focus on the scope itself.
1337  if (subFocusItem && !p->focusItem())
1339  break;
1340  }
1341  p = p->d_ptr->parent;
1342  }
1343  }
1344 
1345  // Resolve depth.
1347 
1348  if ((parent = newParent)) {
1349  if (parent->d_func()->scene && parent->d_func()->scene != scene) {
1350  // Move this item to its new parent's scene
1351  parent->d_func()->scene->addItem(q);
1352  } else if (!parent->d_func()->scene && scene) {
1353  // Remove this item from its former scene
1354  scene->removeItem(q);
1355  }
1356 
1357  parent->d_ptr->addChild(q);
1358  if (thisPointerVariant)
1359  parent->itemChange(QGraphicsItem::ItemChildAddedChange, *thisPointerVariant);
1360  if (scene) {
1361  // Re-enable scene pos notifications for new ancestors
1363  scene->d_func()->setScenePosItemEnabled(q, true);
1364  }
1365 
1366  // Propagate dirty flags to the new parent
1367  markParentDirty(/*updateBoundingRect=*/true);
1368 
1369  // Inherit ancestor flags from the new parent.
1371 
1372  // Update item visible / enabled.
1373  if (parent->d_ptr->visible != visible) {
1374  if (!parent->d_ptr->visible || !explicitlyHidden)
1375  setVisibleHelper(parent->d_ptr->visible, /* explicit = */ false, /* update = */ false);
1376  }
1377  if (parent->isEnabled() != enabled) {
1379  setEnabledHelper(parent->d_ptr->enabled, /* explicit = */ false, /* update = */ false);
1380  }
1381 
1382  // Auto-activate if visible and the parent is active.
1383  if (visible && parent->isActive())
1384  q->setActive(true);
1385  } else {
1386  // Inherit ancestor flags from the new parent.
1388 
1389  if (!inDestructor) {
1390  // Update item visible / enabled.
1391  if (!visible && !explicitlyHidden)
1392  setVisibleHelper(true, /* explicit = */ false);
1393  if (!enabled && !explicitlyDisabled)
1394  setEnabledHelper(true, /* explicit = */ false);
1395  }
1396  }
1397 
1398  dirtySceneTransform = 1;
1399  if (!inDestructor && (transformData || (newParent && newParent->d_ptr->transformData)))
1400  transformChanged();
1401 
1402  // Restore the sub focus chain.
1403  if (subFocusItem) {
1404  subFocusItem->d_ptr->setSubFocus(newParent);
1405  if (parent && parent->isActive())
1407  }
1408 
1409  // Deliver post-change notification
1410  if (newParentVariant)
1411  q->itemChange(QGraphicsItem::ItemParentHasChanged, *newParentVariant);
1412 
1413  if (isObject)
1414  emit static_cast<QGraphicsObject *>(q)->parentChanged();
1415 }
1416 
1423 {
1424  Q_Q(QGraphicsItem);
1425 
1426  QRectF childrenRect;
1427  QRectF *result = rect;
1428  rect = &childrenRect;
1429  const bool setTopMostEffectItem = !topMostEffectItem;
1430 
1431  for (int i = 0; i < children.size(); ++i) {
1433  QGraphicsItemPrivate *childd = child->d_ptr.data();
1434  if (setTopMostEffectItem)
1435  topMostEffectItem = child;
1436  bool hasPos = !childd->pos.isNull();
1437  if (hasPos || childd->transformData) {
1438  // COMBINE
1439  QTransform matrix = childd->transformToParent();
1440  if (x)
1441  matrix *= *x;
1442  *rect |= matrix.mapRect(child->d_ptr->effectiveBoundingRect(topMostEffectItem));
1443  if (!childd->children.isEmpty())
1444  childd->childrenBoundingRectHelper(&matrix, rect, topMostEffectItem);
1445  } else {
1446  if (x)
1447  *rect |= x->mapRect(child->d_ptr->effectiveBoundingRect(topMostEffectItem));
1448  else
1449  *rect |= child->d_ptr->effectiveBoundingRect(topMostEffectItem);
1450  if (!childd->children.isEmpty())
1451  childd->childrenBoundingRectHelper(x, rect, topMostEffectItem);
1452  }
1453  }
1454 
1456  if (x)
1457  *rect &= x->mapRect(q->boundingRect());
1458  else
1459  *rect &= q->boundingRect();
1460  }
1461 
1462  *result |= *rect;
1463 }
1464 
1466  const QRegion &exposedRegion, bool allItems) const
1467 {
1468  Q_ASSERT(option);
1469  Q_Q(const QGraphicsItem);
1470 
1471  // Initialize standard QStyleOption values.
1472  const QRectF brect = q->boundingRect();
1473  option->state = QStyle::State_None;
1474  option->rect = brect.toRect();
1475  option->exposedRect = brect;
1476 
1477  // Style animations require a QObject-based animation target.
1478  // If a plain QGraphicsItem is used to draw animated controls,
1479  // QStyle is let to send animation updates to the whole scene.
1480  option->styleObject = q_ptr->toGraphicsObject();
1481  if (!option->styleObject)
1482  option->styleObject = scene;
1483 
1484  if (selected)
1485  option->state |= QStyle::State_Selected;
1486  if (enabled)
1487  option->state |= QStyle::State_Enabled;
1488  if (q->hasFocus())
1489  option->state |= QStyle::State_HasFocus;
1490  if (scene) {
1491  if (scene->d_func()->hoverItems.contains(q_ptr))
1492  option->state |= QStyle::State_MouseOver;
1493  if (q == scene->mouseGrabberItem())
1494  option->state |= QStyle::State_Sunken;
1495  }
1496 
1498  return;
1499 
1500  if (!allItems) {
1501  // Determine the item's exposed area
1502  option->exposedRect = QRectF();
1503  const QTransform reverseMap = worldTransform.inverted();
1504  for (const QRect &exposedRect : exposedRegion) {
1505  option->exposedRect |= reverseMap.mapRect(QRectF(exposedRect));
1506  if (option->exposedRect.contains(brect))
1507  break;
1508  }
1509  option->exposedRect &= brect;
1510  }
1511 }
1512 
1519 {
1521  key = QPixmapCache::Key();
1522  const auto &constDeviceData = deviceData; // avoid detach
1523  for (const auto &data : constDeviceData)
1525  deviceData.clear();
1526  allExposed = true;
1527  exposed.clear();
1528 }
1529 
1540  : d_ptr(new QGraphicsItemPrivate)
1541 {
1542  d_ptr->q_ptr = this;
1544 }
1545 
1550  : d_ptr(&dd)
1551 {
1552  d_ptr->q_ptr = this;
1554 }
1555 
1565 {
1566  if (d_ptr->isObject) {
1567  QGraphicsObject *o = static_cast<QGraphicsObject *>(this);
1569  p->wasDeleted = true;
1570  if (p->declarativeData) {
1571  p->wasDeleted = true; // needed, so that destroying the declarative data does the right thing
1573  QAbstractDeclarativeData::destroyed(p->declarativeData, o);
1574  p->declarativeData = nullptr;
1575  p->wasDeleted = false;
1576  }
1577  }
1578 
1579  d_ptr->inDestructor = 1;
1581 
1582 #ifndef QT_NO_GESTURES
1583  if (d_ptr->isObject && !d_ptr->gestureContext.isEmpty()) {
1584  QGraphicsObject *o = static_cast<QGraphicsObject *>(this);
1586  for (auto it = d_ptr->gestureContext.constBegin(); it != d_ptr->gestureContext.constEnd(); ++it)
1587  manager->cleanupCachedGestures(o, it.key());
1588  }
1589  }
1590 #endif
1591 
1592  clearFocus();
1593  setFocusProxy(nullptr);
1594 
1595  // Update focus scope item ptr.
1597  while (p) {
1598  if (p->flags() & ItemIsFocusScope) {
1599  if (p->d_ptr->focusScopeItem == this)
1600  p->d_ptr->focusScopeItem = nullptr;
1601  break;
1602  }
1603  p = p->d_ptr->parent;
1604  }
1605 
1606  if (!d_ptr->children.isEmpty()) {
1607  while (!d_ptr->children.isEmpty())
1608  delete d_ptr->children.first();
1610  }
1611 
1612  if (d_ptr->scene) {
1613  d_ptr->scene->d_func()->removeItemHelper(this);
1614  } else {
1616  setParentItem(nullptr);
1617  }
1618 
1619 #if QT_CONFIG(graphicseffect)
1620  delete d_ptr->graphicsEffect;
1621 #endif // QT_CONFIG(graphicseffect)
1622  if (d_ptr->transformData) {
1623  for(int i = 0; i < d_ptr->transformData->graphicsTransforms.size(); ++i) {
1625  static_cast<QGraphicsTransformPrivate *>(t->d_ptr.data())->item = nullptr;
1626  delete t;
1627  }
1628  }
1629  delete d_ptr->transformData;
1630 
1631  if (QGraphicsItemCustomDataStore *dataStore = qt_dataStore())
1632  dataStore->data.remove(this);
1633 }
1634 
1642 {
1643  return d_ptr->scene;
1644 }
1645 
1653 {
1654  if (!d_ptr->isMemberOfGroup)
1655  return nullptr;
1656  QGraphicsItem *parent = const_cast<QGraphicsItem *>(this);
1657  while ((parent = parent->d_ptr->parent)) {
1658  if (QGraphicsItemGroup *group = qgraphicsitem_cast<QGraphicsItemGroup *>(parent))
1659  return group;
1660  }
1661  // Unreachable; if d_ptr->isMemberOfGroup is != 0, then one parent of this
1662  // item is a group item.
1663  return nullptr;
1664 }
1665 
1674 {
1675  if (!group) {
1676  if (QGraphicsItemGroup *group = this->group())
1677  group->removeFromGroup(this);
1678  } else {
1679  group->addToGroup(this);
1680  }
1681 }
1682 
1690 {
1691  return d_ptr->parent;
1692 }
1693 
1703 {
1704  QGraphicsItem *parent = const_cast<QGraphicsItem *>(this);
1705  while (QGraphicsItem *grandPa = parent->parentItem())
1706  parent = grandPa;
1707  return parent;
1708 }
1709 
1719 {
1721  return (p && p->d_ptr->isObject) ? static_cast<QGraphicsObject *>(p) : nullptr;
1722 }
1723 
1733 {
1734  QGraphicsItem *p = parentItem();
1735  while (p && !p->isWidget())
1736  p = p->parentItem();
1737  return (p && p->isWidget()) ? static_cast<QGraphicsWidget *>(p) : nullptr;
1738 }
1739 
1750 {
1751  if (const QGraphicsWidget *p = parentWidget())
1752  return p->topLevelWidget();
1753  return isWidget() ? static_cast<QGraphicsWidget *>(const_cast<QGraphicsItem *>(this)) : nullptr;
1754 }
1755 
1766 {
1767  QGraphicsItem *p = panel();
1768  if (p && p->isWindow())
1769  return static_cast<QGraphicsWidget *>(p);
1770  return nullptr;
1771 }
1772 
1783 {
1784  if (d_ptr->flags & ItemIsPanel)
1785  return const_cast<QGraphicsItem *>(this);
1786  return d_ptr->parent ? d_ptr->parent->panel() : nullptr;
1787 }
1788 
1796 {
1797  return d_ptr->isObject ? static_cast<QGraphicsObject *>(this) : nullptr;
1798 }
1799 
1807 {
1808  return d_ptr->isObject ? static_cast<const QGraphicsObject *>(this) : nullptr;
1809 }
1810 
1826 {
1827  if (newParent == this) {
1828  qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this);
1829  return;
1830  }
1831  if (newParent == d_ptr->parent)
1832  return;
1833 
1834  const QVariant newParentVariant(itemChange(QGraphicsItem::ItemParentChange,
1835  QVariant::fromValue<QGraphicsItem *>(newParent)));
1836  newParent = qvariant_cast<QGraphicsItem *>(newParentVariant);
1837  if (newParent == d_ptr->parent)
1838  return;
1839 
1840  const QVariant thisPointerVariant(QVariant::fromValue<QGraphicsItem *>(this));
1841  d_ptr->setParentItemHelper(newParent, &newParentVariant, &thisPointerVariant);
1842 }
1843 
1855 {
1856  const_cast<QGraphicsItem *>(this)->d_ptr->ensureSortedChildren();
1857  return d_ptr->children;
1858 }
1859 
1866 {
1867  return d_ptr->isWidget;
1868 }
1869 
1878 {
1879  return d_ptr->isWidget && (static_cast<const QGraphicsWidget *>(this)->windowType() & Qt::Window);
1880 }
1881 
1889 {
1890  return d_ptr->flags & ItemIsPanel;
1891 }
1892 
1902 QGraphicsItem::GraphicsItemFlags QGraphicsItem::flags() const
1903 {
1904  return GraphicsItemFlags(d_ptr->flags);
1905 }
1906 
1914 {
1915  if (enabled)
1916  setFlags(GraphicsItemFlags(d_ptr->flags) | flag);
1917  else
1918  setFlags(GraphicsItemFlags(d_ptr->flags) & ~flag);
1919 }
1920 
1936 void QGraphicsItem::setFlags(GraphicsItemFlags flags)
1937 {
1938  // Notify change and check for adjustment.
1939  if (quint32(d_ptr->flags) == quint32(flags))
1940  return;
1941  flags = GraphicsItemFlags(itemChange(ItemFlagsChange, quint32(flags)).toUInt());
1942  if (quint32(d_ptr->flags) == quint32(flags))
1943  return;
1944  if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex)
1945  d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, &flags);
1946 
1947  // Flags that alter the geometry of the item (or its children).
1949  bool fullUpdate = (quint32(flags) & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask);
1950  if (fullUpdate)
1951  d_ptr->updatePaintedViewBoundingRects(/*children=*/true);
1952 
1953  // Keep the old flags to compare the diff.
1954  GraphicsItemFlags oldFlags = GraphicsItemFlags(d_ptr->flags);
1955 
1956  // Update flags.
1957  d_ptr->flags = flags;
1958 
1959  if (!(d_ptr->flags & ItemIsFocusable) && hasFocus()) {
1960  // Clear focus on the item if it has focus when the focusable flag
1961  // is unset.
1962  clearFocus();
1963  }
1964 
1965  if (!(d_ptr->flags & ItemIsSelectable) && isSelected()) {
1966  // Unselect the item if it is selected when the selectable flag is
1967  // unset.
1968  setSelected(false);
1969  }
1970 
1971  if ((flags & ItemClipsChildrenToShape) != (oldFlags & ItemClipsChildrenToShape)) {
1972  // Item children clipping changes. Propagate the ancestor flag to
1973  // all children.
1975  // The childrenBoundingRect is clipped to the boundingRect in case of ItemClipsChildrenToShape,
1976  // which means we have to invalidate the cached childrenBoundingRect whenever this flag changes.
1978  d_ptr->markParentDirty(true);
1979  }
1980 
1982  // Item children containtment changes. Propagate the ancestor flag to all children.
1984  }
1985 
1987  // Item children clipping changes. Propagate the ancestor flag to
1988  // all children.
1990  }
1991 
1993  // NB! We change the flags directly here, so we must also update d_ptr->flags.
1994  // Note that this has do be done before the ItemStacksBehindParent check
1995  // below; otherwise we will loose the change.
1996 
1997  // Update stack-behind.
1998  if (d_ptr->z < qreal(0.0))
2000  else
2002  d_ptr->flags = flags;
2003  }
2004 
2005  if ((flags & ItemStacksBehindParent) != (oldFlags & ItemStacksBehindParent)) {
2006  // NB! This check has to come after the ItemNegativeZStacksBehindParent
2007  // check above. Be careful.
2008 
2009  // Ensure child item sorting is up to date when toggling this flag.
2010  if (d_ptr->parent)
2012  else if (d_ptr->scene)
2013  d_ptr->scene->d_func()->needSortTopLevelItems = 1;
2014  }
2015 
2016  if ((flags & ItemAcceptsInputMethod) != (oldFlags & ItemAcceptsInputMethod)) {
2017  // Update input method sensitivity in any views.
2018  if (d_ptr->scene)
2019  d_ptr->scene->d_func()->updateInputMethodSensitivityInViews();
2020  }
2021 
2022  if ((flags & ItemIsPanel) != (oldFlags & ItemIsPanel)) {
2023  bool becomesPanel = (flags & ItemIsPanel);
2024  if ((d_ptr->panelModality != NonModal) && d_ptr->scene) {
2025  // update the panel's modal state
2026  if (becomesPanel)
2027  d_ptr->scene->d_func()->enterModal(this);
2028  else
2029  d_ptr->scene->d_func()->leaveModal(this);
2030  }
2031  if (d_ptr->isWidget && (becomesPanel || parentWidget())) {
2032  QGraphicsWidget *w = static_cast<QGraphicsWidget *>(this);
2033  QGraphicsWidget *focusFirst = w;
2034  QGraphicsWidget *focusLast = w;
2035  for (;;) {
2036  QGraphicsWidget *test = focusLast->d_func()->focusNext;
2037  if (!w->isAncestorOf(test) || test == w)
2038  break;
2039  focusLast = test;
2040  }
2041 
2042  if (becomesPanel) {
2043  // unlink own widgets from focus chain
2044  QGraphicsWidget *beforeMe = w->d_func()->focusPrev;
2045  QGraphicsWidget *afterMe = focusLast->d_func()->focusNext;
2046  beforeMe->d_func()->focusNext = afterMe;
2047  afterMe->d_func()->focusPrev = beforeMe;
2048  focusFirst->d_func()->focusPrev = focusLast;
2049  focusLast->d_func()->focusNext = focusFirst;
2050  if (!isAncestorOf(focusFirst->d_func()->focusNext))
2051  focusFirst->d_func()->focusNext = w;
2052  } else if (QGraphicsWidget *pw = parentWidget()) {
2053  // link up own widgets to focus chain
2054  QGraphicsWidget *beforeMe = pw;
2055  QGraphicsWidget *afterMe = pw->d_func()->focusNext;
2056  beforeMe->d_func()->focusNext = w;
2057  afterMe->d_func()->focusPrev = focusLast;
2058  w->d_func()->focusPrev = beforeMe;
2059  focusLast->d_func()->focusNext = afterMe;
2060  }
2061  }
2062  }
2063 
2064  if (d_ptr->scene) {
2067  d_ptr->scene->d_func()->registerScenePosItem(this);
2068  else
2069  d_ptr->scene->d_func()->unregisterScenePosItem(this);
2070  }
2071  d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true);
2072  }
2073 
2074  // Notify change.
2076 }
2077 
2086 {
2088 }
2089 
2127 void QGraphicsItem::setCacheMode(CacheMode mode, const QSize &logicalCacheSize)
2128 {
2129  CacheMode lastMode = CacheMode(d_ptr->cacheMode);
2130  d_ptr->cacheMode = mode;
2131  bool noVisualChange = (mode == NoCache && lastMode == NoCache)
2132  || (mode == NoCache && lastMode == DeviceCoordinateCache)
2133  || (mode == DeviceCoordinateCache && lastMode == NoCache)
2134  || (mode == DeviceCoordinateCache && lastMode == DeviceCoordinateCache);
2135  if (mode == NoCache) {
2137  } else {
2139 
2140  // Reset old cache
2141  cache->purge();
2142 
2143  if (mode == ItemCoordinateCache) {
2144  if (lastMode == mode && cache->fixedSize == logicalCacheSize)
2145  noVisualChange = true;
2146  cache->fixedSize = logicalCacheSize;
2147  }
2148  }
2149  if (!noVisualChange)
2150  update();
2151 }
2152 
2159 {
2160  return d_ptr->panelModality;
2161 }
2162 
2171 {
2173  return;
2174 
2175  PanelModality previousModality = d_ptr->panelModality;
2176  bool enterLeaveModal = (isPanel() && d_ptr->scene && isVisible());
2177  if (enterLeaveModal && panelModality == NonModal)
2178  d_ptr->scene->d_func()->leaveModal(this);
2180  if (enterLeaveModal && d_ptr->panelModality != NonModal)
2181  d_ptr->scene->d_func()->enterModal(this, previousModality);
2182 }
2183 
2196 {
2197  if (!d_ptr->scene)
2198  return false;
2199 
2200 
2201  QGraphicsItem *dummy = nullptr;
2202  if (!blockingPanel)
2203  blockingPanel = &dummy;
2204 
2205  const QGraphicsScenePrivate *scene_d = d_ptr->scene->d_func();
2206  if (scene_d->modalPanels.isEmpty())
2207  return false;
2208 
2209  // ###
2210  if (!scene_d->popupWidgets.isEmpty() && scene_d->popupWidgets.first() == this)
2211  return false;
2212 
2213  for (int i = 0; i < scene_d->modalPanels.count(); ++i) {
2214  QGraphicsItem *modalPanel = scene_d->modalPanels.at(i);
2215  if (modalPanel->panelModality() == QGraphicsItem::SceneModal) {
2216  // Scene modal panels block all non-descendents.
2217  if (modalPanel != this && !modalPanel->isAncestorOf(this)) {
2218  *blockingPanel = modalPanel;
2219  return true;
2220  }
2221  } else {
2222  // Window modal panels block ancestors and siblings/cousins.
2223  if (modalPanel != this
2224  && !modalPanel->isAncestorOf(this)
2225  && commonAncestorItem(modalPanel)) {
2226  *blockingPanel = modalPanel;
2227  return true;
2228  }
2229  }
2230  }
2231  return false;
2232 }
2233 
2234 #if QT_CONFIG(tooltip)
2241 QString QGraphicsItem::toolTip() const
2242 {
2244 }
2245 
2252 void QGraphicsItem::setToolTip(const QString &toolTip)
2253 {
2254  const QVariant toolTipVariant(itemChange(ItemToolTipChange, toolTip));
2255  d_ptr->setExtra(QGraphicsItemPrivate::ExtraToolTip, toolTipVariant.toString());
2256  itemChange(ItemToolTipHasChanged, toolTipVariant);
2257 }
2258 #endif // QT_CONFIG(tooltip)
2259 
2260 #ifndef QT_NO_CURSOR
2277 {
2278  return qvariant_cast<QCursor>(d_ptr->extra(QGraphicsItemPrivate::ExtraCursor));
2279 }
2280 
2297 {
2298  const QVariant cursorVariant(itemChange(ItemCursorChange, QVariant::fromValue<QCursor>(cursor)));
2299  d_ptr->setExtra(QGraphicsItemPrivate::ExtraCursor, qvariant_cast<QCursor>(cursorVariant));
2300  d_ptr->hasCursor = 1;
2301  if (d_ptr->scene) {
2302  d_ptr->scene->d_func()->allItemsUseDefaultCursor = false;
2303  const auto views = d_ptr->scene->views();
2304  for (QGraphicsView *view : views) {
2305  view->viewport()->setMouseTracking(true);
2306  // Note: Some of this logic is duplicated in QGraphicsView's mouse events.
2307  if (view->underMouse()) {
2308  const QPoint viewPoint = view->mapFromGlobal(QCursor::pos());
2309  const QPointF cursorPos = mapFromScene(view->mapToScene(viewPoint));
2310  // the cursor can only change if the current item is under the mouse
2311  if (boundingRect().contains(cursorPos)) {
2312  const auto itemsUnderCursor = view->items(viewPoint);
2313  for (QGraphicsItem *itemUnderCursor : itemsUnderCursor) {
2314  if (itemUnderCursor->hasCursor()) {
2315  QMetaObject::invokeMethod(view, "_q_setViewportCursor",
2316  Q_ARG(QCursor, itemUnderCursor->cursor()));
2317  break;
2318  }
2319  }
2320  }
2321  break;
2322  }
2323  }
2324  }
2325  itemChange(ItemCursorHasChanged, cursorVariant);
2326 }
2327 
2337 {
2338  return d_ptr->hasCursor;
2339 }
2340 
2347 {
2348  if (!d_ptr->hasCursor)
2349  return;
2351  d_ptr->hasCursor = 0;
2352  if (d_ptr->scene) {
2353  const auto views = d_ptr->scene->views();
2354  for (QGraphicsView *view : views) {
2355  if (view->underMouse() && view->itemAt(view->mapFromGlobal(QCursor::pos())) == this) {
2356  QMetaObject::invokeMethod(view, "_q_unsetViewportCursor");
2357  break;
2358  }
2359  }
2360  }
2361 }
2362 
2363 #endif // QT_NO_CURSOR
2364 
2374 {
2375  return d_ptr->visible;
2376 }
2377 
2392 {
2393  const QGraphicsItem *p = this;
2394  if (d_ptr->explicitlyHidden)
2395  return false;
2396  do {
2397  if (p == parent)
2398  return true;
2399  if (p->d_ptr->explicitlyHidden)
2400  return false;
2401  } while ((p = p->d_ptr->parent));
2402  return parent == nullptr;
2403 }
2404 
2411 void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly,
2412  bool update, bool hiddenByPanel)
2413 {
2414  Q_Q(QGraphicsItem);
2415 
2416  // Update explicit bit.
2417  if (explicitly)
2418  explicitlyHidden = newVisible ? 0 : 1;
2419 
2420  // Check if there's nothing to do.
2421  if (visible == quint32(newVisible))
2422  return;
2423 
2424  // Don't show child if parent is not visible
2425  if (parent && newVisible && !parent->d_ptr->visible)
2426  return;
2427 
2428  // Modify the property.
2429  const QVariant newVisibleVariant(q_ptr->itemChange(QGraphicsItem::ItemVisibleChange,
2430  quint32(newVisible)));
2431  newVisible = newVisibleVariant.toBool();
2432  if (visible == quint32(newVisible))
2433  return;
2434  visible = newVisible;
2435 
2436  // Schedule redrawing
2437  if (update) {
2438  QGraphicsItemCache *c = (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
2439  if (c)
2440  c->purge();
2441  if (scene) {
2442 #if QT_CONFIG(graphicseffect)
2443  invalidateParentGraphicsEffectsRecursively();
2444 #endif // QT_CONFIG(graphicseffect)
2445  scene->d_func()->markDirty(q_ptr, QRectF(), /*invalidateChildren=*/false, /*force=*/true);
2446  }
2447  }
2448 
2449  // Certain properties are dropped as an item becomes invisible.
2450  bool hasFocus = q_ptr->hasFocus();
2451  if (!newVisible) {
2452  if (scene) {
2453  if (scene->d_func()->mouseGrabberItems.contains(q))
2454  q->ungrabMouse();
2455  if (scene->d_func()->keyboardGrabberItems.contains(q))
2456  q->ungrabKeyboard();
2457  if (q->isPanel() && panelModality != QGraphicsItem::NonModal)
2458  scene->d_func()->leaveModal(q_ptr);
2459  }
2460  if (hasFocus && scene) {
2461  // Hiding the focus item or the closest non-panel ancestor of the focus item
2462  QGraphicsItem *focusItem = scene->focusItem();
2463  bool clear = true;
2464  if (isWidget && !focusItem->isPanel()) {
2465  do {
2466  if (focusItem == q_ptr) {
2467  clear = !static_cast<QGraphicsWidget *>(q_ptr)->focusNextPrevChild(true);
2468  break;
2469  }
2470  } while ((focusItem = focusItem->parentWidget()) && !focusItem->isPanel());
2471  }
2472  if (clear)
2473  clearFocusHelper(/* giveFocusToParent = */ false, hiddenByPanel);
2474  }
2475  if (q_ptr->isSelected())
2476  q_ptr->setSelected(false);
2477  } else {
2478  geometryChanged = 1;
2480  if (scene) {
2481  if (isWidget) {
2482  QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(q_ptr);
2483  if (widget->windowType() == Qt::Popup)
2484  scene->d_func()->addPopup(widget);
2485  }
2486  if (q->isPanel() && panelModality != QGraphicsItem::NonModal) {
2487  scene->d_func()->enterModal(q_ptr);
2488  }
2489  }
2490  }
2491 
2492  // Update children with explicitly = false.
2493  const bool updateChildren = update && !((flags & QGraphicsItem::ItemClipsChildrenToShape
2496  for (QGraphicsItem *child : qAsConst(children)) {
2497  if (!newVisible || !child->d_ptr->explicitlyHidden)
2498  child->d_ptr->setVisibleHelper(newVisible, false, updateChildren, hiddenByPanel);
2499  }
2500 
2501  // Update activation
2502  if (scene && q->isPanel()) {
2503  if (newVisible) {
2504  if (parent && parent->isActive())
2505  q->setActive(true);
2506  } else {
2507  if (q->isActive())
2509  }
2510  }
2511 
2512  // Enable subfocus
2513  if (scene) {
2514  if (newVisible) {
2515  // Item is shown
2516  QGraphicsItem *p = parent;
2517  bool done = false;
2518  while (p) {
2519  if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
2521  if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) {
2522  done = true;
2523  while (fsi->d_ptr->focusScopeItem && fsi->d_ptr->focusScopeItem->isVisible())
2524  fsi = fsi->d_ptr->focusScopeItem;
2525  fsi->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true,
2526  /* focusFromHide = */ false);
2527  }
2528  break;
2529  }
2530  p = p->d_ptr->parent;
2531  }
2532  if (!done) {
2534  if (fi && fi != scene->focusItem()) {
2535  scene->setFocusItem(fi);
2536  } else if (flags & QGraphicsItem::ItemIsFocusScope &&
2537  !scene->focusItem() &&
2538  q->isAncestorOf(scene->d_func()->lastFocusItem)) {
2539  q_ptr->setFocus();
2540  }
2541  }
2542  } else {
2543  // Item is hidden
2544  if (hasFocus) {
2545  QGraphicsItem *p = parent;
2546  while (p) {
2547  if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
2548  if (p->d_ptr->visible) {
2549  p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true,
2550  /* focusFromHide = */ true);
2551  }
2552  break;
2553  }
2554  p = p->d_ptr->parent;
2555  }
2556  }
2557  }
2558  }
2559 
2560  // Deliver post-change notification.
2562 
2563  if (isObject)
2564  emit static_cast<QGraphicsObject *>(q_ptr)->visibleChanged();
2565 }
2566 
2599 void QGraphicsItem::setVisible(bool visible)
2600 {
2601  d_ptr->setVisibleHelper(visible,
2602  /* explicit = */ true,
2603  /* update = */ true,
2604  /* hiddenByPanel = */ isPanel());
2605 }
2606 
2633 {
2634  return d_ptr->enabled;
2635 }
2636 
2643 void QGraphicsItemPrivate::setEnabledHelper(bool newEnabled, bool explicitly, bool update)
2644 {
2645  // Update explicit bit.
2646  if (explicitly)
2647  explicitlyDisabled = newEnabled ? 0 : 1;
2648 
2649  // Check if there's nothing to do.
2650  if (enabled == quint32(newEnabled))
2651  return;
2652 
2653  // Certain properties are dropped when an item is disabled.
2654  if (!newEnabled) {
2655  if (scene) {
2656  if (scene->mouseGrabberItem() == q_ptr)
2657  q_ptr->ungrabMouse();
2658  if (q_ptr->hasFocus()) {
2659  // Disabling the closest non-panel ancestor of the focus item
2660  // causes focus to pop to the next item, otherwise it's cleared.
2661  QGraphicsItem *focusItem = scene->focusItem();
2662  bool clear = true;
2663  if (isWidget && !focusItem->isPanel() && q_ptr->isAncestorOf(focusItem)) {
2664  do {
2665  if (focusItem == q_ptr) {
2666  clear = !static_cast<QGraphicsWidget *>(q_ptr)->focusNextPrevChild(true);
2667  break;
2668  }
2669  } while ((focusItem = focusItem->parentWidget()) && !focusItem->isPanel());
2670  }
2671  if (clear)
2672  q_ptr->clearFocus();
2673  }
2674  }
2675  if (q_ptr->isSelected())
2676  q_ptr->setSelected(false);
2677  }
2678 
2679  // Modify the property.
2680  const QVariant newEnabledVariant(q_ptr->itemChange(QGraphicsItem::ItemEnabledChange,
2681  quint32(newEnabled)));
2682  enabled = newEnabledVariant.toBool();
2683 
2684  // Schedule redraw.
2685  if (update)
2686  q_ptr->update();
2687 
2688  for (QGraphicsItem *child : qAsConst(children)) {
2689  if (!newEnabled || !child->d_ptr->explicitlyDisabled)
2690  child->d_ptr->setEnabledHelper(newEnabled, /* explicitly = */ false);
2691  }
2692 
2693  // Deliver post-change notification.
2695 
2696  if (isObject)
2697  emit static_cast<QGraphicsObject *>(q_ptr)->enabledChanged();
2698 }
2699 
2729 {
2730  d_ptr->setEnabledHelper(enabled, /* explicitly = */ true);
2731 }
2732 
2743 {
2744  if (QGraphicsItemGroup *group = this->group())
2745  return group->isSelected();
2746  return d_ptr->selected;
2747 }
2748 
2773 void QGraphicsItem::setSelected(bool selected)
2774 {
2775  if (QGraphicsItemGroup *group = this->group()) {
2776  group->setSelected(selected);
2777  return;
2778  }
2779 
2780  if (!(d_ptr->flags & ItemIsSelectable) || !d_ptr->enabled || !d_ptr->visible)
2781  selected = false;
2782  if (d_ptr->selected == selected)
2783  return;
2784  const QVariant newSelectedVariant(itemChange(ItemSelectedChange, quint32(selected)));
2785  bool newSelected = newSelectedVariant.toBool();
2786  if (d_ptr->selected == newSelected)
2787  return;
2788  d_ptr->selected = newSelected;
2789 
2790  update();
2791  if (d_ptr->scene) {
2792  QGraphicsScenePrivate *sceneD = d_ptr->scene->d_func();
2793  if (selected) {
2794  sceneD->selectedItems << this;
2795  } else {
2796  // QGraphicsScene::selectedItems() lazily pulls out all items that are
2797  // no longer selected.
2798  }
2799  if (!sceneD->selectionChanging)
2801  }
2802 
2803  // Deliver post-change notification.
2805 }
2806 
2827 {
2828  return d_ptr->opacity;
2829 }
2830 
2843 {
2844  return d_ptr->effectiveOpacity();
2845 }
2846 
2874 {
2875  // Notify change.
2876  const QVariant newOpacityVariant(itemChange(ItemOpacityChange, opacity));
2877 
2878  // Normalized opacity
2879  qreal newOpacity = qBound(qreal(0), newOpacityVariant.toReal(), qreal(1));
2880 
2881  // No change? Done.
2882  if (newOpacity == d_ptr->opacity)
2883  return;
2884 
2885  bool wasFullyTransparent = d_ptr->isOpacityNull();
2886  d_ptr->opacity = newOpacity;
2887 
2888  // Notify change.
2889  itemChange(ItemOpacityHasChanged, newOpacityVariant);
2890 
2891  // Update.
2892  if (d_ptr->scene) {
2893 #if QT_CONFIG(graphicseffect)
2894  d_ptr->invalidateParentGraphicsEffectsRecursively();
2896  d_ptr->invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::OpacityChanged);
2897 #endif // QT_CONFIG(graphicseffect)
2898  d_ptr->scene->d_func()->markDirty(this, QRectF(),
2899  /*invalidateChildren=*/true,
2900  /*force=*/false,
2901  /*ignoreOpacity=*/d_ptr->isOpacityNull());
2902  if (wasFullyTransparent)
2904  }
2905 
2906  if (d_ptr->isObject)
2907  emit static_cast<QGraphicsObject *>(this)->opacityChanged();
2908 }
2909 
2915 #if QT_CONFIG(graphicseffect)
2916 QGraphicsEffect *QGraphicsItem::graphicsEffect() const
2917 {
2918  return d_ptr->graphicsEffect;
2919 }
2920 
2936 void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect)
2937 {
2938  if (d_ptr->graphicsEffect == effect)
2939  return;
2940 
2941  if (d_ptr->graphicsEffect) {
2942  delete d_ptr->graphicsEffect;
2943  d_ptr->graphicsEffect = nullptr;
2944  } else if (d_ptr->parent) {
2946  }
2947 
2948  if (effect) {
2949  // Set new effect.
2953  effect->d_func()->setGraphicsEffectSource(source);
2955  }
2956 }
2957 #endif // QT_CONFIG(graphicseffect)
2958 
2960 {
2961 #if QT_CONFIG(graphicseffect)
2962  QGraphicsItemPrivate *itemPrivate = this;
2963  do {
2964  // parent chain already notified?
2965  if (itemPrivate->mayHaveChildWithGraphicsEffect)
2966  return;
2967  itemPrivate->mayHaveChildWithGraphicsEffect = 1;
2968  } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : nullptr));
2969 #endif
2970 }
2971 
2983 {
2984 #if QT_CONFIG(graphicseffect)
2985  Q_Q(const QGraphicsItem);
2987  if (scene && effect && effect->isEnabled()) {
2988  if (scene->d_func()->views.isEmpty())
2989  return effect->boundingRectFor(rect);
2990  QRectF sceneRect = q->mapRectToScene(rect);
2991  QRectF sceneEffectRect;
2992  const auto views = scene->views();
2993  for (QGraphicsView *view : views) {
2994  QRectF deviceRect = view->d_func()->mapRectFromScene(sceneRect);
2995  QRect deviceEffectRect = effect->boundingRectFor(deviceRect).toAlignedRect();
2996  sceneEffectRect |= view->d_func()->mapRectToScene(deviceEffectRect);
2997  }
2998  return q->mapRectFromScene(sceneEffectRect);
2999  }
3000 #endif // QT_CONFIG(graphicseffect)
3001  return rect;
3002 }
3003 
3015 {
3016 #if QT_CONFIG(graphicseffect)
3017  Q_Q(const QGraphicsItem);
3021  || topMostEffectItem == q)
3022  return brect;
3023 
3024  const QGraphicsItem *effectParent = parent;
3025  while (effectParent) {
3026  QGraphicsEffect *effect = effectParent->d_ptr->graphicsEffect;
3027  if (scene && effect && effect->isEnabled()) {
3028  const QRectF brectInParentSpace = q->mapRectToItem(effectParent, brect);
3029  const QRectF effectRectInParentSpace = effectParent->d_ptr->effectiveBoundingRect(brectInParentSpace);
3030  brect = effectParent->mapRectToItem(q, effectRectInParentSpace);
3031  }
3034  || topMostEffectItem == effectParent) {
3035  return brect;
3036  }
3037  effectParent = effectParent->d_ptr->parent;
3038  }
3039 
3040  return brect;
3041 #else //QT_CONFIG(graphicseffect)
3042  Q_UNUSED(topMostEffectItem);
3043  return q_ptr->boundingRect();
3044 #endif // QT_CONFIG(graphicseffect)
3045 
3046 }
3047 
3060 {
3061  // Find translate-only offset
3062  // COMBINE
3063  QPointF offset;
3064  const QGraphicsItem *parentItem = q_ptr;
3065  const QGraphicsItemPrivate *itemd;
3066  do {
3067  itemd = parentItem->d_ptr.data();
3068  if (itemd->transformData)
3069  break;
3070  offset += itemd->pos;
3071  } while ((parentItem = itemd->parent));
3072 
3074  br.translate(offset);
3075  return !parentItem ? br : parentItem->sceneTransform().mapRect(br);
3076 }
3077 
3086 {
3087  return d_ptr->acceptDrops;
3088 }
3089 
3098 {
3099  d_ptr->acceptDrops = on;
3100 }
3101 
3114 Qt::MouseButtons QGraphicsItem::acceptedMouseButtons() const
3115 {
3116  return Qt::MouseButtons(d_ptr->acceptedMouseButtons);
3117 }
3118 
3133 void QGraphicsItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
3134 {
3135  if (Qt::MouseButtons(d_ptr->acceptedMouseButtons) != buttons) {
3136  if (buttons == 0 && d_ptr->scene && d_ptr->scene->mouseGrabberItem() == this
3137  && d_ptr->scene->d_func()->lastMouseGrabberItemHasImplicitMouseGrab) {
3138  ungrabMouse();
3139  }
3140  d_ptr->acceptedMouseButtons = quint32(buttons);
3141  }
3142 }
3143 
3154 {
3155  return d_ptr->acceptsHover;
3156 }
3157 
3158 
3191 {
3192  if (d_ptr->acceptsHover == quint32(enabled))
3193  return;
3195  if (d_ptr->acceptsHover && d_ptr->scene && d_ptr->scene->d_func()->allItemsIgnoreHoverEvents) {
3196  d_ptr->scene->d_func()->allItemsIgnoreHoverEvents = false;
3197  d_ptr->scene->d_func()->enableMouseTrackingOnViews();
3198  }
3199 }
3200 
3209 {
3210  return d_ptr->acceptTouchEvents;
3211 }
3212 
3221 {
3223  return;
3225  if (d_ptr->acceptTouchEvents && d_ptr->scene && d_ptr->scene->d_func()->allItemsIgnoreTouchEvents) {
3226  d_ptr->scene->d_func()->allItemsIgnoreTouchEvents = false;
3227  d_ptr->scene->d_func()->enableTouchEventsOnViews();
3228  }
3229 }
3230 
3243 {
3245 }
3246 
3259 {
3261  return;
3262 
3265 }
3266 
3285 {
3286  return d_ptr->handlesChildEvents;
3287 }
3288 
3310 {
3312  return;
3313 
3316 }
3333 {
3334  if (!d_ptr->scene || !d_ptr->scene->isActive())
3335  return false;
3336  return panel() == d_ptr->scene->activePanel();
3337 }
3338 
3353 void QGraphicsItem::setActive(bool active)
3354 {
3355  d_ptr->explicitActivate = 1;
3356  d_ptr->wantsActive = active;
3357  if (d_ptr->scene) {
3358  if (active) {
3359  // Activate this item.
3360  d_ptr->scene->setActivePanel(this);
3361  } else {
3362  QGraphicsItem *activePanel = d_ptr->scene->activePanel();
3363  QGraphicsItem *thisPanel = panel();
3364  if (!activePanel || activePanel == thisPanel) {
3365  // Deactivate this item, and reactivate the parent panel,
3366  // or the last active panel (if any).
3367  QGraphicsItem *nextToActivate = nullptr;
3368  if (d_ptr->parent)
3369  nextToActivate = d_ptr->parent->panel();
3370  if (!nextToActivate)
3371  nextToActivate = d_ptr->scene->d_func()->lastActivePanel;
3372  if (nextToActivate == this || isAncestorOf(nextToActivate))
3373  nextToActivate = nullptr;
3374  d_ptr->scene->setActivePanel(nextToActivate);
3375  }
3376  }
3377  }
3378 }
3379 
3387 {
3388  if (!d_ptr->scene || !d_ptr->scene->isActive())
3389  return false;
3390 
3391  if (d_ptr->focusProxy)
3392  return d_ptr->focusProxy->hasFocus();
3393 
3394  if (d_ptr->scene->d_func()->focusItem != this)
3395  return false;
3396 
3397  return panel() == d_ptr->scene->d_func()->activePanel;
3398 }
3399 
3421 {
3422  d_ptr->setFocusHelper(focusReason, /* climb = */ true, /* focusFromHide = */ false);
3423 }
3424 
3428 void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromHide)
3429 {
3430  // Disabled / unfocusable items cannot accept focus.
3432  return;
3433 
3434  // Find focus proxy.
3435  QGraphicsItem *f = q_ptr;
3436  while (f->d_ptr->focusProxy)
3437  f = f->d_ptr->focusProxy;
3438 
3439  // Return if it already has focus.
3440  if (scene && scene->focusItem() == f)
3441  return;
3442 
3443  // Update focus scope item ptr.
3444  QGraphicsItem *p = parent;
3445  while (p) {
3446  if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
3447  QGraphicsItem *oldFocusScopeItem = p->d_ptr->focusScopeItem;
3449  if (oldFocusScopeItem)
3450  oldFocusScopeItem->d_ptr->focusScopeItemChange(false);
3451  focusScopeItemChange(true);
3452  if (!p->focusItem() && !focusFromHide) {
3453  // Calling setFocus() on a child of a focus scope that does
3454  // not have focus changes only the focus scope pointer,
3455  // so that focus is restored the next time the scope gains
3456  // focus.
3457  return;
3458  }
3459  break;
3460  }
3461  p = p->d_ptr->parent;
3462  }
3463 
3464  if (climb) {
3465  while (f->d_ptr->focusScopeItem && f->d_ptr->focusScopeItem->isVisible())
3466  f = f->d_ptr->focusScopeItem;
3467  }
3468 
3469  // Update the child focus chain.
3470  QGraphicsItem *commonAncestor = nullptr;
3471  if (scene && scene->focusItem() && scene->focusItem()->panel() == q_ptr->panel()) {
3472  commonAncestor = scene->focusItem()->commonAncestorItem(f);
3473  scene->focusItem()->d_ptr->clearSubFocus(scene->focusItem(), commonAncestor);
3474  }
3475 
3476  f->d_ptr->setSubFocus(f, commonAncestor);
3477 
3478  // Update the scene's focus item.
3479  if (scene) {
3480  QGraphicsItem *p = q_ptr->panel();
3481  if ((!p && scene->isActive()) || (p && p->isActive())) {
3482  // Visible items immediately gain focus from scene.
3483  scene->d_func()->setFocusItemHelper(f, focusReason);
3484  }
3485  }
3486 }
3487 
3500 {
3501  d_ptr->clearFocusHelper(/* giveFocusToParent = */ true,
3502  /* hiddenByParentPanel = */ false);
3503 }
3504 
3508 void QGraphicsItemPrivate::clearFocusHelper(bool giveFocusToParent, bool hiddenByParentPanel)
3509 {
3514  }
3515 
3516  if (giveFocusToParent) {
3517  // Pass focus to the closest parent focus scope
3518  if (!inDestructor) {
3519  QGraphicsItem *p = parent;
3520  while (p) {
3521  if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
3522  if (p->d_ptr->focusScopeItem == q_ptr) {
3523  p->d_ptr->focusScopeItem = nullptr;
3524  if (!subFocusItem->hasFocus()) //if it has focus, focusScopeItemChange is called elsewhere
3525  focusScopeItemChange(false);
3526  }
3527  if (subFocusItem->hasFocus())
3528  p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ false,
3529  /* focusFromHide = */ false);
3530  return;
3531  }
3532  p = p->d_ptr->parent;
3533  }
3534  }
3535  }
3536 
3537  if (subFocusItem->hasFocus()) {
3538  // Invisible items with focus must explicitly clear subfocus.
3539  if (!hiddenByParentPanel)
3541 
3542  // If this item has the scene's input focus, clear it.
3543  scene->setFocusItem(nullptr);
3544  }
3545 }
3546 
3556 {
3557  return d_ptr->focusProxy;
3558 }
3559 
3580 {
3581  if (item == d_ptr->focusProxy)
3582  return;
3583  if (item == this) {
3584  qWarning("QGraphicsItem::setFocusProxy: cannot assign self as focus proxy");
3585  return;
3586  }
3587  if (item) {
3588  if (item->d_ptr->scene != d_ptr->scene) {
3589  qWarning("QGraphicsItem::setFocusProxy: focus proxy must be in same scene");
3590  return;
3591  }
3592  for (QGraphicsItem *f = item->focusProxy(); f != nullptr; f = f->focusProxy()) {
3593  if (f == this) {
3594  qWarning("QGraphicsItem::setFocusProxy: %p is already in the focus proxy chain", item);
3595  return;
3596  }
3597  }
3598  }
3599 
3600  QGraphicsItem *lastFocusProxy = d_ptr->focusProxy;
3601  if (lastFocusProxy)
3602  lastFocusProxy->d_ptr->focusProxyRefs.removeOne(&d_ptr->focusProxy);
3603  d_ptr->focusProxy = item;
3604  if (item)
3606 }
3607 
3618 {
3619  return d_ptr->subFocusItem;
3620 }
3621 
3628 {
3629  return d_ptr->focusScopeItem;
3630 }
3631 
3667 {
3668  if (!d_ptr->scene) {
3669  qWarning("QGraphicsItem::grabMouse: cannot grab mouse without scene");
3670  return;
3671  }
3672  if (!d_ptr->visible) {
3673  qWarning("QGraphicsItem::grabMouse: cannot grab mouse while invisible");
3674  return;
3675  }
3676  d_ptr->scene->d_func()->grabMouse(this);
3677 }
3678 
3686 {
3687  if (!d_ptr->scene) {
3688  qWarning("QGraphicsItem::ungrabMouse: cannot ungrab mouse without scene");
3689  return;
3690  }
3691  d_ptr->scene->d_func()->ungrabMouse(this);
3692 }
3693 
3729 {
3730  if (!d_ptr->scene) {
3731  qWarning("QGraphicsItem::grabKeyboard: cannot grab keyboard without scene");
3732  return;
3733  }
3734  if (!d_ptr->visible) {
3735  qWarning("QGraphicsItem::grabKeyboard: cannot grab keyboard while invisible");
3736  return;
3737  }
3738  d_ptr->scene->d_func()->grabKeyboard(this);
3739 }
3740 
3748 {
3749  if (!d_ptr->scene) {
3750  qWarning("QGraphicsItem::ungrabKeyboard: cannot ungrab keyboard without scene");
3751  return;
3752  }
3753  d_ptr->scene->d_func()->ungrabKeyboard(this);
3754 }
3755 
3770 {
3771  return d_ptr->pos;
3772 }
3773 
3791 {
3792  if (d_ptr->inDestructor)
3793  return;
3794 
3795  if (qIsNaN(x))
3796  return;
3797 
3798  setPos(QPointF(x, d_ptr->pos.y()));
3799 }
3800 
3818 {
3819  if (d_ptr->inDestructor)
3820  return;
3821 
3822  if (qIsNaN(y))
3823  return;
3824 
3825  setPos(QPointF(d_ptr->pos.x(), y));
3826 }
3827 
3835 {
3836  return mapToScene(0, 0);
3837 }
3838 
3845 {
3846  Q_Q(QGraphicsItem);
3847  inSetPosHelper = 1;
3848  if (scene)
3849  q->prepareGeometryChange();
3850  QPointF oldPos = this->pos;
3851  this->pos = pos;
3852  dirtySceneTransform = 1;
3853  inSetPosHelper = 0;
3854  if (isObject) {
3855  if (pos.x() != oldPos.x())
3856  emit static_cast<QGraphicsObject *>(q_ptr)->xChanged();
3857  if (pos.y() != oldPos.y())
3858  emit static_cast<QGraphicsObject *>(q_ptr)->yChanged();
3859  }
3860 }
3861 
3868 {
3871  dirtySceneTransform = 1;
3872  transformChanged();
3873 }
3874 
3886 {
3887  if (d_ptr->pos == pos)
3888  return;
3889 
3890  if (d_ptr->inDestructor)
3891  return;
3892 
3893  // Update and repositition.
3896  if (d_ptr->isWidget)
3897  static_cast<QGraphicsWidget *>(this)->d_func()->setGeometryFromSetPos();
3900  return;
3901  }
3902 
3903  // Notify the item that the position is changing.
3904  const QVariant newPosVariant(itemChange(ItemPositionChange, QVariant::fromValue<QPointF>(pos)));
3905  QPointF newPos = newPosVariant.toPointF();
3906  if (newPos == d_ptr->pos)
3907  return;
3908 
3909  // Update and repositition.
3910  d_ptr->setPosHelper(newPos);
3911 
3912  // Send post-notification.
3915 }
3916 
3947 void QGraphicsItem::ensureVisible(const QRectF &rect, int xmargin, int ymargin)
3948 {
3949  if (d_ptr->scene) {
3950  QRectF sceneRect;
3951  if (!rect.isNull())
3952  sceneRect = sceneTransform().mapRect(rect);
3953  else
3954  sceneRect = sceneBoundingRect();
3955  for (QGraphicsView *view : qAsConst(d_ptr->scene->d_func()->views))
3956  view->ensureVisible(sceneRect, xmargin, ymargin);
3957  }
3958 }
3959 
3981 {
3982  if (!d_ptr->transformData)
3983  return QTransform();
3984  return d_ptr->transformData->transform;
3985 }
3986 
3999 {
4000  if (!d_ptr->transformData)
4001  return 0;
4002  return d_ptr->transformData->rotation;
4003 }
4004 
4025 {
4027  qreal newRotation = angle;
4028 
4030  // Notify the item that the rotation is changing.
4031  const QVariant newRotationVariant(itemChange(ItemRotationChange, angle));
4032  newRotation = newRotationVariant.toReal();
4033  }
4034 
4035  if (!d_ptr->transformData)
4037 
4038  if (d_ptr->transformData->rotation == newRotation)
4039  return;
4040 
4041  d_ptr->transformData->rotation = newRotation;
4042  d_ptr->transformData->onlyTransform = false;
4044 
4045  // Send post-notification.
4047  itemChange(ItemRotationHasChanged, newRotation);
4048 
4049  if (d_ptr->isObject)
4050  emit static_cast<QGraphicsObject *>(this)->rotationChanged();
4051 
4053 }
4054 
4067 {
4068  if (!d_ptr->transformData)
4069  return 1.;
4070  return d_ptr->transformData->scale;
4071 }
4072 
4091 {
4093  qreal newScale = factor;
4094 
4096  // Notify the item that the scale is changing.
4097  const QVariant newScaleVariant(itemChange(ItemScaleChange, factor));
4098  newScale = newScaleVariant.toReal();
4099  }
4100 
4101  if (!d_ptr->transformData)
4103 
4104  if (d_ptr->transformData->scale == newScale)
4105  return;
4106 
4107  d_ptr->transformData->scale = newScale;
4108  d_ptr->transformData->onlyTransform = false;
4110 
4111  // Send post-notification.
4113  itemChange(ItemScaleHasChanged, newScale);
4114 
4115  if (d_ptr->isObject)
4116  emit static_cast<QGraphicsObject *>(this)->scaleChanged();
4117 
4119 }
4120 
4121 
4138 {
4139  if (!d_ptr->transformData)
4140  return QList<QGraphicsTransform *>();
4142 }
4143 
4165 {
4167  if (!d_ptr->transformData)
4170  for (int i = 0; i < transformations.size(); ++i)
4171  transformations.at(i)->d_func()->setItem(this);
4172  d_ptr->transformData->onlyTransform = false;
4175 }
4176 
4181 {
4182  if (!transformData)
4186 
4187  Q_Q(QGraphicsItem);
4188  t->d_func()->setItem(q);
4189  transformData->onlyTransform = false;
4190  dirtySceneTransform = 1;
4191  transformChanged();
4192 }
4193 
4198 {
4199  if (!transformData)
4203 
4204  Q_Q(QGraphicsItem);
4205  t->d_func()->setItem(q);
4206  transformData->onlyTransform = false;
4207  dirtySceneTransform = 1;
4208  transformChanged();
4209 }
4210 
4221 {
4222  if (!d_ptr->transformData)
4223  return QPointF(0,0);
4225 }
4226 
4235 {
4237  QPointF newOrigin = origin;
4238 
4240  // Notify the item that the origin point is changing.
4241  const QVariant newOriginVariant(itemChange(ItemTransformOriginPointChange,
4242  QVariant::fromValue<QPointF>(origin)));
4243  newOrigin = newOriginVariant.toPointF();
4244  }
4245 
4246  if (!d_ptr->transformData)
4248 
4249  if (d_ptr->transformData->xOrigin == newOrigin.x()
4250  && d_ptr->transformData->yOrigin == newOrigin.y()) {
4251  return;
4252  }
4253 
4254  d_ptr->transformData->xOrigin = newOrigin.x();
4255  d_ptr->transformData->yOrigin = newOrigin.y();
4256  d_ptr->transformData->onlyTransform = false;
4258 
4259  // Send post-notification.
4261  itemChange(ItemTransformOriginPointHasChanged, QVariant::fromValue<QPointF>(newOrigin));
4262 }
4263 
4295 {
4297  return d_ptr->sceneTransform;
4298 }
4299 
4324 {
4325  // Ensure we return the standard transform if we're not untransformable.
4326  if (!d_ptr->itemIsUntransformable()) {
4328  return d_ptr->sceneTransform * viewportTransform;
4329  }
4330 
4331  // Find the topmost item that ignores view transformations.
4332  const QGraphicsItem *untransformedAncestor = this;
4334  while (untransformedAncestor && ((untransformedAncestor->d_ptr->ancestorFlags
4336  parents.prepend(untransformedAncestor);
4337  untransformedAncestor = untransformedAncestor->parentItem();
4338  }
4339 
4340  if (!untransformedAncestor) {
4341  // Assert in debug mode, continue in release.
4342  Q_ASSERT_X(untransformedAncestor, "QGraphicsItem::deviceTransform",
4343  "Invalid object structure!");
4344  return QTransform();
4345  }
4346 
4347  // Determine the inherited origin. Find the parent of the topmost untransformable.
4348  // Use its scene transform to map the position of the untransformable. Then use
4349  // that viewport position as the anchoring point for the untransformable subtree.
4350  QGraphicsItem *parentOfUntransformedAncestor = untransformedAncestor->parentItem();
4351  QTransform inheritedMatrix;
4352  if (parentOfUntransformedAncestor)
4353  inheritedMatrix = parentOfUntransformedAncestor->sceneTransform();
4354  QPointF mappedPoint = (inheritedMatrix * viewportTransform).map(untransformedAncestor->pos());
4355 
4356  // COMBINE
4357  QTransform matrix = QTransform::fromTranslate(mappedPoint.x(), mappedPoint.y());
4358  if (untransformedAncestor->d_ptr->transformData)
4359  matrix = untransformedAncestor->d_ptr->transformData->computedFullTransform(&matrix);
4360 
4361  // Then transform and translate all children.
4362  for (int i = 0; i < parents.size(); ++i) {
4363  const QGraphicsItem *parent = parents.at(i);
4364  parent->d_ptr->combineTransformFromParent(&matrix);
4365  }
4366 
4367  return matrix;
4368 }
4369 
4388 {
4389  // Catch simple cases first.
4390  if (other == nullptr) {
4391  qWarning("QGraphicsItem::itemTransform: null pointer passed");
4392  return QTransform();
4393  }
4394  if (other == this) {
4395  if (ok)
4396  *ok = true;
4397  return QTransform();
4398  }
4399 
4401  const QGraphicsItem *otherParent = other->d_ptr->parent;
4402 
4403  // This is other's child
4404  if (parent == other) {
4405  if (ok)
4406  *ok = true;
4407  QTransform x;
4409  return x;
4410  }
4411 
4412  // This is other's parent
4413  if (otherParent == this) {
4414  const QPointF &otherPos = other->d_ptr->pos;
4415  if (other->d_ptr->transformData) {
4416  QTransform otherToParent;
4417  other->d_ptr->combineTransformFromParent(&otherToParent);
4418  return otherToParent.inverted(ok);
4419  }
4420  if (ok)
4421  *ok = true;
4422  return QTransform::fromTranslate(-otherPos.x(), -otherPos.y());
4423  }
4424 
4425  // Siblings
4426  if (parent == otherParent) {
4427  // COMBINE
4428  const QPointF &itemPos = d_ptr->pos;
4429  const QPointF &otherPos = other->d_ptr->pos;
4430  if (!d_ptr->transformData && !other->d_ptr->transformData) {
4431  QPointF delta = itemPos - otherPos;
4432  if (ok)
4433  *ok = true;
4434  return QTransform::fromTranslate(delta.x(), delta.y());
4435  }
4436 
4437  QTransform itemToParent;
4438  d_ptr->combineTransformFromParent(&itemToParent);
4439  QTransform otherToParent;
4440  other->d_ptr->combineTransformFromParent(&otherToParent);
4441  return itemToParent * otherToParent.inverted(ok);
4442  }
4443 
4444  // Find the closest common ancestor. If the two items don't share an
4445  // ancestor, then the only way is to combine their scene transforms.
4446  const QGraphicsItem *commonAncestor = commonAncestorItem(other);
4447  if (!commonAncestor) {
4449  other->d_ptr->ensureSceneTransform();
4450  return d_ptr->sceneTransform * other->d_ptr->sceneTransform.inverted(ok);
4451  }
4452 
4453  // If the two items are cousins (in sibling branches), map both to the
4454  // common ancestor, and combine the two transforms.
4455  bool cousins = other != commonAncestor && this != commonAncestor;
4456  if (cousins) {
4457  bool good = false;
4458  QTransform thisToScene = itemTransform(commonAncestor, &good);
4459  QTransform otherToScene(Qt::Uninitialized);
4460  if (good)
4461  otherToScene = other->itemTransform(commonAncestor, &good);
4462  if (!good) {
4463  if (ok)
4464  *ok = false;
4465  return QTransform();
4466  }
4467  return thisToScene * otherToScene.inverted(ok);
4468  }
4469 
4470  // One is an ancestor of the other; walk the chain.
4471  bool parentOfOther = isAncestorOf(other);
4472  const QGraphicsItem *child = parentOfOther ? other : this;
4473  const QGraphicsItem *root = parentOfOther ? this : other;
4474 
4475  QTransform x;
4476  const QGraphicsItem *p = child;
4477  do {
4478  p->d_ptr.data()->combineTransformToParent(&x);
4479  } while ((p = p->d_ptr->parent) && p != root);
4480  if (parentOfOther)
4481  return x.inverted(ok);
4482  if (ok)
4483  *ok = true;
4484  return x;
4485 }
4486 
4509 {
4510  if (!d_ptr->transformData)
4512 
4513  QTransform newTransform(combine ? matrix * d_ptr->transformData->transform : matrix);
4514  if (d_ptr->transformData->transform == newTransform)
4515  return;
4516 
4517  // Update and set the new transformation.
4519  d_ptr->setTransformHelper(newTransform);
4522  return;
4523  }
4524 
4525  // Notify the item that the transformation matrix is changing.
4526  const QVariant newTransformVariant(itemChange(ItemTransformChange,
4527  QVariant::fromValue<QTransform>(newTransform)));
4528  newTransform = qvariant_cast<QTransform>(newTransformVariant);
4529  if (d_ptr->transformData->transform == newTransform)
4530  return;
4531 
4532  // Update and set the new transformation.
4533  d_ptr->setTransformHelper(newTransform);
4534 
4535  // Send post-notification.
4536  itemChange(ItemTransformHasChanged, newTransformVariant);
4538 }
4539 
4550 {
4551  setTransform(QTransform(), false);
4552 }
4553 
4570 void QGraphicsItem::advance(int phase)
4571 {
4572  Q_UNUSED(phase);
4573 }
4574 
4584 {
4585  return d_ptr->z;
4586 }
4587 
4603 {
4604  const QVariant newZVariant(itemChange(ItemZValueChange, z));
4605  qreal newZ = newZVariant.toReal();
4606  if (newZ == d_ptr->z)
4607  return;
4608 
4609  if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex) {
4610  // Z Value has changed, we have to notify the index.
4611  d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, &newZ);
4612  }
4613 
4614  d_ptr->z = newZ;
4615  if (d_ptr->parent)
4617  else if (d_ptr->scene)
4618  d_ptr->scene->d_func()->needSortTopLevelItems = 1;
4619 
4620  if (d_ptr->scene)
4621  d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true);
4622 
4623  itemChange(ItemZValueHasChanged, newZVariant);
4624 
4627 
4628  if (d_ptr->isObject)
4629  emit static_cast<QGraphicsObject *>(this)->zChanged();
4630 }
4631 
4642 {
4643  if (!sequentialOrdering) {
4644  std::sort(children.begin(), children.end(), insertionOrder);
4645  sequentialOrdering = 1;
4646  needSortChildren = 1;
4647  }
4648  if (holesInSiblingIndex) {
4649  holesInSiblingIndex = 0;
4650  for (int i = 0; i < children.size(); ++i)
4651  children[i]->d_ptr->siblingIndex = i;
4652  }
4653 }
4654 
4659 {
4660  Q_Q(QGraphicsItem);
4661  if (scene) {
4663  q->itemChange(QGraphicsItem::ItemScenePositionHasChanged, q->scenePos());
4664  if (scenePosDescendants) {
4665  for (QGraphicsItem *item : qAsConst(scene->d_func()->scenePosItems)) {
4666  if (q->isAncestorOf(item))
4668  }
4669  }
4670  }
4671 }
4672 
4690 {
4691  if (sibling == this)
4692  return;
4693  if (!sibling || d_ptr->parent != sibling->parentItem()) {
4694  qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling);
4695  return;
4696  }
4697  QList<QGraphicsItem *> *siblings = d_ptr->parent
4698  ? &d_ptr->parent->d_ptr->children
4699  : (d_ptr->scene ? &d_ptr->scene->d_func()->topLevelItems : nullptr);
4700  if (!siblings) {
4701  qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling);
4702  return;
4703  }
4704 
4705  // First, make sure that the sibling indexes have no holes. This also
4706  // marks the children list for sorting.
4707  if (d_ptr->parent)
4709  else
4710  d_ptr->scene->d_func()->ensureSequentialTopLevelSiblingIndexes();
4711 
4712  // Only move items with the same Z value, and that need moving.
4713  int siblingIndex = sibling->d_ptr->siblingIndex;
4714  int myIndex = d_ptr->siblingIndex;
4715  if (myIndex >= siblingIndex) {
4716  siblings->move(myIndex, siblingIndex);
4717  // Fixup the insertion ordering.
4718  for (int i = 0; i < siblings->size(); ++i) {
4719  int &index = siblings->at(i)->d_ptr->siblingIndex;
4720  if (i != siblingIndex && index >= siblingIndex && index <= myIndex)
4721  ++index;
4722  }
4723  d_ptr->siblingIndex = siblingIndex;
4724  for (int i = 0; i < siblings->size(); ++i) {
4725  int &index = siblings->at(i)->d_ptr->siblingIndex;
4726  if (i != siblingIndex && index >= siblingIndex && index <= myIndex)
4727  siblings->at(i)->d_ptr->siblingOrderChange();
4728  }
4730  }
4731 }
4732 
4751 {
4753  return d_ptr->childrenBoundingRect;
4754 
4758  return d_ptr->childrenBoundingRect;
4759 }
4760 
4801 {
4802  // Find translate-only offset
4803  // COMBINE
4804  QPointF offset;
4805  const QGraphicsItem *parentItem = this;
4806  const QGraphicsItemPrivate *itemd;
4807  do {
4808  itemd = parentItem->d_ptr.data();
4809  if (itemd->transformData)
4810  break;
4811  offset += itemd->pos;
4812  } while ((parentItem = itemd->parent));
4813 
4814  QRectF br = boundingRect();
4815  br.translate(offset);
4816  if (!parentItem)
4817  return br;
4820  return br;
4821  }
4822  return parentItem->d_ptr->sceneTransform.mapRect(br);
4823 }
4824 
4848 {
4850  path.addRect(boundingRect());
4851  return path;
4852 }
4853 
4865 {
4866  Q_D(const QGraphicsItem);
4867  return (d->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
4868  || (d->flags & QGraphicsItem::ItemClipsToShape);
4869 }
4870 
4892 {
4893  Q_D(const QGraphicsItem);
4894  if (!isClipped())
4895  return QPainterPath();
4896 
4897  const QRectF thisBoundingRect(boundingRect());
4898  if (thisBoundingRect.isEmpty())
4899  return QPainterPath();
4900 
4901  QPainterPath clip;
4902  // Start with the item's bounding rect.
4903  clip.addRect(thisBoundingRect);
4904 
4905  if (d->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
4906  const QGraphicsItem *parent = this;
4907  const QGraphicsItem *lastParent = this;
4908 
4909  // Intersect any in-between clips starting at the top and moving downwards.
4910  while ((parent = parent->d_ptr->parent)) {
4911  if (parent->d_ptr->flags & ItemClipsChildrenToShape) {
4912  // Map clip to the current parent and intersect with its shape/clipPath
4913  clip = lastParent->itemTransform(parent).map(clip);
4914  clip = clip.intersected(parent->shape());
4915  if (clip.isEmpty())
4916  return clip;
4917  lastParent = parent;
4918  }
4919 
4920  if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren))
4921  break;
4922  }
4923 
4924  if (lastParent != this) {
4925  // Map clip back to the item's transform.
4926  // ### what if itemtransform fails
4927  clip = lastParent->itemTransform(this).map(clip);
4928  }
4929  }
4930 
4931  if (d->flags & ItemClipsToShape)
4932  clip = clip.intersected(shape());
4933 
4934  return clip;
4935 }
4936 
4949 bool QGraphicsItem::contains(const QPointF &point) const
4950 {
4951  return isClipped() ? clipPath().contains(point) : shape().contains(point);
4952 }
4953 
4984 {
4985  if (other == this)
4986  return true;
4987  if (!other)
4988  return false;
4989  // The items share the same clip if their closest clipper is the same, or
4990  // if one clips the other.
4992  bool otherClips = (other->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren);
4993  if (clips || otherClips) {
4994  const QGraphicsItem *closestClipper = isAncestorOf(other) ? this : parentItem();
4995  while (closestClipper && !(closestClipper->flags() & ItemClipsChildrenToShape))
4996  closestClipper = closestClipper->parentItem();
4997  const QGraphicsItem *otherClosestClipper = other->isAncestorOf(this) ? other : other->parentItem();
4998  while (otherClosestClipper && !(otherClosestClipper->flags() & ItemClipsChildrenToShape))
4999  otherClosestClipper = otherClosestClipper->parentItem();
5000  if (closestClipper == otherClosestClipper) {
5002  bool res = collidesWithPath(mapFromItem(other, other->shape()), mode);
5004  return res;
5005  }
5006  }
5007 
5008  QPainterPath otherShape = other->isClipped() ? other->clipPath() : other->shape();
5009  return collidesWithPath(mapFromItem(other, otherShape), mode);
5010 }
5011 
5027 {
5028  if (path.isEmpty()) {
5029  // No collision with empty paths.
5030  return false;
5031  }
5032 
5033  QRectF rectA(boundingRect());
5034  _q_adjustRect(&rectA);
5035  QRectF rectB(path.controlPointRect());
5036  _q_adjustRect(&rectB);
5037  if (!rectA.intersects(rectB)) {
5038  // This we can determine efficiently. If the two rects neither
5039  // intersect nor contain each other, then the two items do not collide.
5040  return false;
5041  }
5042 
5043  // For further testing, we need this item's shape or bounding rect.
5044  QPainterPath thisShape;
5046  thisShape = (isClipped() && !d_ptr->localCollisionHack) ? clipPath() : shape();
5047  else
5048  thisShape.addRect(rectA);
5049 
5050  if (thisShape == QPainterPath()) {
5051  // Empty shape? No collision.
5052  return false;
5053  }
5054 
5055  // Use QPainterPath boolean operations to determine the collision, O(N*logN).
5057  return path.intersects(thisShape);
5058  return path.contains(thisShape);
5059 }
5060 
5072 {
5073  if (d_ptr->scene)
5074  return d_ptr->scene->collidingItems(this, mode);
5075  return QList<QGraphicsItem *>();
5076 }
5077 
5088 static bool qt_QGraphicsItem_isObscured(const QGraphicsItem *item,
5089  const QGraphicsItem *other,
5090  const QRectF &rect)
5091 {
5092  return other->mapToItem(item, other->opaqueArea()).contains(rect);
5093 }
5094 
5105 {
5106  Q_D(const QGraphicsItem);
5107  if (!d->scene)
5108  return false;
5109 
5110  QRectF br = boundingRect();
5111  QRectF testRect = rect.isNull() ? br : rect;
5112 
5113  const auto items = d->scene->items(mapToScene(br), Qt::IntersectsItemBoundingRect);
5114  for (QGraphicsItem *item : items) {
5115  if (item == this)
5116  break;
5117  if (qt_QGraphicsItem_isObscured(this, item, testRect))
5118  return true;
5119  }
5120  return false;
5121 }
5122 
5145 {
5146  if (!item)
5147  return false;
5148  return qt_closestItemFirst(item, this)
5149  && qt_QGraphicsItem_isObscured(this, item, boundingRect());
5150 }
5151 
5166 {
5167  return QPainterPath();
5168 }
5169 
5193 QRegion QGraphicsItem::boundingRegion(const QTransform &itemToDeviceTransform) const
5194 {
5195  // ### Ideally we would have a better way to generate this region,
5196  // preferably something in the lines of QPainterPath::toRegion(QTransform)
5197  // coupled with a way to generate a painter path from a set of painter
5198  // operations (e.g., QPicture::toPainterPath() or so). The current
5199  // approach generates a bitmap with the size of the item's bounding rect
5200  // in device coordinates, scaled by b.r.granularity, then paints the item
5201  // into the bitmap, converts the result to a QRegion and scales the region
5202  // back to device space with inverse granularity.
5203  qreal granularity = boundingRegionGranularity();
5204  QRect deviceRect = itemToDeviceTransform.mapRect(boundingRect()).toRect();
5205  _q_adjustRect(&deviceRect);
5206  if (granularity == 0.0)
5207  return QRegion(deviceRect);
5208 
5209  int pad = 1;
5210  QSize bitmapSize(qMax(1, int(deviceRect.width() * granularity) + pad * 2),
5211  qMax(1, int(deviceRect.height() * granularity) + pad * 2));
5213  mask.fill(0);
5214  QPainter p(&mask);
5215  p.setRenderHints(QPainter::Antialiasing);
5216 
5217  // Transform painter (### this code is from QGraphicsScene::drawItemHelper
5218  // and doesn't work properly with perspective transformations).
5219  QPointF viewOrigo = itemToDeviceTransform.map(QPointF(0, 0));
5220  QPointF offset = viewOrigo - deviceRect.topLeft();
5221  p.scale(granularity, granularity);
5222  p.translate(offset);
5223  p.translate(pad, pad);
5224  p.setWorldTransform(itemToDeviceTransform, true);
5225  p.translate(itemToDeviceTransform.inverted().map(QPointF(0, 0)));
5226 
5227  // Render
5229  const_cast<QGraphicsItem *>(this)->paint(&p, &option, nullptr);
5230  p.end();
5231 
5232  // Transform QRegion back to device space
5233  QTransform unscale = QTransform::fromScale(1 / granularity, 1 / granularity);
5234  QRegion r;
5235  QBitmap colorMask = QBitmap::fromImage(mask.createMaskFromColor(0));
5236  for (const QRect &rect : QRegion(colorMask)) {
5237  QRect xrect = unscale.mapRect(rect).translated(deviceRect.topLeft() - QPoint(pad, pad));
5238  r += xrect.adjusted(-1, -1, 1, 1) & deviceRect;
5239  }
5240  return r;
5241 }
5242 
5257 {
5260  : 0;
5261 }
5262 
5283 {
5284  if (granularity < 0.0 || granularity > 1.0) {
5285  qWarning("QGraphicsItem::setBoundingRegionGranularity: invalid granularity %g", granularity);
5286  return;
5287  }
5288  if (granularity == 0.0) {
5291  return;
5292  }
5295  QVariant::fromValue<qreal>(granularity));
5296 }
5297 
5346 bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreVisibleBit, bool ignoreDirtyBit,
5347  bool ignoreOpacity) const
5348 {
5349  // No scene, or if the scene is updating everything, means we have nothing
5350  // to do. The only exception is if the scene tracks the growing scene rect.
5351  return !scene
5352  || (!visible && !ignoreVisibleBit && !this->ignoreVisible)
5353  || (!ignoreDirtyBit && fullUpdatePending)
5354  || (!ignoreOpacity && !this->ignoreOpacity && childrenCombineOpacity() && isFullyTransparent());
5355 }
5356 
5361 {
5362  if (itemDepth == -1)
5363  const_cast<QGraphicsItemPrivate *>(this)->resolveDepth();
5364 
5365  return itemDepth;
5366 }
5367 
5371 #if QT_CONFIG(graphicseffect)
5372 void QGraphicsItemPrivate::invalidateParentGraphicsEffectsRecursively()
5373 {
5374  QGraphicsItemPrivate *itemPrivate = this;
5375  do {
5376  if (itemPrivate->graphicsEffect) {
5377  itemPrivate->notifyInvalidated = 1;
5378 
5379  if (!itemPrivate->updateDueToGraphicsEffect)
5380  static_cast<QGraphicsItemEffectSourcePrivate *>(itemPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache();
5381  }
5382  } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : nullptr));
5383 }
5384 
5385 void QGraphicsItemPrivate::invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::InvalidateReason reason)
5386 {
5388  return;
5389 
5390  for (int i = 0; i < children.size(); ++i) {
5391  QGraphicsItemPrivate *childPrivate = children.at(i)->d_ptr.data();
5392  if (reason == OpacityChanged && (childPrivate->flags & QGraphicsItem::ItemIgnoresParentOpacity))
5393  continue;
5394  if (childPrivate->graphicsEffect) {
5395  childPrivate->notifyInvalidated = 1;
5396  static_cast<QGraphicsItemEffectSourcePrivate *>(childPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache();
5397  }
5398 
5399  childPrivate->invalidateChildGraphicsEffectsRecursively(reason);
5400  }
5401 }
5402 #endif // QT_CONFIG(graphicseffect)
5403 
5408 {
5409  if (itemDepth == -1)
5410  return;
5411 
5412  itemDepth = -1;
5413  for (int i = 0; i < children.size(); ++i)
5415 }
5416 
5423 {
5424  if (!parent)
5425  itemDepth = 0;
5426  else {
5427  if (parent->d_ptr->itemDepth == -1)
5429  itemDepth = parent->d_ptr->itemDepth + 1;
5430  }
5431 }
5432 
5440 {
5441  // Remove all holes from the sibling index list. Now the max index
5442  // number is equal to the size of the children list.
5444  needSortChildren = 1; // ### maybe 0
5445  child->d_ptr->siblingIndex = children.size();
5447  if (isObject)
5448  emit static_cast<QGraphicsObject *>(q_ptr)->childrenChanged();
5449 }
5450 
5458 {
5459  // When removing elements in the middle of the children list,
5460  // there will be a "gap" in the list of sibling indexes (0,1,3,4).
5461  if (!holesInSiblingIndex)
5462  holesInSiblingIndex = child->d_ptr->siblingIndex != children.size() - 1;
5464  children.removeAt(child->d_ptr->siblingIndex);
5465  else
5467  // NB! Do not use children.removeAt(child->d_ptr->siblingIndex) because
5468  // the child is not guaranteed to be at the index after the list is sorted.
5469  // (see ensureSortedChildren()).
5470  child->d_ptr->siblingIndex = -1;
5471  if (isObject)
5472  emit static_cast<QGraphicsObject *>(q_ptr)->childrenChanged();
5473 }
5474 
5479 {
5480  return (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
5481 }
5482 
5487 {
5488  QGraphicsItemCache *c = (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
5489  if (!c) {
5490  QGraphicsItemPrivate *that = const_cast<QGraphicsItemPrivate *>(this);
5491  c = new QGraphicsItemCache;
5492  that->setExtra(ExtraCacheData, QVariant::fromValue<void *>(c));
5493  }
5494  return c;
5495 }
5496 
5501 {
5502  QGraphicsItemCache *c = (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
5503  if (c) {
5504  c->purge();
5505  delete c;
5506  }
5508 }
5509 
5511 {
5512  if (!scene)
5513  return;
5514 
5515  for (int i = 0; i < scene->d_func()->views.size(); ++i) {
5516  QGraphicsViewPrivate *viewPrivate = scene->d_func()->views.at(i)->d_func();
5517  QRect rect = paintedViewBoundingRects.value(viewPrivate->viewport);
5518  rect.translate(viewPrivate->dirtyScrollOffset);
5519  viewPrivate->updateRect(rect);
5520  }
5521 
5522  if (updateChildren) {
5523  for (int i = 0; i < children.size(); ++i)
5525  }
5526 }
5527 
5528 // Traverses all the ancestors up to the top-level and updates the pointer to
5529 // always point to the top-most item that has a dirty scene transform.
5530 // It then backtracks to the top-most dirty item and start calculating the
5531 // scene transform by combining the item's transform (+pos) with the parent's
5532 // cached scene transform (which we at this point know for sure is valid).
5534 {
5535  Q_ASSERT(topMostDirtyItem);
5536 
5537  if (dirtySceneTransform)
5538  *topMostDirtyItem = q_ptr;
5539 
5540  if (parent)
5541  parent->d_ptr->ensureSceneTransformRecursive(topMostDirtyItem);
5542 
5543  if (*topMostDirtyItem == q_ptr) {
5544  if (!dirtySceneTransform)
5545  return; // OK, neither my ancestors nor I have dirty scene transforms.
5546  *topMostDirtyItem = nullptr;
5547  } else if (*topMostDirtyItem) {
5548  return; // Continue backtrack.
5549  }
5550 
5551  // This item and all its descendants have dirty scene transforms.
5552  // We're about to validate this item's scene transform, so we have to
5553  // invalidate all the children; otherwise there's no way for the descendants
5554  // to detect that the ancestor has changed.
5556 
5557  // COMBINE my transform with the parent's scene transform.
5560 }
5561 
5566 {
5567  // Update focus child chain. Stop at panels, or if this item
5568  // is hidden, stop at the first item with a visible parent.
5569  QGraphicsItem *parent = rootItem ? rootItem : q_ptr;
5570  if (parent->panel() != q_ptr->panel())
5571  return;
5572 
5573  do {
5574  // Clear any existing ancestor's subFocusItem.
5575  if (parent != q_ptr && parent->d_ptr->subFocusItem) {
5576  if (parent->d_ptr->subFocusItem == q_ptr)
5577  break;
5578  parent->d_ptr->subFocusItem->d_ptr->clearSubFocus(nullptr, stopItem);
5579  }
5582  } while (!parent->isPanel() && (parent = parent->d_ptr->parent) && (visible || !parent->d_ptr->visible));
5583 
5584  if (scene && !scene->isActive()) {
5585  scene->d_func()->passiveFocusItem = subFocusItem;
5586  scene->d_func()->lastFocusItem = subFocusItem;
5587  }
5588 }
5589 
5594 {
5595  // Reset sub focus chain.
5596  QGraphicsItem *parent = rootItem ? rootItem : q_ptr;
5597  do {
5598  if (parent->d_ptr->subFocusItem != q_ptr)
5599  break;
5600  parent->d_ptr->subFocusItem = nullptr;
5601  if (parent != stopItem && !parent->isAncestorOf(stopItem))
5603  } while (!parent->isPanel() && (parent = parent->d_ptr->parent));
5604 }
5605 
5613 {
5614  for (int i = 0; i < focusProxyRefs.size(); ++i)
5615  *focusProxyRefs.at(i) = nullptr;
5617 }
5618 
5626 {
5627 }
5628 
5636 {
5637  Q_UNUSED(isSubFocusItem);
5638 }
5639 
5647 {
5648 }
5649 
5656 {
5657  return false;
5658 }
5659 
5679 {
5680  if (rect.isEmpty() && !rect.isNull())
5681  return;
5682 
5683  // Make sure we notify effects about invalidated source.
5684 #if QT_CONFIG(graphicseffect)
5685  d_ptr->invalidateParentGraphicsEffectsRecursively();
5686 #endif // QT_CONFIG(graphicseffect)
5687 
5688  if (CacheMode(d_ptr->cacheMode) != NoCache) {
5689  // Invalidate cache.
5691  if (!cache->allExposed) {
5692  if (rect.isNull()) {
5693  cache->allExposed = true;
5694  cache->exposed.clear();
5695  } else {
5696  cache->exposed.append(rect);
5697  }
5698  }
5699  // Only invalidate cache; item is already dirty.
5700  if (d_ptr->fullUpdatePending)
5701  return;
5702  }
5703 
5704  if (d_ptr->scene)
5705  d_ptr->scene->d_func()->markDirty(this, rect);
5706 }
5707 
5736 {
5737  Q_D(QGraphicsItem);
5738  if (dx == 0.0 && dy == 0.0)
5739  return;
5740  if (!d->scene)
5741  return;
5742 
5743  // Accelerated scrolling means moving pixels from one location to another
5744  // and only redraw the newly exposed area. The following requirements must
5745  // be fulfilled in order to do that:
5746  //
5747  // 1) Item is opaque.
5748  // 2) Item is not overlapped by other items.
5749  //
5750  // There's (yet) no way to detect whether an item is opaque or not, which means
5751  // we cannot do accelerated scrolling unless the cache is enabled. In case of using
5752  // DeviceCoordinate cache we also have to take the device transform into account in
5753  // order to determine whether we can do accelerated scrolling or not. That's left out
5754  // for simplicity here, but it is definitely something we can consider in the future
5755  // as a performance improvement.
5756  if (d->cacheMode != QGraphicsItem::ItemCoordinateCache
5757  || !qFuzzyIsNull(dx - int(dx)) || !qFuzzyIsNull(dy - int(dy))) {
5758  update(rect);
5759  return;
5760  }
5761 
5762  QGraphicsItemCache *cache = d->extraItemCache();
5763  if (cache->allExposed || cache->fixedSize.isValid()) {
5764  // Cache is either invalidated or item is scaled (see QGraphicsItem::setCacheMode).
5765  update(rect);
5766  return;
5767  }
5768 
5769  // Find pixmap in cache.
5770  QPixmap cachedPixmap;
5771  if (!QPixmapCache::find(cache->key, &cachedPixmap)) {
5772  update(rect);
5773  return;
5774  }
5775 
5776  QRect scrollRect = (rect.isNull() ? boundingRect() : rect).toAlignedRect();
5777  if (!scrollRect.intersects(cache->boundingRect))
5778  return; // Nothing to scroll.
5779 
5780  // Remove from cache to avoid deep copy when modifying.
5782 
5783  QRegion exposed;
5784  cachedPixmap.scroll(dx, dy, scrollRect.translated(-cache->boundingRect.topLeft()), &exposed);
5785 
5786  // Reinsert into cache.
5787  cache->key = QPixmapCache::insert(cachedPixmap);
5788 
5789  // Translate the existing expose.
5790  for (int i = 0; i < cache->exposed.size(); ++i) {
5791  QRectF &e = cache->exposed[i];
5792  if (!rect.isNull() && !e.intersects(rect))
5793  continue;
5794  e.translate(dx, dy);
5795  }
5796 
5797  // Append newly exposed areas. Note that the exposed region is currently
5798  // in pixmap coordinates, so we have to translate it to item coordinates.
5799  exposed.translate(cache->boundingRect.topLeft());
5800  for (const QRect &exposedRect : exposed)
5801  cache->exposed += exposedRect;
5802 
5803  // Trigger update. This will redraw the newly exposed area and make sure
5804  // the pixmap is re-blitted in case there are overlapping items.
5805  d->scene->d_func()->markDirty(this, rect);
5806 }
5807 
5826 {
5827  if (item)
5828  return itemTransform(item).map(point);
5829  return mapToScene(point);
5830 }
5831 
5849 {
5850  // COMBINE
5851  if (!d_ptr->transformData)
5852  return point + d_ptr->pos;
5853  return d_ptr->transformToParent().map(point);
5854 }
5855 
5872 {
5874  return QPointF(point.x() + d_ptr->sceneTransform.dx(), point.y() + d_ptr->sceneTransform.dy());
5875  return d_ptr->sceneTransform.map(point);
5876 }
5877 
5896 {
5897  if (item)
5898  return itemTransform(item).map(rect);
5899  return mapToScene(rect);
5900 }
5901 
5919 {
5920  // COMBINE
5921  if (!d_ptr->transformData)
5922  return rect.translated(d_ptr->pos);
5923  return d_ptr->transformToParent().map(rect);
5924 }
5925 
5941 {
5943  return rect.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
5944  return d_ptr->sceneTransform.map(rect);
5945 }
5946 
5967 {
5968  if (item)
5969  return itemTransform(item).mapRect(rect);
5970  return mapRectToScene(rect);
5971 }
5972 
5991 {
5992  // COMBINE
5993  if (!d_ptr->transformData)
5994  return rect.translated(d_ptr->pos);
5995  return d_ptr->transformToParent().mapRect(rect);
5996 }
5997 
6016 {
6018  return rect.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
6019  return d_ptr->sceneTransform.mapRect(rect);
6020 }
6021 
6042 {
6043  if (item)
6044  return item->itemTransform(this).mapRect(rect);
6045  return mapRectFromScene(rect);
6046 }
6047 
6067 {
6068  // COMBINE
6069  if (!d_ptr->transformData)
6070  return rect.translated(-d_ptr->pos);
6072 }
6073 
6092 {
6094  return rect.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
6096 }
6097 
6115 {
6116  if (item)
6117  return itemTransform(item).map(polygon);
6118  return mapToScene(polygon);
6119 }
6120 
6131 {
6132  // COMBINE
6133  if (!d_ptr->transformData)
6134  return polygon.translated(d_ptr->pos);
6135  return d_ptr->transformToParent().map(polygon);
6136 }
6137 
6146 {
6148  return polygon.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
6149  return d_ptr->sceneTransform.map(polygon);
6150 }
6151 
6162 {
6163  if (item)
6164  return itemTransform(item).map(path);
6165  return mapToScene(path);
6166 }
6167 
6178 {
6179  // COMBINE
6180  if (!d_ptr->transformData)
6181  return path.translated(d_ptr->pos);
6182  return d_ptr->transformToParent().map(path);
6183 }
6184 
6193 {
6195  return path.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
6196  return d_ptr->sceneTransform.map(path);
6197 }
6198 
6209 {
6210  if (item)
6211  return item->itemTransform(this).map(point);
6212  return mapFromScene(point);
6213 }
6214 
6232 {
6233  // COMBINE
6234  if (d_ptr->transformData)
6235  return d_ptr->transformToParent().inverted().map(point);
6236  return point - d_ptr->pos;
6237 }
6238 
6256 {
6258  return QPointF(point.x() - d_ptr->sceneTransform.dx(), point.y() - d_ptr->sceneTransform.dy());
6259  return d_ptr->sceneTransform.inverted().map(point);
6260 }
6261 
6281 {
6282  if (item)
6283  return item->itemTransform(this).map(rect);
6284  return mapFromScene(rect);
6285 }
6286 
6303 {
6304  // COMBINE
6305  if (!d_ptr->transformData)
6306  return rect.translated(-d_ptr->pos);
6307  return d_ptr->transformToParent().inverted().map(rect);
6308 }
6309 
6326 {
6328  return rect.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
6329  return d_ptr->sceneTransform.inverted().map(rect);
6330 }
6331 
6349 {
6350  if (item)
6351  return item->itemTransform(this).map(polygon);
6352  return mapFromScene(polygon);
6353 }
6354 
6363 {
6364  // COMBINE
6365  if (!d_ptr->transformData)
6366  return polygon.translated(-d_ptr->pos);
6368 }
6369 
6378 {
6380  return polygon.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
6382 }
6383 
6394 {
6395  if (item)
6396  return item->itemTransform(this).map(path);
6397  return mapFromScene(path);
6398 }
6399 
6408 {
6409  // COMBINE
6410  if (!d_ptr->transformData)
6411  return path.translated(-d_ptr->pos);
6412  return d_ptr->transformToParent().inverted().map(path);
6413 }
6414 
6423 {
6425  return path.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
6426  return d_ptr->sceneTransform.inverted().map(path);
6427 }
6428 
6436 {
6437  if (!child || child == this)
6438  return false;
6439  if (child->d_ptr->depth() < d_ptr->depth())
6440  return false;
6441  const QGraphicsItem *ancestor = child;
6442  while ((ancestor = ancestor->d_ptr->parent)) {
6443  if (ancestor == this)
6444  return true;
6445  }
6446  return false;
6447 }
6448 
6458 {
6459  if (!other)
6460  return nullptr;
6461  if (other == this)
6462  return const_cast<QGraphicsItem *>(this);
6463  const QGraphicsItem *thisw = this;
6464  const QGraphicsItem *otherw = other;
6465  int thisDepth = d_ptr->depth();
6466  int otherDepth = other->d_ptr->depth();
6467  while (thisDepth > otherDepth) {
6468  thisw = thisw->d_ptr->parent;
6469  --thisDepth;
6470  }
6471  while (otherDepth > thisDepth) {
6472  otherw = otherw->d_ptr->parent;
6473  --otherDepth;
6474  }
6475  while (thisw && thisw != otherw) {
6476  thisw = thisw->d_ptr->parent;
6477  otherw = otherw->d_ptr->parent;
6478  }
6479  return const_cast<QGraphicsItem *>(thisw);
6480 }
6481 
6490 {
6491  Q_D(const QGraphicsItem);
6492  if (!d->scene)
6493  return false;
6494 
6495  QPoint cursorPos = QCursor::pos();
6496  const auto views = d->scene->views();
6497  for (QGraphicsView *view : views) {
6498  if (contains(mapFromScene(view->mapToScene(view->mapFromGlobal(cursorPos)))))
6499  return true;
6500  }
6501  return false;
6502 }
6503 
6518 {
6519  QGraphicsItemCustomDataStore *store = qt_dataStore();
6520  if (!store->data.contains(this))
6521  return QVariant();
6522  return store->data.value(this).value(key);
6523 }
6524 
6535 {
6536  qt_dataStore()->data[this][key] = value;
6537 }
6538 
6572 {
6573  return (int)UserType;
6574 }
6575 
6596 {
6597  if (!d_ptr->scene) {
6598  qWarning("QGraphicsItem::installSceneEventFilter: event filters can only be installed"
6599  " on items in a scene.");
6600  return;
6601  }
6602  if (d_ptr->scene != filterItem->scene()) {
6603  qWarning("QGraphicsItem::installSceneEventFilter: event filters can only be installed"
6604  " on items in the same scene.");
6605  return;
6606  }
6607  d_ptr->scene->d_func()->installSceneEventFilter(this, filterItem);
6608 }
6609 
6616 {
6617  if (!d_ptr->scene || d_ptr->scene != filterItem->scene())
6618  return;
6619  d_ptr->scene->d_func()->removeSceneEventFilter(this, filterItem);
6620 }
6621 
6639 {
6640  Q_UNUSED(watched);
6641  Q_UNUSED(event);
6642  return false;
6643 }
6644 
6660 {
6662  if (event->type() == QEvent::HoverEnter || event->type() == QEvent::HoverLeave
6663  || event->type() == QEvent::DragEnter || event->type() == QEvent::DragLeave) {
6664  // Hover enter and hover leave events for children are ignored;
6665  // hover move events are forwarded.
6666  return true;
6667  }
6668 
6669  QGraphicsItem *handler = this;
6670  do {
6671  handler = handler->d_ptr->parent;
6672  Q_ASSERT(handler);
6674  // Forward the event to the closest parent that handles child
6675  // events, mapping existing item-local coordinates to its
6676  // coordinate system.
6677  d_ptr->remapItemPos(event, handler);
6678  handler->sceneEvent(event);
6679  return true;
6680  }
6681 
6682  if (event->type() == QEvent::FocusOut) {
6683  focusOutEvent(static_cast<QFocusEvent *>(event));
6684  return true;
6685  }
6686 
6687  if (!d_ptr->visible) {
6688  // Eaten
6689  return true;
6690  }
6691 
6692  switch (event->type()) {
6693  case QEvent::FocusIn:
6694  focusInEvent(static_cast<QFocusEvent *>(event));
6695  break;
6698  break;
6701  break;
6704  break;
6707  break;
6709  dropEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
6710  break;
6713  break;
6716  break;
6719  break;
6722  break;
6725  break;
6728  break;
6731  break;
6733  wheelEvent(static_cast<QGraphicsSceneWheelEvent *>(event));
6734  break;
6735  case QEvent::KeyPress: {
6736  QKeyEvent *k = static_cast<QKeyEvent *>(event);
6737  if (k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) {
6738  if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier?
6739  bool res = false;
6740  if (k->key() == Qt::Key_Backtab
6741  || (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier))) {
6742  if (d_ptr->isWidget) {
6743  res = static_cast<QGraphicsWidget *>(this)->focusNextPrevChild(false);
6744  } else if (d_ptr->scene) {
6745  res = d_ptr->scene->focusNextPrevChild(false);
6746  }
6747  } else if (k->key() == Qt::Key_Tab) {
6748  if (d_ptr->isWidget) {
6749  res = static_cast<QGraphicsWidget *>(this)->focusNextPrevChild(true);
6750  } else if (d_ptr->scene) {
6751  res = d_ptr->scene->focusNextPrevChild(true);
6752  }
6753  }
6754  if (!res)
6755  event->ignore();
6756  return true;
6757  }
6758  }
6759  keyPressEvent(static_cast<QKeyEvent *>(event));
6760  break;
6761  }
6762  case QEvent::KeyRelease:
6763  keyReleaseEvent(static_cast<QKeyEvent *>(event));
6764  break;
6765  case QEvent::InputMethod:
6766  inputMethodEvent(static_cast<QInputMethodEvent *>(event));
6767  break;
6770  // Propagate panel activation.
6771  if (d_ptr->scene) {
6772  for (int i = 0; i < d_ptr->children.size(); ++i) {
6774  if (child->isVisible() && !child->isPanel()) {
6775  if (!(child->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorHandlesChildEvents))
6777  }
6778  }
6779  }
6780  break;
6781  default:
6782  return false;
6783  }
6784 
6785  return true;
6786 }
6787 
6807 {
6808  event->ignore();
6809 }
6810 
6835 {
6836  Q_D(QGraphicsItem);
6837  // binary compatibility workaround between 4.4 and 4.5
6838  if (d->isProxyWidget())
6839  static_cast<QGraphicsProxyWidget*>(this)->dragEnterEvent(event);
6840 }
6841 
6859 {
6860  Q_D(QGraphicsItem);
6861  // binary compatibility workaround between 4.4 and 4.5
6862  if (d->isProxyWidget())
6863  static_cast<QGraphicsProxyWidget*>(this)->dragLeaveEvent(event);
6864 }
6865 
6886 {
6887  Q_D(QGraphicsItem);
6888  // binary compatibility workaround between 4.4 and 4.5
6889  if (d->isProxyWidget())
6890  static_cast<QGraphicsProxyWidget*>(this)->dragMoveEvent(event);
6891 }
6892 
6908 {
6909  Q_D(QGraphicsItem);
6910  // binary compatibility workaround between 4.4 and 4.5
6911  if (d->isProxyWidget())
6912  static_cast<QGraphicsProxyWidget*>(this)->dropEvent(event);
6913 }
6914 
6923 {
6924  Q_UNUSED(event);
6925  update();
6926 }
6927 
6935 {
6936  Q_UNUSED(event);
6937  update();
6938 }
6939 
6950 {
6951  Q_UNUSED(event);
6952  update();
6953 }
6954 
6964 {
6965  Q_UNUSED(event);
6966 }
6967 
6978 {
6979  Q_UNUSED(event);
6980  update();
6981 }
6982 
6996 {
6997  event->ignore();
6998 }
6999 
7013 {
7014  event->ignore();
7015 }
7016 
7051 {
7052  if (event->button() == Qt::LeftButton && (flags() & ItemIsSelectable)) {
7053  bool multiSelect = (event->modifiers() & Qt::ControlModifier) != 0;
7054  if (!multiSelect) {
7055  if (!d_ptr->selected) {
7056  if (QGraphicsScene *scene = d_ptr->scene) {
7057  ++scene->d_func()->selectionChanging;
7058  scene->clearSelection();
7059  --scene->d_func()->selectionChanging;
7060  }
7061  setSelected(true);
7062  }
7063  }
7064  } else if (!(flags() & ItemIsMovable)) {
7065  event->ignore();
7066  }
7067  if (d_ptr->isWidget) {
7068  // Qt::Popup closes when you click outside.
7069  QGraphicsWidget *w = static_cast<QGraphicsWidget *>(this);
7070  if ((w->windowFlags() & Qt::Popup) == Qt::Popup) {
7071  event->accept();
7072  if (!w->rect().contains(event->pos()))
7073  w->close();
7074  }
7075  }
7076 }
7077 
7079 {
7080  const QGraphicsItem *parent = item->parentItem();
7081  return parent && (((parent->flags() & QGraphicsItem::ItemIsMovable) && parent->isSelected()) || _qt_movableAncestorIsSelected(parent));
7082 }
7083 
7085 {
7086  const QGraphicsItem *parent = item->d_ptr->parent;
7088 }
7089 
7112 {
7113  if ((event->buttons() & Qt::LeftButton) && (flags() & ItemIsMovable)) {
7114  // Determine the list of items that need to be moved.
7115  QList<QGraphicsItem *> selectedItems;
7116  QHash<QGraphicsItem *, QPointF> initialPositions;
7117  if (d_ptr->scene) {
7118  selectedItems = d_ptr->scene->selectedItems();
7119  initialPositions = d_ptr->scene->d_func()->movingItemsInitialPositions;
7120  if (initialPositions.isEmpty()) {
7121  for (QGraphicsItem *item : qAsConst(selectedItems))
7122  initialPositions[item] = item->pos();
7123  initialPositions[this] = pos();
7124  }
7125  d_ptr->scene->d_func()->movingItemsInitialPositions = initialPositions;
7126  }
7127 
7128  // Find the active view.
7129  QGraphicsView *view = nullptr;
7130  if (event->widget())
7131  view = qobject_cast<QGraphicsView *>(event->widget()->parentWidget());
7132 
7133  // Move all selected items
7134  int i = 0;
7135  bool movedMe = false;
7136  while (i <= selectedItems.size()) {
7137  QGraphicsItem *item = nullptr;
7138  if (i < selectedItems.size())
7139  item = selectedItems.at(i);
7140  else
7141  item = this;
7142  if (item == this) {
7143  // Slightly clumsy-looking way to ensure that "this" is part
7144  // of the list of items to move, this is to avoid allocations
7145  // (appending this item to the list of selected items causes a
7146  // detach).
7147  if (movedMe)
7148  break;
7149  movedMe = true;
7150  }
7151 
7153  QPointF currentParentPos;
7154  QPointF buttonDownParentPos;
7156  // Items whose ancestors ignore transformations need to
7157  // map screen coordinates to local coordinates, then map
7158  // those to the parent.
7159  QTransform viewToItemTransform = (item->deviceTransform(view->viewportTransform())).inverted();
7160  currentParentPos = mapToParent(viewToItemTransform.map(QPointF(view->mapFromGlobal(event->screenPos()))));
7161  buttonDownParentPos = mapToParent(viewToItemTransform.map(QPointF(view->mapFromGlobal(event->buttonDownScreenPos(Qt::LeftButton)))));
7162  } else if (view && (item->flags() & ItemIgnoresTransformations)) {
7163  // Root items that ignore transformations need to
7164  // calculate their diff by mapping viewport coordinates
7165  // directly to parent coordinates.
7166  // COMBINE
7168  if (item->d_ptr->transformData)
7171  QTransform viewToParentTransform = itemTransform
7172  * (item->sceneTransform() * view->viewportTransform()).inverted();
7173  currentParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->screenPos())));
7174  buttonDownParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->buttonDownScreenPos(Qt::LeftButton))));
7175  } else {
7176  // All other items simply map from the scene.
7177  currentParentPos = item->mapToParent(item->mapFromScene(event->scenePos()));
7178  buttonDownParentPos = item->mapToParent(item->mapFromScene(event->buttonDownScenePos(Qt::LeftButton)));
7179  }
7180 
7181  item->setPos(initialPositions.value(item) + currentParentPos - buttonDownParentPos);
7182 
7183  if (item->flags() & ItemIsSelectable)
7184  item->setSelected(true);
7185  }
7186  ++i;
7187  }
7188 
7189  } else {
7190  event->ignore();
7191  }
7192 }
7193 
7214 {
7215  if (event->button() == Qt::LeftButton && (flags() & ItemIsSelectable)) {
7216  bool multiSelect = (event->modifiers() & Qt::ControlModifier) != 0;
7217  if (event->scenePos() == event->buttonDownScenePos(Qt::LeftButton)) {
7218  // The item didn't move
7219  if (multiSelect) {
7220  setSelected(!isSelected());
7221  } else {
7222  bool selectionChanged = false;
7223  if (QGraphicsScene *scene = d_ptr->scene) {
7224  ++scene->d_func()->selectionChanging;
7225  // Clear everything but this item. Bypass
7226  // QGraphicsScene::clearSelection()'s default behavior by
7227  // temporarily removing this item from the selection list.
7228  if (d_ptr->selected) {
7229  scene->d_func()->selectedItems.remove(this);
7230  for (QGraphicsItem *item : qAsConst(scene->d_func()->selectedItems)) {
7231  if (item->isSelected()) {
7232  selectionChanged = true;
7233  break;
7234  }
7235  }
7236  }
7237  scene->clearSelection();
7238  if (d_ptr->selected)
7239  scene->d_func()->selectedItems.insert(this);
7240  --scene->d_func()->selectionChanging;
7241  if (selectionChanged)
7243  }
7244  setSelected(true);
7245  }
7246  }
7247  }
7248  if (d_ptr->scene && !event->buttons())
7249  d_ptr->scene->d_func()->movingItemsInitialPositions.clear();
7250 }
7251 
7277 {
7279 }
7280 
7296 {
7297  event->ignore();
7298 }
7299 
7308 {
7309  event->ignore();
7310 }
7311 
7322 {
7323  Q_UNUSED(query);
7324  return QVariant();
7325 }
7326 
7341 Qt::InputMethodHints QGraphicsItem::inputMethodHints() const
7342 {
7343  Q_D(const QGraphicsItem);
7344  return d->imHints;
7345 }
7346 
7354 void QGraphicsItem::setInputMethodHints(Qt::InputMethodHints hints)
7355 {
7356  Q_D(QGraphicsItem);
7357  d->imHints = hints;
7358  if (!hasFocus())
7359  return;
7360  d->scene->d_func()->updateInputMethodSensitivityInViews();
7362  if (!fw)
7363  return;
7365 }
7366 
7375 {
7376 }
7377 
7400 {
7401  Q_UNUSED(change);
7402  return value;
7403 }
7404 
7412 {
7414  return false;
7415 }
7416 
7424 {
7426  Q_UNUSED(variant);
7427 }
7428 
7436 {
7437  Q_UNUSED(variant);
7438  return QVariant();
7439 }
7440 
7449 {
7452  // ### add to child index only if applicable
7453  return;
7454  }
7455  if (d_ptr->scene)
7456  d_ptr->scene->d_func()->index->addItem(this);
7457 }
7458 
7467 {
7470  // ### remove from child index only if applicable
7471  return;
7472  }
7473  if (d_ptr->scene)
7474  d_ptr->scene->d_func()->index->removeItem(this);
7475 }
7476 
7491 {
7492  if (d_ptr->inDestructor)
7493  return;
7494  if (d_ptr->scene) {
7495  d_ptr->scene->d_func()->dirtyGrowingItemsBoundingRect = true;
7496  d_ptr->geometryChanged = 1;
7499 
7500  QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func();
7501  scenePrivate->index->prepareBoundingRectChange(this);
7502  scenePrivate->markDirty(this, QRectF(), /*invalidateChildren=*/true, /*force=*/false,
7503  /*ignoreOpacity=*/ false, /*removingItemFromScene=*/ false,
7504  /*updateBoundingRect=*/true);
7505 
7506  // For compatibility reasons, we have to update the item's old geometry
7507  // if someone is connected to the changed signal or the scene has no views.
7508  // Note that this has to be done *after* markDirty to ensure that
7509  // _q_processDirtyItems is called before _q_emitUpdated.
7510  if (scenePrivate->isSignalConnected(scenePrivate->changedSignalIndex)
7511  || scenePrivate->views.isEmpty()) {
7513  d_ptr->scene->update(boundingRect().translated(d_ptr->sceneTransform.dx(),
7514  d_ptr->sceneTransform.dy()));
7515  } else {
7517  }
7518  }
7519  }
7520 
7521  d_ptr->markParentDirty(/*updateBoundingRect=*/true);
7522 }
7523 
7531 {
7532  const QRectF murect = painter->transform().mapRect(QRectF(0, 0, 1, 1));
7533  if (qFuzzyIsNull(qMax(murect.width(), murect.height())))
7534  return;
7535 
7536  const QRectF mbrect = painter->transform().mapRect(item->boundingRect());
7537  if (qMin(mbrect.width(), mbrect.height()) < qreal(1.0))
7538  return;
7539 
7540  qreal itemPenWidth;
7541  switch (item->type()) {
7543  itemPenWidth = static_cast<QGraphicsEllipseItem *>(item)->pen().widthF();
7544  break;
7546  itemPenWidth = static_cast<QGraphicsPathItem *>(item)->pen().widthF();
7547  break;
7549  itemPenWidth = static_cast<QGraphicsPolygonItem *>(item)->pen().widthF();
7550  break;
7552  itemPenWidth = static_cast<QGraphicsRectItem *>(item)->pen().widthF();
7553  break;
7555  itemPenWidth = static_cast<QGraphicsSimpleTextItem *>(item)->pen().widthF();
7556  break;
7558  itemPenWidth = static_cast<QGraphicsLineItem *>(item)->pen().widthF();
7559  break;
7560  default:
7561  itemPenWidth = 1.0;
7562  }
7563  const qreal pad = itemPenWidth / 2;
7564 
7565  const qreal penWidth = 0; // cosmetic pen
7566 
7567  const QColor fgcolor = option->palette.windowText().color();
7568  const QColor bgcolor( // ensure good contrast against fgcolor
7569  fgcolor.red() > 127 ? 0 : 255,
7570  fgcolor.green() > 127 ? 0 : 255,
7571  fgcolor.blue() > 127 ? 0 : 255);
7572 
7573  painter->setPen(QPen(bgcolor, penWidth, Qt::SolidLine));
7575  painter->drawRect(item->boundingRect().adjusted(pad, pad, -pad, -pad));
7576 
7577  painter->setPen(QPen(option->palette.windowText(), 0, Qt::DashLine));
7579  painter->drawRect(item->boundingRect().adjusted(pad, pad, -pad, -pad));
7580 }
7581 
7615 {
7617 }
7618 
7623  : QGraphicsItem(dd, parent)
7624 {
7626 }
7627 
7631 QGraphicsObject::~QGraphicsObject()
7632 {
7633 }
7634 
7639 {
7640  if (ev->type() == QEvent::StyleAnimationUpdate) {
7641  if (isVisible()) {
7642  ev->accept();
7643  update();
7644  }
7645  return true;
7646  }
7647  return QObject::event(ev);
7648 }
7649 
7650 #ifndef QT_NO_GESTURES
7656 void QGraphicsObject::grabGesture(Qt::GestureType gesture, Qt::GestureFlags flags)
7657 {
7661  QGraphicsItem::d_ptr->scene->d_func()->grabGesture(this, gesture);
7662 }
7663 
7669 void QGraphicsObject::ungrabGesture(Qt::GestureType gesture)
7670 {
7671  if (QGraphicsItem::d_ptr->gestureContext.remove(gesture) && QGraphicsItem::d_ptr->scene)
7672  QGraphicsItem::d_ptr->scene->d_func()->ungrabGesture(this, gesture);
7673 }
7674 #endif // QT_NO_GESTURES
7675 
7684 {
7686 }
7687 
7689 {
7690  if (item) {
7691  QGraphicsObject *graphicsObject = static_cast<QGraphicsObject *>(list->object);
7693  item->setParentItem(graphicsObject);
7694  } else {
7695  QGraphicsItemPrivate::get(item)->setParentItemHelper(graphicsObject, nullptr, nullptr);
7696  }
7697  }
7698 }
7699 
7701 {
7703  return d->children.count();
7704 }
7705 
7707 {
7709  if (index >= 0 && index < d->children.count())
7710  return d->children.at(index)->toGraphicsObject();
7711  else
7712  return nullptr;
7713 }
7714 
7716 {
7718  int childCount = d->children.count();
7719  if (d->sendParentChangeNotification) {
7720  for (int index = 0; index < childCount; index++)
7721  d->children.at(0)->setParentItem(nullptr);
7722  } else {
7723  for (int index = 0; index < childCount; index++)
7724  QGraphicsItemPrivate::get(d->children.at(0))->setParentItemHelper(nullptr, nullptr, nullptr);
7725  }
7726 }
7727 
7736 {
7737  Q_Q(QGraphicsItem);
7738  if (isObject) {
7739  QGraphicsObject *that = static_cast<QGraphicsObject *>(q);
7742  } else {
7743  //QGraphicsItem is not supported for this property
7745  }
7746 }
7747 
7754 {
7755  return 0;
7756 }
7757 
7764 {
7765  Q_UNUSED(w);
7766 }
7767 
7774 {
7775 }
7776 
7783 {
7784  return 0;
7785 }
7786 
7793 {
7794  Q_UNUSED(h);
7795 }
7796 
7803 {
7804 }
7805 
8046 {
8047  Q_DECLARE_PUBLIC(QAbstractGraphicsShapeItem)
8048 public:
8049 
8052 
8053  // Cached bounding rectangle
8055 };
8056 
8063 {
8064 }
8065 
8070  : QGraphicsItem(dd, parent)
8071 {
8072 }
8073 
8078 {
8079 }
8080 
8086 {
8087  Q_D(const QAbstractGraphicsShapeItem);
8088  return d->pen;
8089 }
8090 
8099 {
8101  if (d->pen == pen)
8102  return;
8104  d->pen = pen;
8105  d->boundingRect = QRectF();
8106  update();
8107 }
8108 
8115 {
8116  Q_D(const QAbstractGraphicsShapeItem);
8117  return d->brush;
8118 }
8119 
8131 {
8133  if (d->brush == brush)
8134  return;
8135  d->brush = brush;
8136  update();
8137 }
8138 
8143 {
8145 }
8146 
8151 {
8152  Q_D(const QAbstractGraphicsShapeItem);
8153  if (d->brush.isOpaque())
8154  return isClipped() ? clipPath() : shape();
8155  return QGraphicsItem::opaqueArea();
8156 }
8157 
8184 {
8185  Q_DECLARE_PUBLIC(QGraphicsPathItem)
8186 public:
8188 };
8189 
8199 {
8200  if (!path.isEmpty())
8201  setPath(path);
8202 }
8203 
8212 {
8213 }
8214 
8219 {
8220 }
8221 
8229 {
8230  Q_D(const QGraphicsPathItem);
8231  return d->path;
8232 }
8233 
8240 {
8241  Q_D(QGraphicsPathItem);
8242  if (d->path == path)
8243  return;
8245  d->path = path;
8246  d->boundingRect = QRectF();
8247  update();
8248 }
8249 
8254 {
8255  Q_D(const QGraphicsPathItem);
8256  if (d->boundingRect.isNull()) {
8257  qreal pw = pen().style() == Qt::NoPen ? qreal(0) : pen().widthF();
8258  if (pw == 0.0)
8259  d->boundingRect = d->path.controlPointRect();
8260  else {
8261  d->boundingRect = shape().controlPointRect();
8262  }
8263  }
8264  return d->boundingRect;
8265 }
8266 
8271 {
8272  Q_D(const QGraphicsPathItem);
8273  return qt_graphicsItem_shapeFromPath(d->path, d->pen);
8274 }
8275 
8279 bool QGraphicsPathItem::contains(const QPointF &point) const
8280 {
8282 }
8283 
8288  QWidget *widget)
8289 {
8290  Q_D(QGraphicsPathItem);
8291  Q_UNUSED(widget);
8292  painter->setPen(d->pen);
8293  painter->setBrush(d->brush);
8294  painter->drawPath(d->path);
8295 
8296  if (option->state & QStyle::State_Selected)
8298 }
8299 
8304 {
8306 }
8307 
8312 {
8314 }
8315 
8319 int QGraphicsPathItem::type() const
8320 {
8321  return Type;
8322 }
8323 
8328 {
8330  return false;
8331 }
8332 
8337 {
8339  Q_UNUSED(variant);
8340 }
8341 
8346 {
8347  Q_UNUSED(variant);
8348  return QVariant();
8349 }
8350 
8384 {
8385  Q_DECLARE_PUBLIC(QGraphicsRectItem)
8386 public:
8388 };
8389 
8398 {
8399  setRect(rect);
8400 }
8401 
8416 {
8417  setRect(QRectF(x, y, w, h));
8418 }
8419 
8428 {
8429 }
8430 
8435 {
8436 }
8437 
8444 {
8445  Q_D(const QGraphicsRectItem);
8446  return d->rect;
8447 }
8448 
8457 {
8458  Q_D(QGraphicsRectItem);
8459  if (d->rect == rect)
8460  return;
8462  d->rect = rect;
8463  d->boundingRect = QRectF();
8464  update();
8465 }
8466 
8484 {
8485  Q_D(const QGraphicsRectItem);
8486  if (d->boundingRect.isNull()) {
8487  qreal halfpw = pen().style() == Qt::NoPen ? qreal(0) : pen().widthF() / 2;
8488  d->boundingRect = d->rect;
8489  if (halfpw > 0.0)
8490  d->boundingRect.adjust(-halfpw, -halfpw, halfpw, halfpw);
8491  }
8492  return d->boundingRect;
8493 }
8494 
8499 {
8500  Q_D(const QGraphicsRectItem);
8502  path.addRect(d->rect);
8503  return qt_graphicsItem_shapeFromPath(path, d->pen);
8504 }
8505 
8509 bool QGraphicsRectItem::contains(const QPointF &point) const
8510 {
8512 }
8513 
8518  QWidget *widget)
8519 {
8520  Q_D(QGraphicsRectItem);
8521  Q_UNUSED(widget);
8522  painter->setPen(d->pen);
8523  painter->setBrush(d->brush);
8524  painter->drawRect(d->rect);
8525 
8526  if (option->state & QStyle::State_Selected)
8528 }
8529 
8534 {
8536 }
8537 
8542 {
8544 }
8545 
8550 {
8551  return Type;
8552 }
8553 
8558 {
8560  return false;
8561 }
8562 
8567 {
8569  Q_UNUSED(variant);
8570 }
8571 
8576 {
8577  Q_UNUSED(variant);
8578  return QVariant();
8579 }
8580 
8614 {
8615  Q_DECLARE_PUBLIC(QGraphicsEllipseItem)
8616 public:
8618  : startAngle(0), spanAngle(360 * 16)
8619  { }
8620 
8624 };
8625 
8634 {
8635  setRect(rect);
8636 }
8637 
8651 {
8652  setRect(x,y,w,h);
8653 }
8654 
8655 
8656 
8665 {
8666 }
8667 
8672 {
8673 }
8674 
8681 {
8682  Q_D(const QGraphicsEllipseItem);
8683  return d->rect;
8684 }
8685 
8695 {
8696  Q_D(QGraphicsEllipseItem);
8697  if (d->rect == rect)
8698  return;
8700  d->rect = rect;
8701  d->boundingRect = QRectF();
8702  update();
8703 }
8704 
8713 {
8714  Q_D(const QGraphicsEllipseItem);
8715  return d->startAngle;
8716 }
8717 
8726 {
8727  Q_D(QGraphicsEllipseItem);
8728  if (angle != d->startAngle) {
8730  d->boundingRect = QRectF();
8731  d->startAngle = angle;
8732  update();
8733  }
8734 }
8735 
8745 {
8746  Q_D(const QGraphicsEllipseItem);
8747  return d->spanAngle;
8748 }
8749 
8759 {
8760  Q_D(QGraphicsEllipseItem);
8761  if (angle != d->spanAngle) {
8763  d->boundingRect = QRectF();
8764  d->spanAngle = angle;
8765  update();
8766  }
8767 }
8768 
8773 {
8774  Q_D(const QGraphicsEllipseItem);
8775  if (d->boundingRect.isNull()) {
8776  qreal pw = pen().style() == Qt::NoPen ? qreal(0) : pen().widthF();
8777  if (pw == 0.0 && d->spanAngle == 360 * 16)
8778  d->boundingRect = d->rect;
8779  else
8780  d->boundingRect = shape().controlPointRect();
8781  }
8782  return d->boundingRect;
8783 }
8784 
8789 {
8790  Q_D(const QGraphicsEllipseItem);
8792  if (d->rect.isNull())
8793  return path;
8794  if (d->spanAngle != 360 * 16) {
8795  path.moveTo(d->rect.center());
8796  path.arcTo(d->rect, d->startAngle / 16.0, d->spanAngle / 16.0);
8797  } else {
8798  path.addEllipse(d->rect);
8799  }
8800 
8801  return qt_graphicsItem_shapeFromPath(path, d->pen);
8802 }
8803 
8807 bool QGraphicsEllipseItem::contains(const QPointF &point) const
8808 {
8810 }
8811 
8816  QWidget *widget)
8817 {
8818  Q_D(QGraphicsEllipseItem);
8819  Q_UNUSED(widget);
8820  painter->setPen(d->pen);
8821  painter->setBrush(d->brush);
8822  if ((d->spanAngle != 0) && (qAbs(d->spanAngle) % (360 * 16) == 0))
8823  painter->drawEllipse(d->rect);
8824  else
8825  painter->drawPie(d->rect, d->startAngle, d->spanAngle);
8826 
8827  if (option->state & QStyle::State_Selected)
8829 }
8830 
8835 {
8837 }
8838 
8843 {
8845 }
8846 
8851 {
8852  return Type;
8853 }
8854 
8855 
8860 {
8862  return false;
8863 }
8864 
8869 {
8871  Q_UNUSED(variant);
8872 }
8873 
8878 {
8879  Q_UNUSED(variant);
8880  return QVariant();
8881 }
8882 
8909 {
8910  Q_DECLARE_PUBLIC(QGraphicsPolygonItem)
8911 public:
8913  : fillRule(Qt::OddEvenFill)
8914  { }
8915 
8918 };
8919 
8928 {
8930 }
8931 
8940 {
8941 }
8942 
8947 {
8948 }
8949 
8957 {
8958  Q_D(const QGraphicsPolygonItem);
8959  return d->polygon;
8960 }
8961 
8968 {
8969  Q_D(QGraphicsPolygonItem);
8970  if (d->polygon == polygon)
8971  return;
8973  d->polygon = polygon;
8974  d->boundingRect = QRectF();
8975  update();
8976 }
8977 
8985 {
8986  Q_D(const QGraphicsPolygonItem);
8987  return d->fillRule;
8988 }
8989 
8997 {
8998  Q_D(QGraphicsPolygonItem);
8999  if (rule != d->fillRule) {
9000  d->fillRule = rule;
9001  update();
9002  }
9003 }
9004 
9009 {
9010  Q_D(const QGraphicsPolygonItem);
9011  if (d->boundingRect.isNull()) {
9012  qreal pw = pen().style() == Qt::NoPen ? qreal(0) : pen().widthF();
9013  if (pw == 0.0)
9014  d->boundingRect = d->polygon.boundingRect();
9015  else
9016  d->boundingRect = shape().controlPointRect();
9017  }
9018  return d->boundingRect;
9019 }
9020 
9025 {
9026  Q_D(const QGraphicsPolygonItem);
9028  path.addPolygon(d->polygon);
9029  return qt_graphicsItem_shapeFromPath(path, d->pen);
9030 }
9031 
9035 bool QGraphicsPolygonItem::contains(const QPointF &point) const
9036 {
9038 }
9039 
9044 {
9045  Q_D(QGraphicsPolygonItem);
9046  Q_UNUSED(widget);
9047  painter->setPen(d->pen);
9048  painter->setBrush(d->brush);
9049  painter->drawPolygon(d->polygon, d->fillRule);
9050 
9051  if (option->state & QStyle::State_Selected)
9053 }
9054 
9059 {
9061 }
9062 
9067 {
9069 }
9070 
9075 {
9076  return Type;
9077 }
9078 
9083 {
9085  return false;
9086 }
9087 
9092 {
9094  Q_UNUSED(variant);
9095 }
9096 
9101 {
9102  Q_UNUSED(variant);
9103  return QVariant();
9104 }
9105 
9131 {
9132  Q_DECLARE_PUBLIC(QGraphicsLineItem)
9133 public:
9136 };
9137 
9146 {
9147  setLine(line);
9148 }
9149 
9159 {
9160  setLine(x1, y1, x2, y2);
9161 }
9162 
9163 
9164 
9173 {
9174 }
9175 
9180 {
9181 }
9182 
9190 {
9191  Q_D(const QGraphicsLineItem);
9192  return d->pen;
9193 }
9194 
9202 {
9203  Q_D(QGraphicsLineItem);
9204  if (d->pen == pen)
9205  return;
9207  d->pen = pen;
9208  update();
9209 }
9210 
9217 {
9218  Q_D(const QGraphicsLineItem);
9219  return d->line;
9220 }
9221 
9228 {
9229  Q_D(QGraphicsLineItem);
9230  if (d->line == line)
9231  return;
9233  d->line = line;
9234  update();
9235 }
9236 
9251 {
9252  Q_D(const QGraphicsLineItem);
9253  if (d->pen.widthF() == 0.0) {
9254  const qreal x1 = d->line.p1().x();
9255  const qreal x2 = d->line.p2().x();
9256  const qreal y1 = d->line.p1().y();
9257  const qreal y2 = d->line.p2().y();
9258  qreal lx = qMin(x1, x2);
9259  qreal rx = qMax(x1, x2);
9260  qreal ty = qMin(y1, y2);
9261  qreal by = qMax(y1, y2);
9262  return QRectF(lx, ty, rx - lx, by - ty);
9263  }
9264  return shape().controlPointRect();
9265 }
9266 
9271 {
9272  Q_D(const QGraphicsLineItem);
9274  if (d->line == QLineF())
9275  return path;
9276 
9277  path.moveTo(d->line.p1());
9278  path.lineTo(d->line.p2());
9279  return qt_graphicsItem_shapeFromPath(path, d->pen);
9280 }
9281 
9285 bool QGraphicsLineItem::contains(const QPointF &point) const
9286 {
9287  return QGraphicsItem::contains(point);
9288 }
9289 
9294 {
9295  Q_D(QGraphicsLineItem);
9296  Q_UNUSED(widget);
9297  painter->setPen(d->pen);
9298  painter->drawLine(d->line);
9299 
9300  if (option->state & QStyle::State_Selected)
9302 }
9303 
9308 {
9310 }
9311 
9316 {
9317  return QGraphicsItem::opaqueArea();
9318 }
9319 
9324 {
9325  return Type;
9326 }
9327 
9332 {
9334  return false;
9335 }
9336 
9341 {
9343  Q_UNUSED(variant);
9344 }
9345 
9350 {
9351  Q_UNUSED(variant);
9352  return QVariant();
9353 }
9354 
9409 extern QPainterPath qt_regionToPath(const QRegion &region);
9410 
9412 {
9413  Q_DECLARE_PUBLIC(QGraphicsPixmapItem)
9414 public:
9417  shapeMode(QGraphicsPixmapItem::MaskShape),
9418  hasShape(false)
9419  {}
9420 
9426  bool hasShape;
9427 
9429  {
9430  shape = QPainterPath();
9431  switch (shapeMode) {
9433  QBitmap mask = pixmap.mask();
9434  if (!mask.isNull()) {
9435  shape = qt_regionToPath(QRegion(mask).translated(offset.toPoint()));
9436  break;
9437  }
9438  Q_FALLTHROUGH();
9439  }
9442  break;
9444 #ifndef QT_NO_IMAGE_HEURISTIC_MASK
9446 #else
9448 #endif
9449  break;
9450  }
9451  }
9452 };
9453 
9462 {
9463  setPixmap(pixmap);
9464 }
9465 
9474 {
9475 }
9476 
9481 {
9482 }
9483 
9490 {
9491  Q_D(QGraphicsPixmapItem);
9493  d->pixmap = pixmap;
9494  d->hasShape = false;
9495  update();
9496 }
9497 
9505 {
9506  Q_D(const QGraphicsPixmapItem);
9507  return d->pixmap;
9508 }
9509 
9518 {
9519  Q_D(const QGraphicsPixmapItem);
9520  return d->transformationMode;
9521 }
9522 
9535 {
9536  Q_D(QGraphicsPixmapItem);
9537  if (mode != d->transformationMode) {
9538  d->transformationMode = mode;
9539  update();
9540  }
9541 }
9542 
9550 {
9551  Q_D(const QGraphicsPixmapItem);
9552  return d->offset;
9553 }
9554 
9562 {
9563  Q_D(QGraphicsPixmapItem);
9564  if (d->offset == offset)
9565  return;
9567  d->offset = offset;
9568  d->hasShape = false;
9569  update();
9570 }
9571 
9583 {
9584  Q_D(const QGraphicsPixmapItem);
9585  if (d->pixmap.isNull())
9586  return QRectF();
9587  if (d->flags & ItemIsSelectable) {
9588  qreal pw = 1.0;
9589  return QRectF(d->offset, d->pixmap.deviceIndependentSize()).adjusted(-pw/2, -pw/2, pw/2, pw/2);
9590  } else {
9591  return QRectF(d->offset, d->pixmap.deviceIndependentSize());
9592  }
9593 }
9594 
9599 {
9600  Q_D(const QGraphicsPixmapItem);
9601  if (!d->hasShape) {
9603  thatD->updateShape();
9604  thatD->hasShape = true;
9605  }
9606  return d_func()->shape;
9607 }
9608 
9612 bool QGraphicsPixmapItem::contains(const QPointF &point) const
9613 {
9614  return QGraphicsItem::contains(point);
9615 }
9616 
9621  QWidget *widget)
9622 {
9623  Q_D(QGraphicsPixmapItem);
9624  Q_UNUSED(widget);
9625 
9627  (d->transformationMode == Qt::SmoothTransformation));
9628 
9629  painter->drawPixmap(d->offset, d->pixmap);
9630 
9631  if (option->state & QStyle::State_Selected)
9633 }
9634 
9639 {
9641 }
9642 
9647 {
9648  return shape();
9649 }
9650 
9655 {
9656  return Type;
9657 }
9658 
9666 {
9667  return d_func()->shapeMode;
9668 }
9669 
9677 {
9678  Q_D(QGraphicsPixmapItem);
9679  if (d->shapeMode == mode)
9680  return;
9681  d->shapeMode = mode;
9682  d->hasShape = false;
9683 }
9684 
9689 {
9691  return false;
9692 }
9693 
9698 {
9700  Q_UNUSED(variant);
9701 }
9702 
9707 {
9708  Q_UNUSED(variant);
9709  return QVariant();
9710 }
9711 
9750 {
9751 public:
9754  { }
9755 
9758 
9759  inline QPointF controlOffset() const
9760  { return QPointF(0., pageNumber * control->document()->pageSize().height()); }
9761  inline void sendControlEvent(QEvent *e)
9762  { if (control) control->processEvent(e, controlOffset()); }
9763 
9764  void _q_updateBoundingRect(const QSizeF &);
9765  void _q_update(QRectF);
9766  void _q_ensureVisible(QRectF);
9768 
9773 
9775 
9777 };
9778 
9779 
9788  dd(new QGraphicsTextItemPrivate)
9789 {
9790  dd->qq = this;
9791  if (!text.isEmpty())
9792  setPlainText(text);
9793  setAcceptDrops(true);
9794  setAcceptHoverEvents(true);
9796 }
9797 
9806  dd(new QGraphicsTextItemPrivate)
9807 {
9808  dd->qq = this;
9809  setAcceptDrops(true);
9810  setAcceptHoverEvents(true);
9812 }
9813 
9818 {
9819  delete dd;
9820 }
9821 
9828 {
9829 #ifndef QT_NO_TEXTHTMLPARSER
9830  if (dd->control)
9831  return dd->control->toHtml();
9832 #endif
9833  return QString();
9834 }
9835 
9844 {
9845  dd->textControl()->setHtml(text);
9846 }
9847 
9854 {
9855  if (dd->control)
9856  return dd->control->toPlainText();
9857  return QString();
9858 }
9859 
9868 {
9869  dd->textControl()->setPlainText(text);
9870 }
9871 
9878 {
9879  if (!dd->control)
9880  return QFont();
9881  return dd->control->document()->defaultFont();
9882 }
9883 
9890 {
9892 }
9893 
9898 {
9899  QWidgetTextControl *c = dd->textControl();
9900  QPalette pal = c->palette();
9901  QColor old = pal.color(QPalette::Text);
9902  pal.setColor(QPalette::Text, col);
9903  c->setPalette(pal);
9904  if (old != col)
9905  update();
9906 }
9907 
9912 {
9913  return dd->textControl()->palette().color(QPalette::Text);
9914 }
9915 
9920 {
9921  return dd->boundingRect;
9922 }
9923 
9928 {
9929  if (!dd->control)
9930  return QPainterPath();
9932  path.addRect(dd->boundingRect);
9933  return path;
9934 }
9935 
9939 bool QGraphicsTextItem::contains(const QPointF &point) const
9940 {
9941  return dd->boundingRect.contains(point);
9942 }
9943 
9948  QWidget *widget)
9949 {
9950  Q_UNUSED(widget);
9951  if (dd->control) {
9952  painter->save();
9953  QRectF r = option->exposedRect;
9954  painter->translate(-dd->controlOffset());
9955  r.translate(dd->controlOffset());
9956 
9957  QTextDocument *doc = dd->control->document();
9958  QTextDocumentLayout *layout = qobject_cast<QTextDocumentLayout *>(doc->documentLayout());
9959 
9960  // the layout might need to expand the root frame to
9961  // the viewport if NoWrap is set
9962  if (layout)
9963  layout->setViewport(dd->boundingRect);
9964 
9965  dd->control->drawContents(painter, r);
9966 
9967  if (layout)
9968  layout->setViewport(QRect());
9969 
9970  painter->restore();
9971  }
9972 
9975 }
9976 
9981 {
9983 }
9984 
9989 {
9990  return QGraphicsItem::opaqueArea();
9991 }
9992 
9997 {
9998  return Type;
9999 }
10000 
10018 {
10019  dd->textControl()->setTextWidth(width);
10020 }
10021 
10031 {
10032  if (!dd->control)
10033  return -1;
10034  return dd->control->textWidth();
10035 }
10036 
10041 {
10042  if (dd->control)
10043  dd->control->adjustSize();
10044 }
10045 
10050 {
10052  dd->_q_updateBoundingRect(dd->control->size());
10053 }
10054 
10059 {
10060  return dd->textControl()->document();
10061 }
10062 
10067 {
10068  QEvent::Type t = event->type();
10069  if (!dd->tabChangesFocus && (t == QEvent::KeyPress || t == QEvent::KeyRelease)) {
10070  int k = ((QKeyEvent *)event)->key();
10071  if (k == Qt::Key_Tab || k == Qt::Key_Backtab) {
10072  dd->sendControlEvent(event);
10073  return true;
10074  }
10075  }
10077 
10078  // Ensure input context is updated.
10079  switch (event->type()) {
10080  case QEvent::ContextMenu:
10081  case QEvent::FocusIn:
10082  case QEvent::FocusOut:
10094  case QEvent::KeyPress:
10095  case QEvent::KeyRelease:
10096  case QEvent::InputMethod:
10097  // Reset the focus widget's input context, regardless
10098  // of how this item gained or lost focus.
10099  if (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut) {
10101  } else {
10103  }
10104  break;
10106  dd->sendControlEvent(event);
10107  return true;
10108  default:
10109  break;
10110  }
10111 
10112  return result;
10113 }
10114 
10119 {
10121  && (event->buttons() & Qt::LeftButton) && dd->_q_mouseOnEdge(event)) {
10122  // User left-pressed on edge of selectable/movable item, use
10123  // base impl.
10124  dd->useDefaultImpl = true;
10125  } else if (event->buttons() == event->button()
10127  // User pressed first button on non-interactive item.
10128  dd->useDefaultImpl = true;
10129  }
10130  if (dd->useDefaultImpl) {
10132  if (!event->isAccepted())
10133  dd->useDefaultImpl = false;
10134  return;
10135  }
10136 
10137  dd->sendControlEvent(event);
10138 }
10139 
10144 {
10145  if (dd->useDefaultImpl) {
10147  return;
10148  }
10149 
10150  dd->sendControlEvent(event);
10151 }
10152 
10157 {
10158  if (dd->useDefaultImpl) {
10161  && !event->buttons()) {
10162  // User released last button on non-interactive item.
10163  dd->useDefaultImpl = false;
10164  } else if ((event->buttons() & Qt::LeftButton) == 0) {
10165  // User released the left button on an interactive item.
10166  dd->useDefaultImpl = false;
10167  }
10168  return;
10169  }
10170 
10171  QWidget *widget = event->widget();
10174  }
10175  dd->clickCausedFocus = 0;
10176  dd->sendControlEvent(event);
10177 }
10178 
10183 {
10184  if (dd->useDefaultImpl) {
10186  return;
10187  }
10188 
10189  if (!hasFocus()) {
10191  return;
10192  }
10193 
10194  dd->sendControlEvent(event);
10195 }
10196 
10201 {
10202  dd->sendControlEvent(event);
10203 }
10204 
10209 {
10210  dd->sendControlEvent(event);
10211 }
10212 
10217 {
10218  dd->sendControlEvent(event);
10219 }
10220 
10225 {
10226  dd->sendControlEvent(event);
10227  if (event->reason() == Qt::MouseFocusReason) {
10228  dd->clickCausedFocus = 1;
10229  }
10230  update();
10231 }
10232 
10237 {
10238  dd->sendControlEvent(event);
10239  update();
10240 }
10241 
10246 {
10247  dd->sendControlEvent(event);
10248 }
10249 
10254 {
10255  dd->sendControlEvent(event);
10256 }
10257 
10262 {
10263  dd->sendControlEvent(event);
10264 }
10265 
10270 {
10271  dd->sendControlEvent(event);
10272 }
10273 
10278 {
10279  dd->sendControlEvent(event);
10280 }
10281 
10286 {
10287  dd->sendControlEvent(event);
10288 }
10289 
10294 {
10295  dd->sendControlEvent(event);
10296 }
10297 
10302 {
10303  dd->sendControlEvent(event);
10304 }
10305 
10310 {
10311  QVariant v;
10312  if (query == Qt::ImHints)
10313  v = int(inputMethodHints());
10314  else if (dd->control)
10316  if (dd->control) {
10317  if (v.userType() == QMetaType::QRectF)
10318  v = v.toRectF().translated(-dd->controlOffset());
10319  else if (v.userType() == QMetaType::QPointF)
10320  v = v.toPointF() - dd->controlOffset();
10321  else if (v.userType() == QMetaType::QRect)
10322  v = v.toRect().translated(-dd->controlOffset().toPoint());
10323  else if (v.userType() == QMetaType::QPoint)
10324  v = v.toPoint() - dd->controlOffset().toPoint();
10325  }
10326  return v;
10327 }
10328 
10333 {
10335  return false;
10336 }
10337 
10342 {
10344  Q_UNUSED(variant);
10345 }
10346 
10351 {
10352  Q_UNUSED(variant);
10353  return QVariant();
10354 }
10355 
10360 {
10361  if (rect.isValid()) {
10362  rect.translate(-controlOffset());
10363  } else {
10364  rect = boundingRect;
10365  }
10366  if (rect.intersects(boundingRect))
10367  qq->update(rect);
10368 }
10369 
10374 {
10375  if (size != boundingRect.size()) {
10378  qq->update();
10379  }
10380 }
10381 
10386 {
10387  if (qq->hasFocus()) {
10388  rect.translate(-controlOffset());
10389  qq->ensureVisible(rect, /*xmargin=*/0, /*ymargin=*/0);
10390  }
10391 }
10392 
10394 {
10395  if (!control) {
10396  QGraphicsTextItem *that = const_cast<QGraphicsTextItem *>(qq);
10397  control = new QWidgetTextControl(that);
10399 
10401  [dd = that->dd](const QRectF &rect) { dd->_q_update(rect); });
10403  [dd = that->dd](QSizeF size) { dd->_q_updateBoundingRect(size); });
10405  [dd = that->dd](const QRectF &rect) { dd->_q_ensureVisible(rect); });
10410 
10411  const QSizeF pgSize = control->document()->pageSize();
10412  if (pgSize.height() != -1) {
10414  that->dd->boundingRect.setSize(pgSize);
10415  qq->update();
10416  } else {
10417  that->dd->_q_updateBoundingRect(control->size());
10418  }
10419  }
10420  return control;
10421 }
10422 
10427 {
10429  path.addRect(qq->boundingRect());
10430 
10431  QPainterPath docPath;
10433  docPath.addRect(
10435  format.leftMargin(),
10436  format.topMargin(),
10437  -format.rightMargin(),
10438  -format.bottomMargin()));
10439 
10440  return path.subtracted(docPath).contains(event->pos());
10441 }
10442 
10475 {
10478  else
10480 
10482 }
10483 
10489 Qt::TextInteractionFlags QGraphicsTextItem::textInteractionFlags() const
10490 {
10491  if (!dd->control)
10492  return Qt::NoTextInteraction;
10493  return dd->control->textInteractionFlags();
10494 }
10495 
10509 {
10510  dd->tabChangesFocus = b;
10511 }
10512 
10524 {
10525  return dd->tabChangesFocus;
10526 }
10527 
10538 {
10540 }
10541 
10543 {
10544  if (!dd->control)
10545  return false;
10546  return dd->control->openExternalLinks();
10547 }
10548 
10560 {
10562 }
10563 
10565 {
10566  if (!dd->control)
10567  return QTextCursor();
10568  return dd->control->textCursor();
10569 }
10570 
10572 {
10573  Q_DECLARE_PUBLIC(QGraphicsSimpleTextItem)
10574 public:
10577  brush.setStyle(Qt::SolidPattern);
10578  }
10582 
10583  void updateBoundingRect();
10584 };
10585 
10586 static QRectF setupTextLayout(QTextLayout *layout)
10587 {
10588  layout->setCacheEnabled(true);
10589  layout->beginLayout();
10590  while (layout->createLine().isValid())
10591  ;
10592  layout->endLayout();
10593  qreal maxWidth = 0;
10594  qreal y = 0;
10595  for (int i = 0; i < layout->lineCount(); ++i) {
10596  QTextLine line = layout->lineAt(i);
10597  maxWidth = qMax(maxWidth, line.naturalTextWidth());
10598  line.setPosition(QPointF(0, y));
10599  y += line.height();
10600  }
10601  return QRectF(0, 0, maxWidth, y);
10602 }
10603 
10605 {
10607  QRectF br;
10608  if (text.isEmpty()) {
10609  br = QRectF();
10610  } else {
10611  QString tmp = text;
10613  QStackTextEngine engine(tmp, font);
10614  QTextLayout layout(&engine);
10615  br = setupTextLayout(&layout);
10616  }
10617  if (br != boundingRect) {
10618  q->prepareGeometryChange();
10619  boundingRect = br;
10620  q->update();
10621  }
10622 }
10623 
10666 {
10667 }
10668 
10678 {
10679  setText(text);
10680 }
10681 
10686 {
10687 }
10688 
10696 {
10698  if (d->text == text)
10699  return;
10700  d->text = text;
10701  d->updateBoundingRect();
10702  update();
10703 }
10704 
10709 {
10710  Q_D(const QGraphicsSimpleTextItem);
10711  return d->text;
10712 }
10713 
10718 {
10720  d->font = font;
10721  d->updateBoundingRect();
10722 }
10723 
10728 {
10729  Q_D(const QGraphicsSimpleTextItem);
10730  return d->font;
10731 }
10732 
10737 {
10738  Q_D(const QGraphicsSimpleTextItem);
10739  return d->boundingRect;
10740 }
10741 
10746 {
10747  Q_D(const QGraphicsSimpleTextItem);
10749  path.addRect(d->boundingRect);
10750  return path;
10751 }
10752 
10757 {
10758  Q_D(const QGraphicsSimpleTextItem);
10759  return d->boundingRect.contains(point);
10760 }
10761 
10766 {
10767  Q_UNUSED(widget);
10769 
10770  painter->setFont(d->font);
10771 
10772  QString tmp = d->text;
10774  QStackTextEngine engine(tmp, d->font);
10775  QTextLayout layout(&engine);
10776 
10777  QPen p;
10778  p.setBrush(d->brush);
10779  painter->setPen(p);
10780  if (d->pen.style() == Qt::NoPen && d->brush.style() == Qt::SolidPattern) {
10782  } else {
10784  range.start = 0;
10785  range.length = layout.text().length();
10786  range.format.setTextOutline(d->pen);
10788  }
10789 
10790  setupTextLayout(&layout);
10791  layout.draw(painter, QPointF(0, 0));
10792 
10795 }
10796 
10801 {
10803 }
10804 
10809 {
10811 }
10812 
10817 {
10818  return Type;
10819 }
10820 
10825 {
10827  return false;
10828 }
10829 
10834 {
10836  Q_UNUSED(variant);
10837 }
10838 
10843 {
10844  Q_UNUSED(variant);
10845  return QVariant();
10846 }
10847 
10908 {
10909 public:
10911 };
10912 
10921 {
10922  setHandlesChildEvents(true);
10923 }
10924 
10929 {
10930 }
10931 
10940 {
10941  Q_D(QGraphicsItemGroup);
10942  if (!item) {
10943  qWarning("QGraphicsItemGroup::addToGroup: cannot add null item");
10944  return;
10945  }
10946  if (item == this) {
10947  qWarning("QGraphicsItemGroup::addToGroup: cannot add a group to itself");
10948  return;
10949  }
10950 
10951  // COMBINE
10952  bool ok;
10954 
10955  if (!ok) {
10956  qWarning("QGraphicsItemGroup::addToGroup: could not find a valid transformation from item to group coordinates");
10957  return;
10958  }
10959 
10960  QTransform newItemTransform(itemTransform);
10961  item->setPos(mapFromItem(item, 0, 0));
10962  item->setParentItem(this);
10963 
10964  // removing position from translation component of the new transform
10965  if (!item->pos().isNull())
10966  newItemTransform *= QTransform::fromTranslate(-item->x(), -item->y());
10967 
10968  // removing additional transformations properties applied with itemTransform()
10969  QPointF origin = item->transformOriginPoint();
10970  QMatrix4x4 m;
10971  QList<QGraphicsTransform*> transformList = item->transformations();
10972  for (int i = 0; i < transformList.size(); ++i)
10973  transformList.at(i)->applyTo(&m);
10974  newItemTransform *= m.toTransform().inverted();
10975  newItemTransform.translate(origin.x(), origin.y());
10976  newItemTransform.rotate(-item->rotation());
10977  newItemTransform.scale(1/item->scale(), 1/item->scale());
10978  newItemTransform.translate(-origin.x(), -origin.y());
10979 
10980  // ### Expensive, we could maybe use dirtySceneTransform bit for optimization
10981 
10982  item->setTransform(newItemTransform);
10983  item->d_func()->setIsMemberOfGroup(true);
10985  d->itemsBoundingRect |= itemTransform.mapRect(item->boundingRect() | item->childrenBoundingRect());
10986  update();
10987 }
10988 
10998 {
10999  Q_D(QGraphicsItemGroup);
11000  if (!item) {
11001  qWarning("QGraphicsItemGroup::removeFromGroup: cannot remove null item");
11002  return;
11003  }
11004 
11005  QGraphicsItem *newParent = d_ptr->parent;
11006 
11007  // COMBINE
11008  bool ok;
11010  if (newParent)
11011  itemTransform = item->itemTransform(newParent, &ok);
11012  else
11014 
11015  QPointF oldPos = item->mapToItem(newParent, 0, 0);
11016  item->setParentItem(newParent);
11017  item->setPos(oldPos);
11018 
11019  // removing position from translation component of the new transform
11020  if (!item->pos().isNull())
11022 
11023  // removing additional transformations properties applied
11024  // with itemTransform() or sceneTransform()
11025  QPointF origin = item->transformOriginPoint();
11026  QMatrix4x4 m;
11027  QList<QGraphicsTransform*> transformList = item->transformations();
11028  for (int i = 0; i < transformList.size(); ++i)
11029  transformList.at(i)->applyTo(&m);
11030  itemTransform *= m.toTransform().inverted();
11031  itemTransform.translate(origin.x(), origin.y());
11033  itemTransform.scale(1 / item->scale(), 1 / item->scale());
11034  itemTransform.translate(-origin.x(), -origin.y());
11035 
11036  // ### Expensive, we could maybe use dirtySceneTransform bit for optimization
11037 
11039  item->d_func()->setIsMemberOfGroup(item->group() != nullptr);
11040 
11041  // ### Quite expensive. But removeFromGroup() isn't called very often.
11043  d->itemsBoundingRect = childrenBoundingRect();
11044 }
11045 
11052 {
11053  Q_D(const QGraphicsItemGroup);
11054  return d->itemsBoundingRect;
11055 }
11056 
11061  QWidget *widget)
11062 {
11063  Q_UNUSED(widget);
11064  if (option->state & QStyle::State_Selected) {
11065  Q_D(QGraphicsItemGroup);
11067  painter->drawRect(d->itemsBoundingRect);
11068  }
11069 }
11070 
11075 {
11077 }
11078 
11083 {
11084  return QGraphicsItem::opaqueArea();
11085 }
11086 
11091 {
11092  return Type;
11093 }
11094 
11095 #if QT_CONFIG(graphicseffect)
11096 QRectF QGraphicsItemEffectSourcePrivate::boundingRect(Qt::CoordinateSystem system) const
11097 {
11098  const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
11099  if (!info && deviceCoordinates) {
11100  // Device coordinates without info not yet supported.
11101  qWarning("QGraphicsEffectSource::boundingRect: Not yet implemented, lacking device context");
11102  return QRectF();
11103  }
11104 
11106  if (!item->d_ptr->children.isEmpty())
11108 
11109  if (deviceCoordinates) {
11110  Q_ASSERT(info->painter);
11111  rect = info->painter->worldTransform().mapRect(rect);
11112  }
11113 
11114  return rect;
11115 }
11116 
11118 {
11119  if (!info) {
11120  qWarning("QGraphicsEffectSource::draw: Can only begin as a result of QGraphicsEffect::draw");
11121  return;
11122  }
11123 
11124  Q_ASSERT(item->d_ptr->scene);
11125  QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func();
11126  if (painter == info->painter) {
11127  scened->draw(item, painter, info->viewTransform, info->transformPtr, info->exposedRegion,
11128  info->widget, info->opacity, info->effectTransform, info->wasDirtySceneTransform,
11129  info->drawItem);
11130  } else {
11131  QTransform effectTransform = info->painter->worldTransform().inverted();
11132  effectTransform *= painter->worldTransform();
11133  scened->draw(item, painter, info->viewTransform, info->transformPtr, info->exposedRegion,
11134  info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform,
11135  info->drawItem);
11136  }
11137 }
11138 
11139 // sourceRect must be in the given coordinate system
11140 QRectF QGraphicsItemEffectSourcePrivate::paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded) const
11141 {
11142  QRectF effectRectF;
11143 
11144  if (unpadded)
11145  *unpadded = false;
11146 
11148  if (info) {
11149  QRectF deviceRect = system == Qt::DeviceCoordinates ? sourceRect : info->painter->worldTransform().mapRect(sourceRect);
11150  effectRectF = item->graphicsEffect()->boundingRectFor(deviceRect);
11151  if (unpadded)
11152  *unpadded = (effectRectF.size() == sourceRect.size());
11153  if (info && system == Qt::LogicalCoordinates)
11154  effectRectF = info->painter->worldTransform().inverted().mapRect(effectRectF);
11155  } else {
11156  // no choice but to send a logical coordinate bounding rect to boundingRectFor
11157  effectRectF = item->graphicsEffect()->boundingRectFor(sourceRect);
11158  }
11160  // adjust by 1.5 to account for cosmetic pens
11161  effectRectF = sourceRect.adjusted(-1.5, -1.5, 1.5, 1.5);
11162  } else {
11163  effectRectF = sourceRect;
11164  if (unpadded)
11165  *unpadded = true;
11166  }
11167 
11168  return effectRectF;
11169 }
11170 
11173 {
11174  const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
11175  if (!info && deviceCoordinates) {
11176  // Device coordinates without info not yet supported.
11177  qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
11178  return QPixmap();
11179  }
11180  if (!item->d_ptr->scene)
11181  return QPixmap();
11182  QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func();
11183 
11184  bool unpadded;
11185  const QRectF sourceRect = boundingRect(system);
11186  QRectF effectRectF = paddedEffectRect(system, mode, sourceRect, &unpadded);
11187  QRect effectRect = effectRectF.toAlignedRect();
11188 
11189  if (offset)
11190  *offset = effectRect.topLeft();
11191 
11192  bool untransformed = !deviceCoordinates
11193  || info->painter->worldTransform().type() <= QTransform::TxTranslate;
11194  if (untransformed && unpadded && isPixmap()) {
11195  if (offset)
11196  *offset = boundingRect(system).topLeft().toPoint();
11197  return static_cast<QGraphicsPixmapItem *>(item)->pixmap();
11198  }
11199 
11200  if (effectRect.isEmpty())
11201  return QPixmap();
11202 
11203  const auto dpr = info ? info->painter->device()->devicePixelRatio() : 1.0;
11204  QPixmap pixmap(QRectF(effectRectF.topLeft(), effectRectF.size() * dpr).toAlignedRect().size());
11205  pixmap.setDevicePixelRatio(dpr);
11206  pixmap.fill(Qt::transparent);
11207  QPainter pixmapPainter(&pixmap);
11208  pixmapPainter.setRenderHints(info ? info->painter->renderHints() : QPainter::TextAntialiasing);
11209 
11210  QTransform effectTransform = QTransform::fromTranslate(-effectRect.x(), -effectRect.y());
11211  if (deviceCoordinates && info->effectTransform)
11212  effectTransform *= *info->effectTransform;
11213 
11214  if (!info) {
11215  // Logical coordinates without info.
11217  QTransform newEffectTransform = sceneTransform.inverted();
11218  newEffectTransform *= effectTransform;
11219  scened->draw(item, &pixmapPainter, nullptr, &sceneTransform, nullptr, nullptr, qreal(1.0),
11220  &newEffectTransform, false, true);
11221  } else if (deviceCoordinates) {
11222  // Device coordinates with info.
11223  scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, nullptr,
11224  info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform,
11225  info->drawItem);
11226  } else {
11227  // Item coordinates with info.
11228  QTransform newEffectTransform = info->transformPtr->inverted();
11229  newEffectTransform *= effectTransform;
11230  scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, nullptr,
11231  info->widget, info->opacity, &newEffectTransform, info->wasDirtySceneTransform,
11232  info->drawItem);
11233  }
11234 
11235  pixmapPainter.end();
11236 
11237  return pixmap;
11238 }
11239 #endif // QT_CONFIG(graphicseffect)
11240 
11241 #ifndef QT_NO_DEBUG_STREAM
11242 static void formatGraphicsItemHelper(QDebug debug, const QGraphicsItem *item)
11243 {
11244  if (const QGraphicsItem *parent = item->parentItem())
11245  debug << ", parent=" << static_cast<const void *>(parent);
11246  debug << ", pos=";
11247  QtDebugUtils::formatQPoint(debug, item->pos());
11248  if (const qreal z = item->zValue())
11249  debug << ", z=" << z;
11250  if (item->flags())
11251  debug << ", flags=" << item->flags();
11252 }
11253 
11255 {
11256  QDebugStateSaver saver(debug);
11257  debug.nospace();
11258 
11259  if (!item) {
11260  debug << "QGraphicsItem(0)";
11261  return debug;
11262  }
11263 
11264  if (const QGraphicsObject *o = item->toGraphicsObject())
11265  debug << o->metaObject()->className();
11266  else
11267  debug << "QGraphicsItem";
11268  debug << '(' << static_cast<const void *>(item);
11269  if (const QGraphicsProxyWidget *pw = qgraphicsitem_cast<const QGraphicsProxyWidget *>(item)) {
11270  debug << ", widget=";
11271  if (const QWidget *w = pw->widget()) {
11272  debug << w->metaObject()->className() << '(' << static_cast<const void *>(w);
11273  if (!w->objectName().isEmpty())
11274  debug << ", name=" << w->objectName();
11275  debug << ')';
11276  } else {
11277  debug << "QWidget(0)";
11278  }
11279  }
11280  formatGraphicsItemHelper(debug, item);
11281  debug << ')';
11282  return debug;
11283 }
11284 
11286 {
11287  QDebugStateSaver saver(debug);
11288  debug.nospace();
11289 
11290  if (!item) {
11291  debug << "QGraphicsObject(0)";
11292  return debug;
11293  }
11294 
11295  debug << item->metaObject()->className() << '(' << static_cast<const void *>(item);
11296  if (!item->objectName().isEmpty())
11297  debug << ", name=" << item->objectName();
11298  formatGraphicsItemHelper(debug, item);
11299  debug << ')';
11300  return debug;
11301 }
11302 
11304 {
11305  const char *str = "UnknownChange";
11306  switch (change) {
11308  str = "ItemChildAddedChange";
11309  break;
11311  str = "ItemChildRemovedChange";
11312  break;
11314  str = "ItemCursorChange";
11315  break;
11317  str = "ItemCursorHasChanged";
11318  break;
11320  str = "ItemEnabledChange";
11321  break;
11323  str = "ItemEnabledHasChanged";
11324  break;
11326  str = "ItemFlagsChange";
11327  break;
11329  str = "ItemFlagsHaveChanged";
11330  break;
11332  str = "ItemParentChange";
11333  break;
11335  str = "ItemParentHasChanged";
11336  break;
11338  str = "ItemPositionChange";
11339  break;
11341  str = "ItemPositionHasChanged";
11342  break;
11344  str = "ItemSceneChange";
11345  break;
11347  str = "ItemSceneHasChanged";
11348  break;
11350  str = "ItemSelectedChange";
11351  break;
11353  str = "ItemSelectedHasChanged";
11354  break;
11356  str = "ItemToolTipChange";
11357  break;
11359  str = "ItemToolTipHasChanged";
11360  break;
11362  str = "ItemTransformChange";
11363  break;
11365  str = "ItemTransformHasChanged";
11366  break;
11368  str = "ItemVisibleChange";
11369  break;
11371  str = "ItemVisibleHasChanged";
11372  break;
11374  str = "ItemZValueChange";
11375  break;
11377  str = "ItemZValueHasChanged";
11378  break;
11380  str = "ItemOpacityChange";
11381  break;
11383  str = "ItemOpacityHasChanged";
11384  break;
11386  str = "ItemScenePositionHasChanged";
11387  break;
11389  str = "ItemRotationChange";
11390  break;
11392  str = "ItemRotationHasChanged";
11393  break;
11395  str = "ItemScaleChange";
11396  break;
11398  str = "ItemScaleHasChanged";
11399  break;
11401  str = "ItemTransformOriginPointChange";
11402  break;
11404  str = "ItemTransformOriginPointHasChanged";
11405  break;
11406  }
11407  debug << str;
11408  return debug;
11409 }
11410 
11412 {
11413  const char *str = "UnknownFlag";
11414  switch (flag) {
11416  str = "ItemIsMovable";
11417  break;
11419  str = "ItemIsSelectable";
11420  break;
11422  str = "ItemIsFocusable";
11423  break;
11425  str = "ItemClipsToShape";
11426  break;
11428  str = "ItemClipsChildrenToShape";
11429  break;
11431  str = "ItemIgnoresTransformations";
11432  break;
11434  str = "ItemIgnoresParentOpacity";
11435  break;
11437  str = "ItemDoesntPropagateOpacityToChildren";
11438  break;
11440  str = "ItemStacksBehindParent";
11441  break;
11443  str = "ItemUsesExtendedStyleOption";
11444  break;
11446  str = "ItemHasNoContents";
11447  break;
11449  str = "ItemSendsGeometryChanges";
11450  break;
11452  str = "ItemAcceptsInputMethod";
11453  break;
11455  str = "ItemNegativeZStacksBehindParent";
11456  break;
11458  str = "ItemIsPanel";
11459  break;
11461  str = "ItemIsFocusScope";
11462  break;
11464  str = "ItemSendsScenePositionChanges";
11465  break;
11467  str = "ItemStopsClickFocusPropagation";
11468  break;
11470  str = "ItemStopsFocusHandling";
11471  break;
11473  str = "ItemContainsChildrenInShape";
11474  break;
11475  }
11476  debug << str;
11477  return debug;
11478 }
11479 
11480 QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlags flags)
11481 {
11482  debug << '(';
11483  bool f = false;
11484  for (int i = 0; i < 17; ++i) {
11485  if (flags & (1 << i)) {
11486  if (f)
11487  debug << '|';
11488  f = true;
11489  debug << QGraphicsItem::GraphicsItemFlag(int(flags & (1 << i)));
11490  }
11491  }
11492  debug << ')';
11493  return debug;
11494 }
11495 
11496 #endif
11497 
11499 
11500 #include "moc_qgraphicsitem.cpp"
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
#define value
[5]
static void(* destroyed)(QAbstractDeclarativeData *, QObject *)
Definition: qobject_p.h:91
The QAbstractGraphicsShapeItem class provides a common base for all path items.
void setPen(const QPen &pen)
bool isObscuredBy(const QGraphicsItem *item) const override
void setBrush(const QBrush &brush)
QPainterPath opaqueArea() const override
QAbstractGraphicsShapeItem(QGraphicsItem *parent=nullptr)
static QWidget * focusWidget()
The QBitmap class provides monochrome (1-bit depth) pixmaps.
Definition: qbitmap.h:52
static QBitmap fromImage(const QImage &image, Qt::ImageConversionFlags flags=Qt::AutoColor)
Definition: qbitmap.cpp:206
The QBrush class defines the fill pattern of shapes drawn by QPainter.
Definition: qbrush.h:66
@ LineSeparator
Definition: qchar.h:100
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
int red() const noexcept
Definition: qcolor.cpp:1525
int blue() const noexcept
Definition: qcolor.cpp:1580
int green() const noexcept
Definition: qcolor.cpp:1552
The QCursor class provides a mouse cursor with an arbitrary shape.
Definition: qcursor.h:81
static QPoint pos()
Definition: qcursor.cpp:224
operator<<(QDataStream &ds, qfloat16 f)
Definition: qfloat16.cpp:327
The QDebug class provides an output stream for debugging information.
Definition: qdebug.h:65
Convenience class for custom QDebug operators.
Definition: qdebug.h:176
The QEvent class is the base class of all event classes. Event objects contain event parameters.
Definition: qcoreevent.h:58
@ GraphicsSceneDragLeave
Definition: qcoreevent.h:213
@ GraphicsSceneMouseMove
Definition: qcoreevent.h:202
@ GraphicsSceneContextMenu
Definition: qcoreevent.h:206
@ GraphicsSceneMouseRelease
Definition: qcoreevent.h:204
@ GraphicsSceneDragEnter
Definition: qcoreevent.h:211
@ GraphicsSceneDragMove
Definition: qcoreevent.h:212
@ ShortcutOverride
Definition: qcoreevent.h:171
@ FocusOut
Definition: qcoreevent.h:80
@ InputMethod
Definition: qcoreevent.h:133
@ GraphicsSceneMousePress
Definition: qcoreevent.h:203
@ DragEnter
Definition: qcoreevent.h:114
@ KeyRelease
Definition: qcoreevent.h:78
@ KeyPress
Definition: qcoreevent.h:77
@ StyleAnimationUpdate
Definition: qcoreevent.h:285
@ FocusIn
Definition: qcoreevent.h:79
@ HoverLeave
Definition: qcoreevent.h:189
@ HoverEnter
Definition: qcoreevent.h:188
@ GraphicsSceneHoverLeave
Definition: qcoreevent.h:209
@ WindowActivate
Definition: qcoreevent.h:96
@ GraphicsSceneMouseDoubleClick
Definition: qcoreevent.h:205
@ GraphicsSceneWheel
Definition: qcoreevent.h:215
@ DragLeave
Definition: qcoreevent.h:116
@ GraphicsSceneDrop
Definition: qcoreevent.h:214
@ GraphicsSceneHoverEnter
Definition: qcoreevent.h:207
@ GraphicsSceneHoverMove
Definition: qcoreevent.h:208
@ WindowDeactivate
Definition: qcoreevent.h:97
@ ContextMenu
Definition: qcoreevent.h:132
Type type() const
Definition: qcoreevent.h:307
void accept()
Definition: qcoreevent.h:313
The QFocusEvent class contains event parameters for widget focus events. \inmodule QtGui.
Definition: qevent.h:520
The QFont class specifies a query for a font used for drawing text.
Definition: qfont.h:56
static QGestureManager * instance(InstanceCreation ic=ForceCreation)
The QGraphicsEffect class is the base class for all graphics effects.
QGraphicsEffectSource * source() const
bool isEnabled() const
virtual QRectF boundingRectFor(const QRectF &sourceRect) const
The QGraphicsEllipseItem class provides an ellipse item that you can add to a QGraphicsScene.
QRectF boundingRect() const override
QGraphicsEllipseItem(QGraphicsItem *parent=nullptr)
QPainterPath opaqueArea() const override
void setExtension(Extension extension, const QVariant &variant) override
QVariant extension(const QVariant &variant) const override
bool supportsExtension(Extension extension) const override
bool contains(const QPointF &point) const override
void setStartAngle(int angle)
void setSpanAngle(int angle)
bool isObscuredBy(const QGraphicsItem *item) const override
void setRect(const QRectF &rect)
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget=nullptr) override
QPainterPath shape() const override
int type() const override
QList< QRectF > exposed
QHash< QPaintDevice *, DeviceData > deviceData
QHash< const QGraphicsItem *, QMap< int, QVariant > > data
The QGraphicsItemGroup class provides a container that treats a group of items as a single item.
bool isObscuredBy(const QGraphicsItem *item) const override
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget=nullptr) override
QPainterPath opaqueArea() const override
QRectF boundingRect() const override
int type() const override
void addToGroup(QGraphicsItem *item)
void removeFromGroup(QGraphicsItem *item)
The QGraphicsItem class is the base class for all graphical items in a QGraphicsScene.
Definition: qgraphicsitem.h:83
virtual bool contains(const QPointF &point) const
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
virtual QVariant extension(const QVariant &variant) const
QRectF mapRectToItem(const QGraphicsItem *item, const QRectF &rect) const
QTransform deviceTransform(const QTransform &viewportTransform) const
QTransform itemTransform(const QGraphicsItem *other, bool *ok=nullptr) const
QPointF scenePos() const
bool isWidget() const
@ ItemTransformOriginPointChange
@ ItemTransformOriginPointHasChanged
@ ItemScenePositionHasChanged
virtual void wheelEvent(QGraphicsSceneWheelEvent *event)
void setSelected(bool selected)
bool acceptDrops() const
QGraphicsWidget * topLevelWidget() const
void setData(int key, const QVariant &value)
QPointF mapToItem(const QGraphicsItem *item, const QPointF &point) const
QScopedPointer< QGraphicsItemPrivate > d_ptr
qreal rotation() const
void setX(qreal x)
void ensureVisible(const QRectF &rect=QRectF(), int xmargin=50, int ymargin=50)
virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event)
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
void setScale(qreal scale)
void update(const QRectF &rect=QRectF())
virtual void dragEnterEvent(QGraphicsSceneDragDropEvent *event)
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event)
void setTransformOriginPoint(const QPointF &origin)
QPainterPath clipPath() const
bool isObscured(const QRectF &rect=QRectF()) const
bool handlesChildEvents() const
QGraphicsWidget * parentWidget() const
void setTransform(const QTransform &matrix, bool combine=false)
void setRotation(qreal angle)
virtual void dropEvent(QGraphicsSceneDragDropEvent *event)
void setOpacity(qreal opacity)
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value)
qreal boundingRegionGranularity() const
friend class QGraphicsObject
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget=nullptr)=0
void setPanelModality(PanelModality panelModality)
bool isWindow() const
QGraphicsScene * scene() const
bool isSelected() const
void setAcceptHoverEvents(bool enabled)
virtual void setExtension(Extension extension, const QVariant &variant)
void setGroup(QGraphicsItemGroup *group)
qreal scale() const
QPointF pos() const
QList< QGraphicsItem * > childItems() const
void installSceneEventFilter(QGraphicsItem *filterItem)
qreal y() const
CacheMode cacheMode() const
virtual bool collidesWithItem(const QGraphicsItem *other, Qt::ItemSelectionMode mode=Qt::IntersectsItemShape) const
virtual QPainterPath shape() const
@ ItemDoesntPropagateOpacityToChildren
Definition: qgraphicsitem.h:93
@ ItemIgnoresTransformations
Definition: qgraphicsitem.h:91
@ ItemClipsChildrenToShape
Definition: qgraphicsitem.h:90
@ ItemContainsChildrenInShape
@ ItemNegativeZStacksBehindParent
Definition: qgraphicsitem.h:99
@ ItemSendsScenePositionChanges
@ ItemIgnoresParentOpacity
Definition: qgraphicsitem.h:92
@ ItemStopsClickFocusPropagation
@ ItemUsesExtendedStyleOption
Definition: qgraphicsitem.h:95
@ ItemSendsGeometryChanges
Definition: qgraphicsitem.h:97
void setFiltersChildEvents(bool enabled)
void setZValue(qreal z)
virtual void focusInEvent(QFocusEvent *event)
void stackBefore(const QGraphicsItem *sibling)
virtual void dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
QGraphicsWidget * window() const
QRectF sceneBoundingRect() const
virtual QRectF boundingRect() const =0
QCursor cursor() const
QPointF mapFromItem(const QGraphicsItem *item, const QPointF &point) const
void setPos(const QPointF &pos)
bool isEnabled() const
bool isBlockedByModalPanel(QGraphicsItem **blockingPanel=nullptr) const
friend class QGraphicsItemEffectSourcePrivate
bool acceptHoverEvents() const
QGraphicsObject * toGraphicsObject()
QRectF mapRectToParent(const QRectF &rect) const
virtual void focusOutEvent(QFocusEvent *event)
bool hasFocus() const
QGraphicsItem * focusProxy() const
virtual void advance(int phase)
bool isClipped() const
bool isUnderMouse() const
QGraphicsItemGroup * group() const
friend class QGraphicsItemGroup
void setHandlesChildEvents(bool enabled)
qreal x() const
bool hasCursor() const
void setParentItem(QGraphicsItem *parent)
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event)
qreal zValue() const
QGraphicsItem * topLevelItem() const
virtual void dragMoveEvent(QGraphicsSceneDragDropEvent *event)
QPointF mapToScene(const QPointF &point) const
QGraphicsItem * focusScopeItem() const
virtual void keyPressEvent(QKeyEvent *event)
QRectF childrenBoundingRect() const
QPointF transformOriginPoint() const
void prepareGeometryChange()
virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event)
Qt::MouseButtons acceptedMouseButtons() const
void setFocusProxy(QGraphicsItem *item)
void setFlags(GraphicsItemFlags flags)
void setEnabled(bool enabled)
void setCacheMode(CacheMode mode, const QSize &cacheSize=QSize())
QVariant data(int key) const
QList< QGraphicsTransform * > transformations() const
void setFlag(GraphicsItemFlag flag, bool enabled=true)
QRectF mapRectToScene(const QRectF &rect) const
qreal effectiveOpacity() const
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
void scroll(qreal dx, qreal dy, const QRectF &rect=QRectF())
bool isPanel() const
QGraphicsObject * parentObject() const
void setAcceptDrops(bool on)
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
void setActive(bool active)
virtual void inputMethodEvent(QInputMethodEvent *event)
QGraphicsItem * panel() const
virtual int type() const
QPointF mapToParent(const QPointF &point) const
bool filtersChildEvents() const
QRectF mapRectFromItem(const QGraphicsItem *item, const QRectF &rect) const
virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const
virtual bool isObscuredBy(const QGraphicsItem *item) const
QGraphicsItem * parentItem() const
friend bool qt_closestItemFirst(const QGraphicsItem *, const QGraphicsItem *)
QRectF mapRectFromScene(const QRectF &rect) const
QTransform sceneTransform() const
QRegion boundingRegion(const QTransform &itemToDeviceTransform) const
Qt::InputMethodHints inputMethodHints() const
void removeSceneEventFilter(QGraphicsItem *filterItem)
void setVisible(bool visible)
QPointF mapFromParent(const QPointF &point) const
virtual ~QGraphicsItem()
void setBoundingRegionGranularity(qreal granularity)
QGraphicsItem * commonAncestorItem(const QGraphicsItem *other) const
QRectF mapRectFromParent(const QRectF &rect) const
virtual bool collidesWithPath(const QPainterPath &path, Qt::ItemSelectionMode mode=Qt::IntersectsItemShape) const
void setInputMethodHints(Qt::InputMethodHints hints)
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event)
void setTransformations(const QList< QGraphicsTransform * > &transformations)
bool isVisible() const
void setAcceptTouchEvents(bool enabled)
QGraphicsItem * focusItem() const
QGraphicsItem(QGraphicsItem *parent=nullptr)
QList< QGraphicsItem * > collidingItems(Qt::ItemSelectionMode mode=Qt::IntersectsItemShape) const
QTransform transform() const
virtual void keyReleaseEvent(QKeyEvent *event)
PanelModality panelModality() const
virtual bool supportsExtension(Extension extension) const
qreal opacity() const
bool isVisibleTo(const QGraphicsItem *parent) const
void setFocus(Qt::FocusReason focusReason=Qt::OtherFocusReason)
void setAcceptedMouseButtons(Qt::MouseButtons buttons)
virtual QPainterPath opaqueArea() const
bool isActive() const
void setCursor(const QCursor &cursor)
GraphicsItemFlags flags() const
virtual bool sceneEvent(QEvent *event)
void setY(qreal y)
bool acceptTouchEvents() const
QPointF mapFromScene(const QPointF &point) const
bool isAncestorOf(const QGraphicsItem *child) const
virtual ~QGraphicsItemPrivate()
bool isOpacityNull() const
void updateChildWithGraphicsEffectFlagRecursively()
QGraphicsItem * subFocusItem
void setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromHide)
void invalidateChildrenSceneTransform()
virtual void setPosHelper(const QPointF &pos)
QVariant extra(Extra type) const
QGraphicsScene * scene
static bool insertionOrder(QGraphicsItem *a, QGraphicsItem *b)
QList< QGraphicsItem ** > focusProxyRefs
static void children_append(QDeclarativeListProperty< QGraphicsObject > *list, QGraphicsObject *item)
QTransform transformToParent() const
void setParentItemHelper(QGraphicsItem *parent, const QVariant *newParentVariant, const QVariant *thisPointerVariant)
virtual void focusScopeItemChange(bool isSubFocusItem)
void initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform, const QRegion &exposedRegion, bool allItems=false) const
QGraphicsEffect * graphicsEffect
QGraphicsItem * focusProxy
virtual qreal height() const
void markParentDirty(bool updateBoundingRect=false)
QGraphicsItem * focusScopeItem
void setEnabledHelper(bool newEnabled, bool explicitly, bool update=true)
void setSubFocus(QGraphicsItem *rootItem=nullptr, QGraphicsItem *stopItem=nullptr)
void combineTransformToParent(QTransform *x, const QTransform *viewTransform=nullptr) const
virtual qreal width() const
QMap< Qt::GestureType, Qt::GestureFlags > gestureContext
bool itemIsUntransformable() const
quint32 mayHaveChildWithGraphicsEffect
void updateAncestorFlag(QGraphicsItem::GraphicsItemFlag childFlag, AncestorFlag flag=NoFlag, bool enabled=false, bool root=true)
bool discardUpdateRequest(bool ignoreVisibleBit=false, bool ignoreDirtyBit=false, bool ignoreOpacity=false) const
void combineTransformFromParent(QTransform *x, const QTransform *viewTransform=nullptr) const
void setExtra(Extra type, const QVariant &value)
virtual void resetWidth()
QGraphicsItem::PanelModality panelModality
virtual void transformChanged()
static const QGraphicsItemPrivate * get(const QGraphicsItem *item)
bool childrenCombineOpacity() const
void appendGraphicsTransform(QGraphicsTransform *t)
void clearSubFocus(QGraphicsItem *rootItem=nullptr, QGraphicsItem *stopItem=nullptr)
void setTransformHelper(const QTransform &transform)
QList< QGraphicsItem * > children
void ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem)
void removeChild(QGraphicsItem *child)
QRectF sceneEffectiveBoundingRect() const
quint32 hasBoundingRegionGranularity
quint32 sceneTransformTranslateOnly
void remapItemPos(QEvent *event, QGraphicsItem *item)
void clearFocusHelper(bool giveFocusToParent, bool hiddenByParentPanel)
static bool movableAncestorIsSelected(const QGraphicsItem *item)
quint32 sendParentChangeNotification
QRectF effectiveBoundingRect(QGraphicsItem *topMostEffectItem=nullptr) const
void updatePaintedViewBoundingRects(bool updateChildren)
bool isFullyTransparent() const
virtual void setWidth(qreal)
QPointF genericMapFromScene(const QPointF &pos, const QWidget *viewport) const
virtual void updateSceneTransformFromParent()
QTransform genericMapFromSceneTransform(const QWidget *viewport=nullptr) const
virtual void siblingOrderChange()
QDeclarativeListProperty< QGraphicsObject > childrenList()
quint32 paintedViewBoundingRectsNeedRepaint
QGraphicsItem * parent
void childrenBoundingRectHelper(QTransform *x, QRectF *rect, QGraphicsItem *topMostEffectItem)
bool hasTranslateOnlySceneTransform()
static void children_clear(QDeclarativeListProperty< QGraphicsObject > *list)
virtual void subFocusItemChange()
qreal effectiveOpacity() const
QGraphicsItem * q_ptr
TransformData * transformData
QGraphicsItemCache * maybeExtraItemCache() const
void prependGraphicsTransform(QGraphicsTransform *t)
static int children_count(QDeclarativeListProperty< QGraphicsObject > *list)
virtual void resetHeight()
QHash< QWidget *, QRect > paintedViewBoundingRects
QGraphicsItemCache * extraItemCache() const
void unsetExtra(Extra type)
void addChild(QGraphicsItem *child)
void setIsMemberOfGroup(bool enabled)
virtual bool isProxyWidget() const
void setVisibleHelper(bool newVisible, bool explicitly, bool update=true, bool hiddenByPanel=false)
virtual void setHeight(qreal)
static QGraphicsObject * children_at(QDeclarativeListProperty< QGraphicsObject > *list, int)
The QGraphicsLineItem class provides a line item that you can add to a QGraphicsScene.
QVariant extension(const QVariant &variant) const override
bool contains(const QPointF &point) const override
QPainterPath opaqueArea() const override
QPainterPath shape() const override
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget=nullptr) override
void setPen(const QPen &pen)
void setLine(const QLineF &line)
QRectF boundingRect() const override
int type() const override
bool isObscuredBy(const QGraphicsItem *item) const override
QLineF line() const
bool supportsExtension(Extension extension) const override
QGraphicsLineItem(QGraphicsItem *parent=nullptr)
void setExtension(Extension extension, const QVariant &variant) override
The QGraphicsObject class provides a base class for all graphics items that require signals,...
bool event(QEvent *ev) override
void setExtension(Extension extension, const QVariant &variant) override
QPainterPath opaqueArea() const override
QPainterPath shape() const override
QVariant extension(const QVariant &variant) const override
void setPath(const QPainterPath &path)
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget=nullptr) override
bool supportsExtension(Extension extension) const override
QPainterPath path() const
bool isObscuredBy(const QGraphicsItem *item) const override
bool contains(const QPointF &point) const override
QGraphicsPathItem(QGraphicsItem *parent=nullptr)
QRectF boundingRect() const override
The QGraphicsPixmapItem class provides a pixmap item that you can add to a QGraphicsScene.
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
void setExtension(Extension extension, const QVariant &variant) override
QPixmap pixmap() const
void setPixmap(const QPixmap &pixmap)
QVariant extension(const QVariant &variant) const override
void setOffset(const QPointF &offset)
bool isObscuredBy(const QGraphicsItem *item) const override
ShapeMode shapeMode() const
bool supportsExtension(Extension extension) const override
Qt::TransformationMode transformationMode() const
void setShapeMode(ShapeMode mode)
QGraphicsPixmapItem(QGraphicsItem *parent=nullptr)
bool contains(const QPointF &point) const override
QPainterPath opaqueArea() const override
void setTransformationMode(Qt::TransformationMode mode)
QRectF boundingRect() const override
QPainterPath shape() const override
int type() const override
QPointF offset() const
QGraphicsPixmapItem::ShapeMode shapeMode
Qt::TransformationMode transformationMode
The QGraphicsPolygonItem class provides a polygon item that you can add to a QGraphicsScene.
QGraphicsPolygonItem(QGraphicsItem *parent=nullptr)
int type() const override
void setExtension(Extension extension, const QVariant &variant) override
bool supportsExtension(Extension extension) const override
void setPolygon(const QPolygonF &polygon)
QPainterPath shape() const override
bool isObscuredBy(const QGraphicsItem *item) const override
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget=nullptr) override
QVariant extension(const QVariant &variant) const override
QRectF boundingRect() const override
void setFillRule(Qt::FillRule rule)
QPainterPath opaqueArea() const override
QPolygonF polygon() const
bool contains(const QPointF &point) const override
Qt::FillRule fillRule() const
The QGraphicsProxyWidget class provides a proxy layer for embedding a QWidget in a QGraphicsScene.
The QGraphicsRectItem class provides a rectangle item that you can add to a QGraphicsScene.
int type() const override
bool contains(const QPointF &point) const override
QPainterPath shape() const override
bool isObscuredBy(const QGraphicsItem *item) const override
QVariant extension(const QVariant &variant) const override
QPainterPath opaqueArea() const override
bool supportsExtension(Extension extension) const override
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget=nullptr) override
void setRect(const QRectF &rect)
QGraphicsRectItem(QGraphicsItem *parent=nullptr)
QRectF rect() const
void setExtension(Extension extension, const QVariant &variant) override
QRectF boundingRect() const override
The QGraphicsSceneContextMenuEvent class provides context menu events in the graphics view framework.
The QGraphicsSceneDragDropEvent class provides events for drag and drop in the graphics view framewor...
The QGraphicsSceneHoverEvent class provides hover events in the graphics view framework.
void setPos(const QPointF &pos)
The QGraphicsScene class provides a surface for managing a large number of 2D graphical items.
void removeItem(QGraphicsItem *item)
void addItem(QGraphicsItem *item)
void setFocusItem(QGraphicsItem *item, Qt::FocusReason focusReason=Qt::OtherFocusReason)
bool sendEvent(QGraphicsItem *item, QEvent *event)
bool isActive() const
void setActivePanel(QGraphicsItem *item)
QList< QGraphicsItem * > selectedItems() const
QGraphicsItem * activePanel() const
QList< QGraphicsView * > views() const
void update(qreal x, qreal y, qreal w, qreal h)
void selectionChanged()
virtual bool focusNextPrevChild(bool next)
QList< QGraphicsItem * > collidingItems(const QGraphicsItem *item, Qt::ItemSelectionMode mode=Qt::IntersectsItemShape) const
QGraphicsItem * focusItem() const
QGraphicsItem * mouseGrabberItem() const
virtual void prepareBoundingRectChange(const QGraphicsItem *item)
The QGraphicsSceneMouseEvent class provides mouse events in the graphics view framework.
void setButtonDownPos(Qt::MouseButton button, const QPointF &pos)
void setLastPos(const QPointF &pos)
void setPos(const QPointF &pos)
Qt::MouseButtons buttons() const
QPointF buttonDownPos(Qt::MouseButton button) const
QList< QGraphicsView * > views
QList< QGraphicsItem * > modalPanels
QList< QGraphicsWidget * > popupWidgets
void markDirty(QGraphicsItem *item, const QRectF &rect=QRectF(), bool invalidateChildren=false, bool force=false, bool ignoreOpacity=false, bool removingItemFromScene=false, bool updateBoundingRect=false)
QSet< QGraphicsItem * > selectedItems
QGraphicsSceneIndex * index
void draw(QGraphicsItem *, QPainter *, const QTransform *const, const QTransform *const, QRegion *, QWidget *, qreal, const QTransform *const, bool, bool)
The QGraphicsSceneWheelEvent class provides wheel events in the graphics view framework.
void setPos(const QPointF &pos)
The QGraphicsSimpleTextItem class provides a simple text path item that you can add to a QGraphicsSce...
bool contains(const QPointF &point) const override
void setExtension(Extension extension, const QVariant &variant) override
QPainterPath shape() const override
QGraphicsSimpleTextItem(QGraphicsItem *parent=nullptr)
void setText(const QString &text)
QVariant extension(const QVariant &variant) const override
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
void setFont(const QFont &font)
bool isObscuredBy(const QGraphicsItem *item) const override
bool supportsExtension(Extension extension) const override
int type() const override
QPainterPath opaqueArea() const override
QRectF boundingRect() const override
The QGraphicsTextItem class provides a text item that you can add to a QGraphicsScene to display form...
void setDocument(QTextDocument *document)
void linkHovered(const QString &)
bool contains(const QPointF &point) const override
void setTextInteractionFlags(Qt::TextInteractionFlags flags)
QTextCursor textCursor() const
void setHtml(const QString &html)
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override
void dragLeaveEvent(QGraphicsSceneDragDropEvent *event) override
void linkActivated(const QString &)
void mousePressEvent(QGraphicsSceneMouseEvent *event) override
bool isObscuredBy(const QGraphicsItem *item) const override
void focusInEvent(QFocusEvent *event) override
QVariant extension(const QVariant &variant) const override
bool openExternalLinks() const
QGraphicsTextItem(QGraphicsItem *parent=nullptr)
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
void setDefaultTextColor(const QColor &c)
QPainterPath opaqueArea() const override
void setTextCursor(const QTextCursor &cursor)
void dragMoveEvent(QGraphicsSceneDragDropEvent *event) override
Qt::TextInteractionFlags textInteractionFlags() const
QVariant inputMethodQuery(Qt::InputMethodQuery query) const override
bool tabChangesFocus() const
QColor defaultTextColor() const
void focusOutEvent(QFocusEvent *event) override
QRectF boundingRect() const override
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override
int type() const override
void setOpenExternalLinks(bool open)
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override
void setExtension(Extension extension, const QVariant &variant) override
void dropEvent(QGraphicsSceneDragDropEvent *event) override
void inputMethodEvent(QInputMethodEvent *event) override
bool sceneEvent(QEvent *event) override
QString toHtml() const
QPainterPath shape() const override
void setTextWidth(qreal width)
QFont font() const
void setTabChangesFocus(bool b)
void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override
QString toPlainText() const
QTextDocument * document() const
void keyPressEvent(QKeyEvent *event) override
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override
qreal textWidth() const
void keyReleaseEvent(QKeyEvent *event) override
void setPlainText(const QString &text)
bool supportsExtension(Extension extension) const override
void setFont(const QFont &font)
void dragEnterEvent(QGraphicsSceneDragDropEvent *event) override
void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override
QGraphicsTextItem * qq
void _q_updateBoundingRect(const QSizeF &)
QWidgetTextControl * control
QPointF controlOffset() const
bool _q_mouseOnEdge(QGraphicsSceneMouseEvent *)
QWidgetTextControl * textControl() const
void sendControlEvent(QEvent *e)
The QGraphicsTransform class is an abstract base class for building advanced transformations on QGrap...
virtual void applyTo(QMatrix4x4 *matrix) const =0
The QGraphicsView class provides a widget for displaying the contents of a QGraphicsScene.
Definition: qgraphicsview.h:60
bool updateRect(const QRect &rect)
The QGraphicsWidget class is the base class for all widget items in a QGraphicsScene.
static QInputMethod * inputMethod()
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qhash.h:773
bool contains(const Key &key) const noexcept
Definition: qhash.h:944
T value(const Key &key) const noexcept
Definition: qhash.h:997
bool isEmpty() const noexcept
Definition: qhash.h:881
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:73
@ Format_ARGB32_Premultiplied
Definition: qimage.h:84
The QInputMethodEvent class provides parameters for input method events. \inmodule QtGui.
Definition: qevent.h:696
void update(Qt::InputMethodQueries queries)
The QKeyEvent class describes a key event.
Definition: qevent.h:471
Qt::KeyboardModifiers modifiers() const
Definition: qevent.cpp:1502
int key() const
Definition: qevent.h:484
The QLineF class provides a two-dimensional vector using floating point precision.
Definition: qline.h:215
qsizetype size() const noexcept
Definition: qlist.h:414
bool isEmpty() const noexcept
Definition: qlist.h:418
void removeAt(qsizetype i)
Definition: qlist.h:588
iterator insert(qsizetype i, parameter_type t)
Definition: qlist.h:499
bool removeOne(const AT &t)
Definition: qlist.h:596
iterator end()
Definition: qlist.h:624
const_reference at(qsizetype i) const noexcept
Definition: qlist.h:457
void move(qsizetype from, qsizetype to)
Definition: qlist.h:608
void remove(qsizetype i, qsizetype n=1)
Definition: qlist.h:798
qsizetype count() const noexcept
Definition: qlist.h:415
void prepend(rvalue_ref t)
Definition: qlist.h:484
iterator begin()
Definition: qlist.h:623
T & first()
Definition: qlist.h:643
void append(parameter_type t)
Definition: qlist.h:469
void clear()
Definition: qlist.h:445
iterator insert(const Key &key, const T &value)
Definition: qmap.h:719
bool contains(const Key &key) const
Definition: qmap.h:376
bool isEmpty() const
Definition: qmap.h:304
const_iterator constBegin() const
Definition: qmap.h:635
const_iterator constEnd() const
Definition: qmap.h:639
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition: qmatrix4x4.h:61
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Definition: qobject.cpp:2772
virtual bool event(QEvent *event)
Definition: qobject.cpp:1329
bool isSignalConnected(uint signalIdx, bool checkDeclarative=true) const
Definition: qobject.cpp:460
static QObjectPrivate * get(QObject *o)
Definition: qobject_p.h:368
The QPainter class performs low-level painting on widgets and other paint devices.
Definition: qpainter.h:82
void drawRect(const QRectF &rect)
Definition: qpainter.h:554
void drawPath(const QPainterPath &path)
Definition: qpainter.cpp:3171
void drawPie(const QRectF &rect, int a, int alen)
Definition: qpainter.cpp:4175
void setPen(const QColor &color)
Definition: qpainter.cpp:3640
void drawLine(const QLineF &line)
Definition: qpainter.h:477
void restore()
Definition: qpainter.cpp:1611
const QTransform & worldTransform() const
Definition: qpainter.cpp:7967
void save()
Definition: qpainter.cpp:1577
void setFont(const QFont &f)
Definition: qpainter.cpp:3866
void drawPixmap(const QRectF &targetRect, const QPixmap &pixmap, const QRectF &sourceRect)
Definition: qpainter.cpp:4883
void drawEllipse(const QRectF &r)
Definition: qpainter.cpp:3986
void setBrush(const QBrush &brush)
Definition: qpainter.cpp:3755
@ SmoothPixmapTransform
Definition: qpainter.h:90
@ Antialiasing
Definition: qpainter.h:88
@ TextAntialiasing
Definition: qpainter.h:89
const QTransform & transform() const
Definition: qpainter.cpp:7873
void drawPolygon(const QPointF *points, int pointCount, Qt::FillRule fillRule=Qt::OddEvenFill)
Definition: qpainter.cpp:4575
void translate(const QPointF &offset)
Definition: qpainter.cpp:2993
void setRenderHint(RenderHint hint, bool on=true)
Definition: qpainter.cpp:6845
The QPainterPath class provides a container for painting operations, enabling graphical shapes to be ...
Definition: qpainterpath.h:65
void addRect(const QRectF &rect)
QRectF controlPointRect() const
bool contains(const QPointF &pt) const
bool isEmpty() const
QPainterPath intersected(const QPainterPath &r) const
The QPainterPathStroker class is used to generate fillable outlines for a given painter path.
Definition: qpainterpath.h:232
The QPalette class contains color groups for each widget state.
Definition: qpalette.h:55
const QColor & color(ColorGroup cg, ColorRole cr) const
Definition: qpalette.h:101
void setColor(ColorGroup cg, ColorRole cr, const QColor &color)
Definition: qpalette.h:179
@ Text
Definition: qpalette.h:87
The QPen class defines how a QPainter should draw lines and outlines of shapes.
Definition: qpen.h:61
qreal widthF() const
Definition: qpen.cpp:634
void setStyle(Qt::PenStyle)
[0]
Qt::PenCapStyle capStyle() const
Definition: qpen.cpp:698
Qt::PenJoinStyle joinStyle() const
Definition: qpen.cpp:725
qreal miterLimit() const
Definition: qpen.cpp:584
Qt::PenStyle style() const
Definition: qpen.cpp:421
static bool find(const QString &key, QPixmap *pixmap)
static void remove(const QString &key)
static bool insert(const QString &key, const QPixmap &pixmap)
The QPixmap class is an off-screen image representation that can be used as a paint device.
Definition: qpixmap.h:63
int height() const
Definition: qpixmap.cpp:515
void scroll(int dx, int dy, int x, int y, int width, int height, QRegion *exposed=nullptr)
Definition: qpixmap.h:195
QBitmap mask() const
Definition: qpixmap.cpp:1395
int width() const
Definition: qpixmap.cpp:503
QBitmap createHeuristicMask(bool clipTight=true) const
Definition: qpixmap.cpp:686
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:242
constexpr qreal x() const noexcept
Definition: qpoint.h:361
constexpr qreal y() const noexcept
Definition: qpoint.h:366
constexpr QPoint toPoint() const
Definition: qpoint.h:420
bool isNull() const noexcept
Definition: qpoint.h:356
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:52
The QPolygonF class provides a list of points using floating point precision. \inmodule QtGui.
Definition: qpolygon.h:128
The QRectF class defines a finite rectangle in the plane using floating point precision.
Definition: qrect.h:511
constexpr bool isEmpty() const noexcept
Definition: qrect.h:670
QRect toAlignedRect() const noexcept
Definition: qrect.cpp:2351
constexpr qreal height() const noexcept
Definition: qrect.h:741
constexpr qreal width() const noexcept
Definition: qrect.h:738
constexpr QRectF translated(qreal dx, qreal dy) const noexcept
Definition: qrect.h:771
bool contains(const QRectF &r) const noexcept
Definition: qrect.cpp:2006
constexpr QRectF adjusted(qreal x1, qreal y1, qreal x2, qreal y2) const noexcept
Definition: qrect.h:822
bool intersects(const QRectF &r) const noexcept
Definition: qrect.cpp:2284
constexpr void setSize(const QSizeF &s) noexcept
Definition: qrect.h:833
constexpr QPointF topLeft() const noexcept
Definition: qrect.h:538
constexpr QSizeF size() const noexcept
Definition: qrect.h:744
constexpr QRect toRect() const noexcept
Definition: qrect.h:866
constexpr void translate(qreal dx, qreal dy) noexcept
Definition: qrect.h:747
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:59
constexpr bool isEmpty() const noexcept
Definition: qrect.h:194
bool intersects(const QRect &r) const noexcept
Definition: qrect.cpp:1101
constexpr int height() const noexcept
Definition: qrect.h:266
constexpr QPoint topLeft() const noexcept
Definition: qrect.h:248
constexpr QRect adjusted(int x1, int y1, int x2, int y2) const noexcept
Definition: qrect.h:397
constexpr int x() const noexcept
Definition: qrect.h:212
constexpr QSize size() const noexcept
Definition: qrect.h:269
constexpr int width() const noexcept
Definition: qrect.h:263
constexpr QRect translated(int dx, int dy) const noexcept
Definition: qrect.h:288
constexpr int y() const noexcept
Definition: qrect.h:215
The QRegion class specifies a clip region for a painter.
Definition: qregion.h:63
void translate(int dx, int dy)
QRegion translated(int dx, int dy) const
Definition: qregion.cpp:629
T * data() const noexcept
The QSizeF class defines the size of a two-dimensional object using floating point precision.
Definition: qsize.h:235
constexpr qreal height() const noexcept
Definition: qsize.h:352
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:55
The QString class provides a Unicode character string.
Definition: qstring.h:388
QString & replace(qsizetype i, qsizetype len, QChar after)
Definition: qstring.cpp:3450
bool isEmpty() const
Definition: qstring.h:1216
@ State_MouseOver
Definition: qstyle.h:116
@ State_Sunken
Definition: qstyle.h:105
@ State_HasFocus
Definition: qstyle.h:111
@ State_Enabled
Definition: qstyle.h:103
@ State_Selected
Definition: qstyle.h:118
@ State_None
Definition: qstyle.h:102
The QStyleOptionGraphicsItem class is used to describe the parameters needed to draw a QGraphicsItem.
Definition: qstyleoption.h:684
The QTextCursor class offers an API to access and modify QTextDocuments.
Definition: qtextcursor.h:67
The QTextDocument class holds formatted text.
Definition: qtextdocument.h:93
QFont defaultFont
the default font used to display the document's text
Definition: qtextdocument.h:99
QAbstractTextDocumentLayout * documentLayout() const
QSizeF pageSize
the page size that should be used for laying out the document
Definition: qtextdocument.h:98
void setDefaultFont(const QFont &font)
QTextFrame * rootFrame() const
The QTextFrameFormat class provides formatting information for frames in a QTextDocument....
Definition: qtextformat.h:859
QTextFrameFormat frameFormat() const
Definition: qtextobject.h:125
The QTextLayout class is used to lay out and render text. \inmodule QtGui.
Definition: qtextlayout.h:106
The QTextLine class represents a line of text inside a QTextLayout. \inmodule QtGui.
Definition: qtextlayout.h:208
The QTransform class specifies 2D transformations of a coordinate system.
Definition: qtransform.h:56
static QTransform fromScale(qreal dx, qreal dy)
Definition: qtransform.cpp:503
QTransform & scale(qreal sx, qreal sy)
Definition: qtransform.cpp:460
qreal dx() const
Definition: qtransform.h:262
QPoint map(const QPoint &p) const
static QTransform fromTranslate(qreal dx, qreal dy)
Definition: qtransform.cpp:437
QTransform inverted(bool *invertible=nullptr) const
Definition: qtransform.cpp:339
QTransform & rotate(qreal a, Qt::Axis axis=Qt::ZAxis)
Definition: qtransform.cpp:588
TransformationType type() const
QTransform & translate(qreal dx, qreal dy)
Definition: qtransform.cpp:392
QRect mapRect(const QRect &) const
qreal dy() const
Definition: qtransform.h:266
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:95
QPointF toPointF() const
Definition: qvariant.cpp:1627
qreal toReal(bool *ok=nullptr) const
Definition: qvariant.cpp:1967
QString toString() const
Definition: qvariant.cpp:1416
bool toBool() const
Definition: qvariant.cpp:1906
QRectF toRectF() const
Definition: qvariant.cpp:1587
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:133
Qt::WindowType windowType() const
Definition: qwidget.h:834
void handleSoftwareInputPanel(Qt::MouseButton button, bool clickCausedFocus)
Definition: qwidget_p.h:588
void setPlainText(const QString &text)
QTextCursor textCursor() const
Qt::TextInteractionFlags textInteractionFlags
QString toPlainText() const
void setOpenExternalLinks(bool open)
void setHtml(const QString &text)
void setTextCursor(const QTextCursor &cursor, bool selectionClipboard=false)
void linkActivated(const QString &link)
QPalette palette() const
void updateRequest(const QRectF &rect=QRectF())
void setDocument(QTextDocument *document)
void drawContents(QPainter *painter, const QRectF &rect=QRectF(), QWidget *widget=nullptr)
virtual QVariant inputMethodQuery(Qt::InputMethodQuery property, QVariant argument) const
virtual void processEvent(QEvent *e, const QTransform &transform, QWidget *contextWidget=nullptr)
void documentSizeChanged(const QSizeF &)
void linkHovered(const QString &)
void visibilityRequest(const QRectF &rect)
QTextDocument * document() const
void setTextWidth(qreal width)
void setTextInteractionFlags(Qt::TextInteractionFlags flags)
QRhiGraphicsPipeline * ps
float factor
float rx
#define this
Definition: dialogs.cpp:56
QOpenGLWidget * widget
[1]
b clear()
QMap< QString, QString > map
[6]
QString str
[2]
QDomDocument document
[0]
QPixmap p2
QString text
[meta data]
QPushButton * button
[2]
QCursor cursor
double e
QCache< int, Employee > cache
[0]
rect
[4]
#define true
Definition: ftrandom.c:51
backing_store_ptr info
[4]
Definition: jmemsys.h:161
Definition: qnamespace.h:55
InputMethodQuery
Definition: qnamespace.h:1380
@ ImHints
Definition: qnamespace.h:1389
@ ImQueryInput
Definition: qnamespace.h:1401
MouseButton
Definition: qnamespace.h:81
@ LeftButton
Definition: qnamespace.h:83
@ TextEditable
Definition: qnamespace.h:1575
@ NoTextInteraction
Definition: qnamespace.h:1570
TransformationMode
Definition: qnamespace.h:1349
@ FastTransformation
Definition: qnamespace.h:1350
@ SmoothTransformation
Definition: qnamespace.h:1351
@ NonModal
Definition: qnamespace.h:1564
@ ImhNone
Definition: qnamespace.h:1409
@ transparent
Definition: qnamespace.h:78
@ SolidLine
Definition: qnamespace.h:1113
@ DashLine
Definition: qnamespace.h:1114
@ NoPen
Definition: qnamespace.h:1112
@ Key_Tab
Definition: qnamespace.h:685
@ Key_Backtab
Definition: qnamespace.h:686
@ ShiftModifier
Definition: qnamespace.h:1075
@ ControlModifier
Definition: qnamespace.h:1076
@ AltModifier
Definition: qnamespace.h:1077
ItemSelectionMode
Definition: qnamespace.h:1337
@ IntersectsItemShape
Definition: qnamespace.h:1339
@ ContainsItemShape
Definition: qnamespace.h:1338
@ IntersectsItemBoundingRect
Definition: qnamespace.h:1341
@ SolidPattern
Definition: qnamespace.h:1141
@ NoBrush
Definition: qnamespace.h:1140
CoordinateSystem
Definition: qnamespace.h:1615
@ DeviceCoordinates
Definition: qnamespace.h:1616
@ LogicalCoordinates
Definition: qnamespace.h:1617
GestureType
Definition: qnamespace.h:1641
constexpr Initialization Uninitialized
Definition: qnamespace.h:1613
FillRule
Definition: qnamespace.h:1320
@ OddEvenFill
Definition: qnamespace.h:1321
@ Popup
Definition: qnamespace.h:236
@ Window
Definition: qnamespace.h:232
FocusReason
Definition: qnamespace.h:1360
@ MouseFocusReason
Definition: qnamespace.h:1361
@ OtherFocusReason
Definition: qnamespace.h:1368
Definition: brush.cpp:52
#define QString()
Definition: parse-defines.h:51
#define Q_FALLTHROUGH()
DBusConnection const char * rule
EGLOutputLayerEXT EGLint EGLAttrib value
QT_BEGIN_NAMESPACE bool done
bool qFuzzyIsNull(qfloat16 f) noexcept
Definition: qfloat16.h:249
bool qIsNaN(qfloat16 f) noexcept
Definition: qfloat16.h:221
unsigned int quint32
Definition: qglobal.h:288
QT_END_INCLUDE_NAMESPACE typedef double qreal
Definition: qglobal.h:341
unsigned int uint
Definition: qglobal.h:334
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
bool _qt_movableAncestorIsSelected(const QGraphicsItem *item)
QPainterPath qt_regionToPath(const QRegion &region)
Definition: qregion.cpp:1043
void Q_WIDGETS_EXPORT qt_graphicsItem_highlightSelected(QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option)
@ text
void invalidateCache(QAccessibleInterface *iface)
#define qWarning
Definition: qlogging.h:179
#define Q_ARG(type, data)
Definition: qobjectdefs.h:98
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat z
GLint GLint GLint GLint GLint x
[0]
GLenum mode
const GLfloat * m
GLuint64 key
GLboolean r
[2]
GLfloat GLfloat GLfloat w
[0]
GLuint GLfloat GLfloat GLfloat GLfloat y1
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLuint GLfloat GLfloat GLfloat x1
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLfloat GLfloat f
GLsizei range
GLint GLsizei width
GLboolean GLuint group
GLfloat angle
GLbitfield flags
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLintptr offset
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLint GLsizei GLsizei GLenum format
GLint y
GLfloat GLfloat GLfloat GLfloat h
GLsizei GLsizei GLchar * source
struct _cl_event * event
Definition: qopenglext.h:2998
GLuint GLenum GLenum transform
Definition: qopenglext.h:11564
GLenum query
Definition: qopenglext.h:2738
GLuint res
Definition: qopenglext.h:8867
const GLubyte * c
Definition: qopenglext.h:12701
GLfixed GLfixed GLfixed y2
Definition: qopenglext.h:5231
GLuint GLenum matrix
Definition: qopenglext.h:11564
GLfixed GLfixed x2
Definition: qopenglext.h:5231
GLdouble GLdouble t
[9]
Definition: qopenglext.h:243
GLdouble GLdouble GLdouble GLdouble q
Definition: qopenglext.h:259
GLsizei const GLchar *const * path
Definition: qopenglext.h:4283
GLuint64EXT * result
[6]
Definition: qopenglext.h:10932
GLfloat GLfloat p
[1]
Definition: qopenglext.h:12698
GLuint GLenum option
Definition: qopenglext.h:5929
GLbyte ty
Definition: qopenglext.h:6700
GLbyte by
Definition: qopenglext.h:6710
#define Q_ASSERT(cond)
Definition: qrandom.cpp:84
#define Q_ASSERT_X(cond, x, msg)
Definition: qrandom.cpp:85
QPointF qAbs(const QPointF &p)
Definition: qscroller.cpp:119
#define emit
Definition: qtmetamacros.h:85
Q_WIDGETS_EXPORT QWidgetPrivate * qt_widget_private(QWidget *widget)
Definition: qwidget.cpp:12216
#define enabled
Definition: qopenglext.h:3098
Q_UNUSED(salary)
[21]
file open(QIODevice::ReadOnly)
QFileInfo fi("c:/temp/foo")
[newstuff]
QObject::connect nullptr
QVBoxLayout * layout
QVariant variant
[1]
QSharedPointer< T > other(t)
[5]
QGraphicsOpacityEffect * effect
QGraphicsScene scene
[0]
rect sceneTransform().map(QPointF(0
QGraphicsItem * item
view viewport() -> scroll(dx, dy, deviceRect)
myFilter draw(painter, QPoint(0, 0), originalPixmap)
QList< QTreeWidgetItem * > items
QLayoutItem * child
[0]
widget render & pixmap
QPainter painter(this)
[7]
backaction setToolTip(browser.historyTitle(-1))
[0]
QNetworkAccessManager manager
QQuickView * view
[0]
QStringList::Iterator it
QStringList list
[0]
QTransform computedFullTransform(QTransform *postmultiplyTransform=nullptr) const
QList< QGraphicsTransform * > graphicsTransforms
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:53
bool contains(const AT &t) const noexcept
Definition: qlist.h:78
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(nullptr), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
The QTextLayout::FormatRange structure is used to apply extra formatting information for a specified ...
Definition: qtextlayout.h:132
QThreadStorage< int * > dummy[8]
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent