Qt 4.8
qgraphicsscene.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui 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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
214 #include "qgraphicsscene.h"
215 
216 #ifndef QT_NO_GRAPHICSVIEW
217 
218 #include "qgraphicsitem.h"
219 #include "qgraphicsitem_p.h"
220 #include "qgraphicslayout.h"
221 #include "qgraphicsscene_p.h"
222 #include "qgraphicssceneevent.h"
223 #include "qgraphicsview.h"
224 #include "qgraphicsview_p.h"
225 #include "qgraphicswidget.h"
226 #include "qgraphicswidget_p.h"
227 #include "qgraphicssceneindex_p.h"
230 
231 #include <QtCore/qdebug.h>
232 #include <QtCore/qlist.h>
233 #include <QtCore/qmath.h>
234 #include <QtCore/qrect.h>
235 #include <QtCore/qset.h>
236 #include <QtCore/qstack.h>
237 #include <QtCore/qtimer.h>
238 #include <QtCore/qvarlengtharray.h>
239 #include <QtCore/QMetaMethod>
240 #include <QtGui/qapplication.h>
241 #include <QtGui/qdesktopwidget.h>
242 #include <QtGui/qevent.h>
243 #include <QtGui/qgraphicslayout.h>
244 #include <QtGui/qgraphicsproxywidget.h>
245 #include <QtGui/qgraphicswidget.h>
246 #include <QtGui/qmatrix.h>
247 #include <QtGui/qpaintengine.h>
248 #include <QtGui/qpainter.h>
249 #include <QtGui/qpixmapcache.h>
250 #include <QtGui/qpolygon.h>
251 #include <QtGui/qstyleoption.h>
252 #include <QtGui/qtooltip.h>
253 #include <QtGui/qtransform.h>
254 #include <QtGui/qinputcontext.h>
255 #include <QtGui/qgraphicseffect.h>
256 #ifndef QT_NO_ACCESSIBILITY
257 # include <QtGui/qaccessible.h>
258 #endif
259 
260 #include <private/qapplication_p.h>
261 #include <private/qobject_p.h>
262 #ifdef Q_WS_X11
263 #include <private/qt_x11_p.h>
264 #endif
265 #include <private/qgraphicseffect_p.h>
266 #include <private/qgesturemanager_p.h>
267 #include <private/qpathclipper_p.h>
268 
269 // #define GESTURE_DEBUG
270 #ifndef GESTURE_DEBUG
271 # define G_DEBUG if (0) qDebug
272 #else
273 # define G_DEBUG qDebug
274 #endif
275 
277 
278 bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event);
279 
281 {
282  hover->setWidget(mouseEvent->widget());
283  hover->setPos(mouseEvent->pos());
284  hover->setScenePos(mouseEvent->scenePos());
285  hover->setScreenPos(mouseEvent->screenPos());
286  hover->setLastPos(mouseEvent->lastPos());
287  hover->setLastScenePos(mouseEvent->lastScenePos());
288  hover->setLastScreenPos(mouseEvent->lastScreenPos());
289  hover->setModifiers(mouseEvent->modifiers());
290  hover->setAccepted(mouseEvent->isAccepted());
291 }
292 
297  : indexMethod(QGraphicsScene::BspTreeIndex),
298  index(0),
299  lastItemCount(0),
300  hasSceneRect(false),
301  dirtyGrowingItemsBoundingRect(true),
302  updateAll(false),
303  calledEmitUpdated(false),
304  processDirtyItemsEmitted(false),
305  needSortTopLevelItems(true),
306  holesInTopLevelSiblingIndex(false),
307  topLevelSequentialOrdering(true),
308  scenePosDescendantsUpdatePending(false),
309  stickyFocus(false),
310  hasFocus(false),
311  lastMouseGrabberItemHasImplicitMouseGrab(false),
312  allItemsIgnoreHoverEvents(true),
313  allItemsUseDefaultCursor(true),
314  painterStateProtection(true),
315  sortCacheEnabled(false),
316  allItemsIgnoreTouchEvents(true),
317  selectionChanging(0),
318  rectAdjust(2),
319  focusItem(0),
320  lastFocusItem(0),
321  passiveFocusItem(0),
322  tabFocusFirst(0),
323  activePanel(0),
324  lastActivePanel(0),
325  activationRefCount(0),
326  childExplicitActivation(0),
327  lastMouseGrabberItem(0),
328  dragDropItem(0),
329  enterWidget(0),
330  lastDropAction(Qt::IgnoreAction),
331  style(0)
332 {
333 }
334 
339 {
341 
343 
344  // Keep this index so we can check for connected slots later on.
345  changedSignalIndex = signalIndex("changed(QList<QRectF>)");
346  processDirtyItemsIndex = q->metaObject()->indexOfSlot("_q_processDirtyItems()");
347  polishItemsIndex = q->metaObject()->indexOfSlot("_q_polishItems()");
348 
349  qApp->d_func()->scene_list.append(q);
350  q->update();
351 }
352 
357 {
358  return q->d_func();
359 }
360 
362 {
364  calledEmitUpdated = false;
365 
367  if (!hasSceneRect) {
368  const QRectF oldGrowingItemsBoundingRect = growingItemsBoundingRect;
369  growingItemsBoundingRect |= q->itemsBoundingRect();
370  if (oldGrowingItemsBoundingRect != growingItemsBoundingRect)
371  emit q->sceneRectChanged(growingItemsBoundingRect);
372  }
374  }
375 
376  // Ensure all views are connected if anything is connected. This disables
377  // the optimization that items send updates directly to the views, but it
378  // needs to happen in order to keep compatibility with the behavior from
379  // Qt 4.4 and backward.
381  for (int i = 0; i < views.size(); ++i) {
382  QGraphicsView *view = views.at(i);
383  if (!view->d_func()->connectedToScene) {
384  view->d_func()->connectedToScene = true;
385  q->connect(q, SIGNAL(changed(QList<QRectF>)),
386  views.at(i), SLOT(updateScene(QList<QRectF>)));
387  }
388  }
389  } else {
390  if (views.isEmpty()) {
391  updateAll = false;
392  return;
393  }
394  for (int i = 0; i < views.size(); ++i)
395  views.at(i)->d_func()->processPendingUpdates();
396  // It's important that we update all views before we dispatch, hence two for-loops.
397  for (int i = 0; i < views.size(); ++i)
398  views.at(i)->d_func()->dispatchPendingUpdateRequests();
399  return;
400  }
401 
402  // Notify the changes to anybody interested.
403  QList<QRectF> oldUpdatedRects;
404  oldUpdatedRects = updateAll ? (QList<QRectF>() << q->sceneRect()) : updatedRects;
405  updateAll = false;
407  emit q->changed(oldUpdatedRects);
408 }
409 
416 {
418  needSortTopLevelItems = true; // ### maybe false
420  topLevelItems.append(item);
421 }
422 
429 {
434  else
435  topLevelItems.removeOne(item);
436  // NB! Do not use topLevelItems.removeAt(item->d_ptr->siblingIndex) because
437  // the item is not guaranteed to be at the index after the list is sorted
438  // (see ensureSortedTopLevelItems()).
439  item->d_ptr->siblingIndex = -1;
442 }
443 
448 {
449  if (unpolishedItems.isEmpty())
450  return;
451 
452  const QVariant booleanTrueVariant(true);
453  QGraphicsItem *item = 0;
454  QGraphicsItemPrivate *itemd = 0;
455  const int oldUnpolishedCount = unpolishedItems.count();
456 
457  for (int i = 0; i < oldUnpolishedCount; ++i) {
458  item = unpolishedItems.at(i);
459  if (!item)
460  continue;
461  itemd = item->d_ptr.data();
462  itemd->pendingPolish = false;
463  if (!itemd->explicitlyHidden) {
464  item->itemChange(QGraphicsItem::ItemVisibleChange, booleanTrueVariant);
465  item->itemChange(QGraphicsItem::ItemVisibleHasChanged, booleanTrueVariant);
466  }
467  if (itemd->isWidget) {
469  QApplication::sendEvent((QGraphicsWidget *)item, &event);
470  }
471  }
472 
473  if (unpolishedItems.count() == oldUnpolishedCount) {
474  // No new items were added to the vector.
476  } else {
477  // New items were appended; keep them and remove the old ones.
478  unpolishedItems.remove(0, oldUnpolishedCount);
481  }
482 }
483 
485 {
486  processDirtyItemsEmitted = false;
487 
488  if (updateAll) {
490  // No need for further processing (except resetting the dirty states).
491  // The growingItemsBoundingRect is updated in _q_emitUpdated.
492  for (int i = 0; i < topLevelItems.size(); ++i)
493  resetDirtyItem(topLevelItems.at(i), /*recursive=*/true);
494  return;
495  }
496 
497  const bool wasPendingSceneUpdate = calledEmitUpdated;
498  const QRectF oldGrowingItemsBoundingRect = growingItemsBoundingRect;
499 
500  // Process items recursively.
501  for (int i = 0; i < topLevelItems.size(); ++i)
503 
505  if (!hasSceneRect && oldGrowingItemsBoundingRect != growingItemsBoundingRect)
506  emit q_func()->sceneRectChanged(growingItemsBoundingRect);
507 
508  if (wasPendingSceneUpdate)
509  return;
510 
511  for (int i = 0; i < views.size(); ++i)
512  views.at(i)->d_func()->processPendingUpdates();
513 
514  if (calledEmitUpdated) {
515  // We did a compatibility QGraphicsScene::update in processDirtyItemsRecursive
516  // and we cannot wait for the control to reach the eventloop before the
517  // changed signal is emitted, so we emit it now.
518  _q_emitUpdated();
519  }
520 
521  // Immediately dispatch all pending update requests on the views.
522  for (int i = 0; i < views.size(); ++i)
523  views.at(i)->d_func()->dispatchPendingUpdateRequests();
524 }
525 
530 {
531  QGraphicsItem *p = item->d_ptr->parent;
532  while (p) {
534  p = p->d_ptr->parent;
535  }
536  if (!enabled && !scenePosDescendantsUpdatePending) {
538  QMetaObject::invokeMethod(q_func(), "_q_updateScenePosDescendants", Qt::QueuedConnection);
539  }
540 }
541 
546 {
547  scenePosItems.insert(item);
548  setScenePosItemEnabled(item, true);
549 }
550 
555 {
556  scenePosItems.remove(item);
557  setScenePosItemEnabled(item, false);
558 }
559 
564 {
565  foreach (QGraphicsItem *item, scenePosItems) {
566  QGraphicsItem *p = item->d_ptr->parent;
567  while (p) {
568  p->d_ptr->scenePosDescendants = 1;
569  p = p->d_ptr->parent;
570  }
571  }
573 }
574 
591 {
593 
594  // Clear focus on the item to remove any reference in the focusWidget chain.
595  item->clearFocus();
596 
597  markDirty(item, QRectF(), /*invalidateChildren=*/false, /*force=*/false,
598  /*ignoreOpacity=*/false, /*removingItemFromScene=*/true);
599 
600  if (item->d_ptr->inDestructor) {
601  // The item is actually in its destructor, we call the special method in the index.
602  index->deleteItem(item);
603  } else {
604  // Can potentially call item->boundingRect() (virtual function), that's why
605  // we only can call this function if the item is not in its destructor.
606  index->removeItem(item);
607  }
608 
609  item->d_ptr->clearSubFocus();
610 
613 
614  QGraphicsScene *oldScene = item->d_func()->scene;
615  item->d_func()->scene = 0;
616 
617  //We need to remove all children first because they might use their parent
618  //attributes (e.g. sceneTransform).
619  if (!item->d_ptr->inDestructor) {
620  // Remove all children recursively
621  for (int i = 0; i < item->d_ptr->children.size(); ++i)
622  q->removeItem(item->d_ptr->children.at(i));
623  }
624 
625  if (!item->d_ptr->inDestructor && item == tabFocusFirst) {
626  QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
627  widget->d_func()->fixFocusChainBeforeReparenting(0, oldScene, 0);
628  }
629 
630  // Unregister focus proxy.
631  item->d_ptr->resetFocusProxy();
632 
633  // Remove from parent, or unregister from toplevels.
634  if (QGraphicsItem *parentItem = item->parentItem()) {
635  if (parentItem->scene()) {
636  Q_ASSERT_X(parentItem->scene() == q, "QGraphicsScene::removeItem",
637  "Parent item's scene is different from this item's scene");
638  item->setParentItem(0);
639  }
640  } else {
642  }
643 
644  // Reset the mouse grabber and focus item data.
645  if (item == focusItem)
646  focusItem = 0;
647  if (item == lastFocusItem)
648  lastFocusItem = 0;
649  if (item == passiveFocusItem)
650  passiveFocusItem = 0;
651  if (item == activePanel) {
652  // ### deactivate...
653  activePanel = 0;
654  }
655  if (item == lastActivePanel)
656  lastActivePanel = 0;
657 
658  // Cancel active touches
659  {
661  while (it != itemForTouchPointId.end()) {
662  if (it.value() == item) {
664  it = itemForTouchPointId.erase(it);
665  } else {
666  ++it;
667  }
668  }
669  }
670 
671  // Disable selectionChanged() for individual items
673  int oldSelectedItemsSize = selectedItems.size();
674 
675  // Update selected & hovered item bookkeeping
676  selectedItems.remove(item);
677  hoverItems.removeAll(item);
679  if (item->d_ptr->pendingPolish) {
680  const int unpolishedIndex = unpolishedItems.indexOf(item);
681  if (unpolishedIndex != -1)
682  unpolishedItems[unpolishedIndex] = 0;
683  item->d_ptr->pendingPolish = false;
684  }
685  resetDirtyItem(item);
686 
687  //We remove all references of item from the sceneEventFilter arrays
689  while (iterator != sceneEventFilters.end()) {
690  if (iterator.value() == item || iterator.key() == item)
691  iterator = sceneEventFilters.erase(iterator);
692  else
693  ++iterator;
694  }
695 
696  if (item->isPanel() && item->isVisible() && item->panelModality() != QGraphicsItem::NonModal)
697  leaveModal(item);
698 
699  // Reset the mouse grabber and focus item data.
700  if (mouseGrabberItems.contains(item))
701  ungrabMouse(item, /* item is dying */ item->d_ptr->inDestructor);
702 
703  // Reset the keyboard grabber
704  if (keyboardGrabberItems.contains(item))
705  ungrabKeyboard(item, /* item is dying */ item->d_ptr->inDestructor);
706 
707  // Reset the last mouse grabber item
708  if (item == lastMouseGrabberItem)
710 
711  // Reset the current drop item
712  if (item == dragDropItem)
713  dragDropItem = 0;
714 
715  // Reenable selectionChanged() for individual items
717  if (!selectionChanging && selectedItems.size() != oldSelectedItemsSize)
718  emit q->selectionChanged();
719 
720 #ifndef QT_NO_GESTURES
722  for (it = gestureTargets.begin(); it != gestureTargets.end();) {
723  if (it.value() == item)
724  it = gestureTargets.erase(it);
725  else
726  ++it;
727  }
728 
729  QGraphicsObject *dummy = static_cast<QGraphicsObject *>(item);
731  cachedItemGestures.remove(dummy);
733 
734  foreach (Qt::GestureType gesture, item->d_ptr->gestureContext.keys())
735  ungrabGesture(item, gesture);
736 #endif // QT_NO_GESTURES
737 }
738 
742 void QGraphicsScenePrivate::setActivePanelHelper(QGraphicsItem *item, bool duringActivationEvent)
743 {
745  if (item && item->scene() != q) {
746  qWarning("QGraphicsScene::setActivePanel: item %p must be part of this scene",
747  item);
748  return;
749  }
750 
751  // Ensure the scene has focus when we change panel activation.
752  q->setFocus(Qt::ActiveWindowFocusReason);
753 
754  // Find the item's panel.
755  QGraphicsItem *panel = item ? item->panel() : 0;
756  lastActivePanel = panel ? activePanel : 0;
757  if (panel == activePanel || (!q->isActive() && !duringActivationEvent))
758  return;
759 
760  // Deactivate the last active panel.
761  if (activePanel) {
762  if (QGraphicsItem *fi = activePanel->focusItem()) {
763  // Remove focus from the current focus item.
764  if (fi == q->focusItem())
765  q->setFocusItem(0, Qt::ActiveWindowFocusReason);
766  }
767 
769  q->sendEvent(activePanel, &event);
770  } else if (panel && !duringActivationEvent) {
771  // Deactivate the scene if changing activation to a panel.
773  foreach (QGraphicsItem *item, q->items()) {
774  if (item->isVisible() && !item->isPanel() && !item->parentItem())
775  q->sendEvent(item, &event);
776  }
777  }
778 
779  // Update activate state.
780  activePanel = panel;
782  QApplication::sendEvent(q, &event);
783 
784  // Activate
785  if (panel) {
787  q->sendEvent(panel, &event);
788 
789  // Set focus on the panel's focus item.
790  if (QGraphicsItem *focusItem = panel->focusItem())
792  } else if (q->isActive()) {
793  // Activate the scene
795  foreach (QGraphicsItem *item, q->items()) {
796  if (item->isVisible() && !item->isPanel() && !item->parentItem())
797  q->sendEvent(item, &event);
798  }
799  }
800 }
801 
806  Qt::FocusReason focusReason)
807 {
809  if (item == focusItem)
810  return;
811 
812  // Clear focus if asked to set focus on something that can't
813  // accept input focus.
814  if (item && (!(item->flags() & QGraphicsItem::ItemIsFocusable)
815  || !item->isVisible() || !item->isEnabled())) {
816  item = 0;
817  }
818 
819  // Set focus on the scene if an item requests focus.
820  if (item) {
821  q->setFocus(focusReason);
822  if (item == focusItem)
823  return;
824  }
825 
826  if (focusItem) {
828 
829 #ifndef QT_NO_IM
830  if (lastFocusItem
832  // Close any external input method panel. This happens
833  // automatically by removing WA_InputMethodEnabled on
834  // the views, but if we are changing focus, we have to
835  // do it ourselves.
836  for (int i = 0; i < views.size(); ++i)
837  if (views.at(i)->inputContext())
838  views.at(i)->inputContext()->reset();
839  }
840 
841  focusItem = 0;
842  QFocusEvent event(QEvent::FocusOut, focusReason);
843  sendEvent(lastFocusItem, &event);
844 #endif //QT_NO_IM
845  }
846 
847  // This handles the case that the item has been removed from the
848  // scene in response to the FocusOut event.
849  if (item && item->scene() != q)
850  item = 0;
851 
852  if (item)
853  focusItem = item;
855 
856 #ifndef QT_NO_ACCESSIBILITY
857  if (focusItem) {
858  if (QGraphicsObject *focusObj = focusItem->toGraphicsObject()) {
860  }
861  }
862 #endif
863  if (item) {
864  QFocusEvent event(QEvent::FocusIn, focusReason);
865  sendEvent(item, &event);
866  }
867 }
868 
873 {
874  Q_ASSERT(widget);
875  Q_ASSERT(!popupWidgets.contains(widget));
876  popupWidgets << widget;
877  if (QGraphicsWidget *focusWidget = widget->focusWidget()) {
878  focusWidget->setFocus(Qt::PopupFocusReason);
879  } else {
880  grabKeyboard((QGraphicsItem *)widget);
881  if (focusItem && popupWidgets.size() == 1) {
883  sendEvent(focusItem, &event);
884  }
885  }
886  grabMouse((QGraphicsItem *)widget);
887 }
888 
902 {
903  Q_ASSERT(widget);
904  int index = popupWidgets.indexOf(widget);
905  Q_ASSERT(index != -1);
906 
907  for (int i = popupWidgets.size() - 1; i >= index; --i) {
909  ungrabMouse(widget, itemIsDying);
910  if (focusItem && popupWidgets.isEmpty()) {
912  sendEvent(focusItem, &event);
913  } else if (keyboardGrabberItems.contains(static_cast<QGraphicsItem *>(widget))) {
914  ungrabKeyboard(static_cast<QGraphicsItem *>(widget), itemIsDying);
915  }
916  if (!itemIsDying && widget->isVisible()) {
917  widget->QGraphicsItem::d_ptr->setVisibleHelper(false, /* explicit = */ false);
918  }
919  }
920 }
921 
926 {
927  // Append to list of mouse grabber items, and send a mouse grab event.
928  if (mouseGrabberItems.contains(item)) {
929  if (mouseGrabberItems.last() == item) {
930  Q_ASSERT(!implicit);
932  qWarning("QGraphicsItem::grabMouse: already a mouse grabber");
933  } else {
934  // Upgrade to an explicit mouse grab
936  }
937  } else {
938  qWarning("QGraphicsItem::grabMouse: already blocked by mouse grabber: %p",
940  }
941  return;
942  }
943 
944  // Send ungrab event to the last grabber.
945  if (!mouseGrabberItems.isEmpty()) {
948  // Implicit mouse grab is immediately lost.
949  last->ungrabMouse();
950  } else {
951  // Just send ungrab event to current grabber.
952  QEvent ungrabEvent(QEvent::UngrabMouse);
953  sendEvent(last, &ungrabEvent);
954  }
955  }
956 
957  mouseGrabberItems << item;
959 
960  // Send grab event to current grabber.
961  QEvent grabEvent(QEvent::GrabMouse);
962  sendEvent(item, &grabEvent);
963 }
964 
969 {
970  int index = mouseGrabberItems.indexOf(item);
971  if (index == -1) {
972  qWarning("QGraphicsItem::ungrabMouse: not a mouse grabber");
973  return;
974  }
975 
976  if (item != mouseGrabberItems.last()) {
977  // Recursively ungrab the next mouse grabber until we reach this item
978  // to ensure state consistency.
979  ungrabMouse(mouseGrabberItems.at(index + 1), itemIsDying);
980  }
981  if (!popupWidgets.isEmpty() && item == popupWidgets.last()) {
982  // If the item is a popup, go via removePopup to ensure state
983  // consistency and that it gets hidden correctly - beware that
984  // removePopup() reenters this function to continue removing the grab.
985  removePopup((QGraphicsWidget *)item, itemIsDying);
986  return;
987  }
988 
989  // Send notification about mouse ungrab.
990  if (!itemIsDying) {
992  sendEvent(item, &event);
993  }
994 
995  // Remove the item from the list of grabbers. Whenever this happens, we
996  // reset the implicitGrab (there can be only ever be one implicit grabber
997  // in a scene, and it is always the latest grabber; if the implicit grab
998  // is lost, it is not automatically regained.
1001 
1002  // Send notification about mouse regrab. ### It's unfortunate that all the
1003  // items get a GrabMouse event, but this is a rare case with a simple
1004  // implementation and it does ensure a consistent state.
1005  if (!itemIsDying && !mouseGrabberItems.isEmpty()) {
1008  sendEvent(last, &event);
1009  }
1010 }
1011 
1016 {
1017  if (!mouseGrabberItems.isEmpty())
1020 }
1021 
1026 {
1027  if (keyboardGrabberItems.contains(item)) {
1028  if (keyboardGrabberItems.last() == item)
1029  qWarning("QGraphicsItem::grabKeyboard: already a keyboard grabber");
1030  else
1031  qWarning("QGraphicsItem::grabKeyboard: already blocked by keyboard grabber: %p",
1033  return;
1034  }
1035 
1036  // Send ungrab event to the last grabber.
1037  if (!keyboardGrabberItems.isEmpty()) {
1038  // Just send ungrab event to current grabber.
1039  QEvent ungrabEvent(QEvent::UngrabKeyboard);
1040  sendEvent(keyboardGrabberItems.last(), &ungrabEvent);
1041  }
1042 
1043  keyboardGrabberItems << item;
1044 
1045  // Send grab event to current grabber.
1046  QEvent grabEvent(QEvent::GrabKeyboard);
1047  sendEvent(item, &grabEvent);
1048 }
1049 
1054 {
1056  if (index == -1) {
1057  qWarning("QGraphicsItem::ungrabKeyboard: not a keyboard grabber");
1058  return;
1059  }
1060  if (item != keyboardGrabberItems.last()) {
1061  // Recursively ungrab the topmost keyboard grabber until we reach this
1062  // item to ensure state consistency.
1063  ungrabKeyboard(keyboardGrabberItems.at(index + 1), itemIsDying);
1064  }
1065 
1066  // Send notification about keyboard ungrab.
1067  if (!itemIsDying) {
1069  sendEvent(item, &event);
1070  }
1071 
1072  // Remove the item from the list of grabbers.
1074 
1075  // Send notification about mouse regrab.
1076  if (!itemIsDying && !keyboardGrabberItems.isEmpty()) {
1079  sendEvent(last, &event);
1080  }
1081 }
1082 
1087 {
1090 }
1091 
1093 {
1094  foreach (QGraphicsView *view, views)
1095  view->viewport()->setMouseTracking(true);
1096 }
1097 
1102  const QPointF &scenePos,
1103  QWidget *widget) const
1104 {
1105  Q_Q(const QGraphicsScene);
1106  QGraphicsView *view = widget ? qobject_cast<QGraphicsView *>(widget->parentWidget()) : 0;
1107  if (!view)
1109 
1110  const QRectF pointRect(QPointF(widget->mapFromGlobal(screenPos)), QSizeF(1, 1));
1111  if (!view->isTransformed())
1112  return q->items(pointRect, Qt::IntersectsItemShape, Qt::DescendingOrder);
1113 
1114  const QTransform viewTransform = view->viewportTransform();
1115  if (viewTransform.type() <= QTransform::TxScale) {
1116  return q->items(viewTransform.inverted().mapRect(pointRect), Qt::IntersectsItemShape,
1117  Qt::DescendingOrder, viewTransform);
1118  }
1119  return q->items(viewTransform.inverted().map(pointRect), Qt::IntersectsItemShape,
1120  Qt::DescendingOrder, viewTransform);
1121 }
1122 
1127 {
1128  for (int i = 0x1; i <= 0x10; i <<= 1) {
1129  if (event->buttons() & i) {
1132  event->widget()));
1135  }
1136  }
1137 }
1138 
1143 {
1144  sceneEventFilters.insert(watched, filter);
1145 }
1146 
1151 {
1152  if (!sceneEventFilters.contains(watched))
1153  return;
1154 
1157  do {
1158  if (it.value() == filter)
1159  it = sceneEventFilters.erase(it);
1160  else
1161  ++it;
1162  } while (it != end);
1163 }
1164 
1169 {
1171  QGraphicsItem *parent = item->parentItem();
1172  while (parent) {
1173  if (parent->d_ptr->filtersDescendantEvents && parent->sceneEventFilter(item, event))
1174  return true;
1176  return false;
1177  parent = parent->parentItem();
1178  }
1179  }
1180  return false;
1181 }
1182 
1187 {
1188  if (item && !sceneEventFilters.contains(item))
1189  return false;
1190 
1193  while (it != end) {
1194  // ### The filterer and filteree might both be deleted.
1195  if (it.value()->sceneEventFilter(it.key(), event))
1196  return true;
1197  ++it;
1198  }
1199  return false;
1200 }
1201 
1215 {
1216  if (QGraphicsObject *object = item->toGraphicsObject()) {
1217 #ifndef QT_NO_GESTURES
1219  if (gestureManager) {
1220  if (gestureManager->filterEvent(object, event))
1221  return true;
1222  }
1223 #endif // QT_NO_GESTURES
1224  }
1225 
1226  if (filterEvent(item, event))
1227  return false;
1228  if (filterDescendantEvent(item, event))
1229  return false;
1230  if (!item || !item->isEnabled())
1231  return false;
1232  if (QGraphicsObject *o = item->toGraphicsObject()) {
1233  bool spont = event->spontaneous();
1234  if (spont ? qt_sendSpontaneousEvent(o, event) : QApplication::sendEvent(o, event))
1235  return true;
1236  event->spont = spont;
1237  }
1238  return item->sceneEvent(event);
1239 }
1240 
1246 {
1247  dest->setWidget(source->widget());
1248  dest->setPos(source->pos());
1249  dest->setScenePos(source->scenePos());
1250  dest->setScreenPos(source->screenPos());
1251  dest->setButtons(source->buttons());
1252  dest->setModifiers(source->modifiers());
1253  dest->setPossibleActions(source->possibleActions());
1254  dest->setProposedAction(source->proposedAction());
1255  dest->setDropAction(source->dropAction());
1256  dest->setSource(source->source());
1257  dest->setMimeData(source->mimeData());
1258 }
1259 
1264  QGraphicsSceneDragDropEvent *dragDropEvent)
1265 {
1266  dragDropEvent->setPos(item->d_ptr->genericMapFromScene(dragDropEvent->scenePos(), dragDropEvent->widget()));
1267  sendEvent(item, dragDropEvent);
1268 }
1269 
1274  QGraphicsSceneHoverEvent *hoverEvent)
1275 {
1277  event.setWidget(hoverEvent->widget());
1278  event.setPos(item->d_ptr->genericMapFromScene(hoverEvent->scenePos(), hoverEvent->widget()));
1279  event.setScenePos(hoverEvent->scenePos());
1280  event.setScreenPos(hoverEvent->screenPos());
1281  event.setLastPos(item->d_ptr->genericMapFromScene(hoverEvent->lastScenePos(), hoverEvent->widget()));
1282  event.setLastScenePos(hoverEvent->lastScenePos());
1283  event.setLastScreenPos(hoverEvent->lastScreenPos());
1284  event.setModifiers(hoverEvent->modifiers());
1285  sendEvent(item, &event);
1286 }
1287 
1292 {
1293  if (mouseEvent->button() == 0 && mouseEvent->buttons() == 0 && lastMouseGrabberItemHasImplicitMouseGrab) {
1294  // ### This is a temporary fix for until we get proper mouse
1295  // grab events.
1297  return;
1298  }
1299 
1301  if (item->isBlockedByModalPanel())
1302  return;
1303 
1304  for (int i = 0x1; i <= 0x10; i <<= 1) {
1305  Qt::MouseButton button = Qt::MouseButton(i);
1306  mouseEvent->setButtonDownPos(button, mouseGrabberButtonDownPos.value(button, item->d_ptr->genericMapFromScene(mouseEvent->scenePos(), mouseEvent->widget())));
1307  mouseEvent->setButtonDownScenePos(button, mouseGrabberButtonDownScenePos.value(button, mouseEvent->scenePos()));
1308  mouseEvent->setButtonDownScreenPos(button, mouseGrabberButtonDownScreenPos.value(button, mouseEvent->screenPos()));
1309  }
1310  mouseEvent->setPos(item->d_ptr->genericMapFromScene(mouseEvent->scenePos(), mouseEvent->widget()));
1311  mouseEvent->setLastPos(item->d_ptr->genericMapFromScene(mouseEvent->lastScenePos(), mouseEvent->widget()));
1312  sendEvent(item, mouseEvent);
1313 }
1314 
1319 {
1321 
1322  // Ignore by default, unless we find a mouse grabber that accepts it.
1323  mouseEvent->ignore();
1324 
1325  // Deliver to any existing mouse grabber.
1326  if (!mouseGrabberItems.isEmpty()) {
1328  return;
1329  // The event is ignored by default, but we disregard the event's
1330  // accepted state after delivery; the mouse is grabbed, after all.
1331  sendMouseEvent(mouseEvent);
1332  return;
1333  }
1334 
1335  // Start by determining the number of items at the current position.
1336  // Reuse value from earlier calculations if possible.
1339  mouseEvent->scenePos(),
1340  mouseEvent->widget());
1341  }
1342 
1343  // Update window activation.
1345  QGraphicsWidget *newActiveWindow = topItem ? topItem->window() : 0;
1346  if (newActiveWindow && newActiveWindow->isBlockedByModalPanel(&topItem)) {
1347  // pass activation to the blocking modal window
1348  newActiveWindow = topItem ? topItem->window() : 0;
1349  }
1350 
1351  if (newActiveWindow != q->activeWindow())
1352  q->setActiveWindow(newActiveWindow);
1353 
1354  // Set focus on the topmost enabled item that can take focus.
1355  bool setFocus = false;
1356 
1357  foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
1358  if (item->isBlockedByModalPanel()
1360  // Make sure we don't clear focus.
1361  setFocus = true;
1362  break;
1363  }
1364  if (item->isEnabled() && ((item->flags() & QGraphicsItem::ItemIsFocusable))) {
1365  if (!item->isWidget() || ((QGraphicsWidget *)item)->focusPolicy() & Qt::ClickFocus) {
1366  setFocus = true;
1367  if (item != q->focusItem() && item->d_ptr->mouseSetsFocus)
1368  q->setFocusItem(item, Qt::MouseFocusReason);
1369  break;
1370  }
1371  }
1372  if (item->isPanel())
1373  break;
1375  break;
1376  }
1377 
1378  // Check for scene modality.
1379  bool sceneModality = false;
1380  for (int i = 0; i < modalPanels.size(); ++i) {
1382  sceneModality = true;
1383  break;
1384  }
1385  }
1386 
1387  // If nobody could take focus, clear it.
1388  if (!stickyFocus && !setFocus && !sceneModality)
1389  q->setFocusItem(0, Qt::MouseFocusReason);
1390 
1391  // Any item will do.
1392  if (sceneModality && cachedItemsUnderMouse.isEmpty())
1394 
1395  // Find a mouse grabber by sending mouse press events to all mouse grabber
1396  // candidates one at a time, until the event is accepted. It's accepted by
1397  // default, so the receiver has to explicitly ignore it for it to pass
1398  // through.
1399  foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
1400  if (!(item->acceptedMouseButtons() & mouseEvent->button())) {
1401  // Skip items that don't accept the event's mouse button.
1402  continue;
1403  }
1404 
1405  // Check if this item is blocked by a modal panel and deliver the mouse event to the
1406  // blocking panel instead of this item if blocked.
1407  (void) item->isBlockedByModalPanel(&item);
1408 
1409  grabMouse(item, /* implicit = */ true);
1410  mouseEvent->accept();
1411 
1412  // check if the item we are sending to are disabled (before we send the event)
1413  bool disabled = !item->isEnabled();
1414  bool isPanel = item->isPanel();
1415  if (mouseEvent->type() == QEvent::GraphicsSceneMouseDoubleClick
1417  // If this item is different from the item that received the last
1418  // mouse event, and mouseEvent is a doubleclick event, then the
1419  // event is converted to a press. Known limitation:
1420  // Triple-clicking will not generate a doubleclick, though.
1422  mousePress.spont = mouseEvent->spont;
1423  mousePress.accept();
1424  mousePress.setButton(mouseEvent->button());
1425  mousePress.setButtons(mouseEvent->buttons());
1426  mousePress.setScreenPos(mouseEvent->screenPos());
1427  mousePress.setScenePos(mouseEvent->scenePos());
1428  mousePress.setModifiers(mouseEvent->modifiers());
1429  mousePress.setWidget(mouseEvent->widget());
1430  mousePress.setButtonDownPos(mouseEvent->button(),
1431  mouseEvent->buttonDownPos(mouseEvent->button()));
1432  mousePress.setButtonDownScenePos(mouseEvent->button(),
1433  mouseEvent->buttonDownScenePos(mouseEvent->button()));
1434  mousePress.setButtonDownScreenPos(mouseEvent->button(),
1435  mouseEvent->buttonDownScreenPos(mouseEvent->button()));
1436  sendMouseEvent(&mousePress);
1437  mouseEvent->setAccepted(mousePress.isAccepted());
1438  } else {
1439  sendMouseEvent(mouseEvent);
1440  }
1441 
1442  bool dontSendUngrabEvents = mouseGrabberItems.isEmpty() || mouseGrabberItems.last() != item;
1443  if (disabled) {
1444  ungrabMouse(item, /* itemIsDying = */ dontSendUngrabEvents);
1445  break;
1446  }
1447  if (mouseEvent->isAccepted()) {
1448  if (!mouseGrabberItems.isEmpty())
1450  lastMouseGrabberItem = item;
1451  return;
1452  }
1453  ungrabMouse(item, /* itemIsDying = */ dontSendUngrabEvents);
1454 
1455  // Don't propagate through panels.
1456  if (isPanel)
1457  break;
1458  }
1459 
1460  // Is the event still ignored? Then the mouse press goes to the scene.
1461  // Reset the mouse grabber, clear the selection, clear focus, and leave
1462  // the event ignored so that it can propagate through the originating
1463  // view.
1464  if (!mouseEvent->isAccepted()) {
1466 
1467  QGraphicsView *view = mouseEvent->widget() ? qobject_cast<QGraphicsView *>(mouseEvent->widget()->parentWidget()) : 0;
1468  bool dontClearSelection = view && view->dragMode() == QGraphicsView::ScrollHandDrag;
1469  if (!dontClearSelection) {
1470  // Clear the selection if the originating view isn't in scroll
1471  // hand drag mode. The view will clear the selection if no drag
1472  // happened.
1473  q->clearSelection();
1474  }
1475  }
1476 }
1477 
1491 {
1496  }
1499  for (int i = 0; i < topLevelItems.size(); ++i)
1500  topLevelItems[i]->d_ptr->siblingIndex = i;
1501  }
1502 }
1503 
1514 {
1515  if (this->font == font && this->font.resolve() == font.resolve())
1516  return;
1517  updateFont(font);
1518 }
1519 
1530 {
1531  QFont naturalFont = QApplication::font();
1532  naturalFont.resolve(0);
1533  QFont resolvedFont = font.resolve(naturalFont);
1534  updateFont(resolvedFont);
1535 }
1536 
1547 {
1549 
1550  // Update local font setting.
1551  this->font = font;
1552 
1553  // Resolve the fonts of all top-level widget items, or widget items
1554  // whose parent is not a widget.
1555  foreach (QGraphicsItem *item, q->items()) {
1556  if (!item->parentItem()) {
1557  // Resolvefont for an item is a noop operation, but
1558  // every item can be a widget, or can have a widget
1559  // childre.
1560  item->d_ptr->resolveFont(font.resolve());
1561  }
1562  }
1563 
1564  // Send the scene a FontChange event.
1566  QApplication::sendEvent(q, &event);
1567 }
1568 
1579 {
1580  if (this->palette == palette && this->palette.resolve() == palette.resolve())
1581  return;
1582  updatePalette(palette);
1583 }
1584 
1595 {
1596  QPalette naturalPalette = QApplication::palette();
1597  naturalPalette.resolve(0);
1598  QPalette resolvedPalette = palette.resolve(naturalPalette);
1599  updatePalette(resolvedPalette);
1600 }
1601 
1612 {
1614 
1615  // Update local palette setting.
1616  this->palette = palette;
1617 
1618  // Resolve the palettes of all top-level widget items, or widget items
1619  // whose parent is not a widget.
1620  foreach (QGraphicsItem *item, q->items()) {
1621  if (!item->parentItem()) {
1622  // Resolvefont for an item is a noop operation, but
1623  // every item can be a widget, or can have a widget
1624  // childre.
1625  item->d_ptr->resolvePalette(palette.resolve());
1626  }
1627  }
1628 
1629  // Send the scene a PaletteChange event.
1631  QApplication::sendEvent(q, &event);
1632 }
1633 
1639  : QObject(*new QGraphicsScenePrivate, parent)
1640 {
1641  d_func()->init();
1642 }
1643 
1652  : QObject(*new QGraphicsScenePrivate, parent)
1653 {
1654  d_func()->init();
1655  setSceneRect(sceneRect);
1656 }
1657 
1667  : QObject(*new QGraphicsScenePrivate, parent)
1668 {
1669  d_func()->init();
1670  setSceneRect(x, y, width, height);
1671 }
1672 
1680 {
1682 
1683  // Remove this scene from qApp's global scene list.
1685  qApp->d_func()->scene_list.removeAll(this);
1686 
1687  clear();
1688 
1689  // Remove this scene from all associated views.
1690  for (int j = 0; j < d->views.size(); ++j)
1691  d->views.at(j)->setScene(0);
1692 }
1693 
1713 {
1714  Q_D(const QGraphicsScene);
1715  if (d->hasSceneRect)
1716  return d->sceneRect;
1717 
1718  if (d->dirtyGrowingItemsBoundingRect) {
1719  // Lazily update the growing items bounding rect
1720  QGraphicsScenePrivate *thatd = const_cast<QGraphicsScenePrivate *>(d);
1721  QRectF oldGrowingBoundingRect = thatd->growingItemsBoundingRect;
1723  thatd->dirtyGrowingItemsBoundingRect = false;
1724  if (oldGrowingBoundingRect != thatd->growingItemsBoundingRect)
1725  emit const_cast<QGraphicsScene *>(this)->sceneRectChanged(thatd->growingItemsBoundingRect);
1726  }
1727  return d->growingItemsBoundingRect;
1728 }
1730 {
1732  if (rect != d->sceneRect) {
1733  d->hasSceneRect = !rect.isNull();
1734  d->sceneRect = rect;
1735  emit sceneRectChanged(d->hasSceneRect ? rect : d->growingItemsBoundingRect);
1736  }
1737 }
1738 
1779 void QGraphicsScene::render(QPainter *painter, const QRectF &target, const QRectF &source,
1780  Qt::AspectRatioMode aspectRatioMode)
1781 {
1782  // ### Switch to using the recursive rendering algorithm instead.
1783 
1784  // Default source rect = scene rect
1785  QRectF sourceRect = source;
1786  if (sourceRect.isNull())
1787  sourceRect = sceneRect();
1788 
1789  // Default target rect = device rect
1790  QRectF targetRect = target;
1791  if (targetRect.isNull()) {
1792  if (painter->device()->devType() == QInternal::Picture)
1793  targetRect = sourceRect;
1794  else
1795  targetRect.setRect(0, 0, painter->device()->width(), painter->device()->height());
1796  }
1797 
1798  // Find the ideal x / y scaling ratio to fit \a source into \a target.
1799  qreal xratio = targetRect.width() / sourceRect.width();
1800  qreal yratio = targetRect.height() / sourceRect.height();
1801 
1802  // Scale according to the aspect ratio mode.
1803  switch (aspectRatioMode) {
1804  case Qt::KeepAspectRatio:
1805  xratio = yratio = qMin(xratio, yratio);
1806  break;
1808  xratio = yratio = qMax(xratio, yratio);
1809  break;
1810  case Qt::IgnoreAspectRatio:
1811  break;
1812  }
1813 
1814  // Find all items to draw, and reverse the list (we want to draw
1815  // in reverse order).
1817  QGraphicsItem **itemArray = new QGraphicsItem *[itemList.size()];
1818  int numItems = itemList.size();
1819  for (int i = 0; i < numItems; ++i)
1820  itemArray[numItems - i - 1] = itemList.at(i);
1821  itemList.clear();
1822 
1823  painter->save();
1824 
1825  // Transform the painter.
1826  painter->setClipRect(targetRect, Qt::IntersectClip);
1827  QTransform painterTransform;
1828  painterTransform *= QTransform()
1829  .translate(targetRect.left(), targetRect.top())
1830  .scale(xratio, yratio)
1831  .translate(-sourceRect.left(), -sourceRect.top());
1832  painter->setWorldTransform(painterTransform, true);
1833 
1834  // Two unit vectors.
1835  QLineF v1(0, 0, 1, 0);
1836  QLineF v2(0, 0, 0, 1);
1837 
1838  // Generate the style options
1839  QStyleOptionGraphicsItem *styleOptionArray = new QStyleOptionGraphicsItem[numItems];
1840  for (int i = 0; i < numItems; ++i)
1841  itemArray[i]->d_ptr->initStyleOption(&styleOptionArray[i], painterTransform, targetRect.toRect());
1842 
1843  // Render the scene.
1844  drawBackground(painter, sourceRect);
1845  drawItems(painter, numItems, itemArray, styleOptionArray);
1846  drawForeground(painter, sourceRect);
1847 
1848  delete [] itemArray;
1849  delete [] styleOptionArray;
1850 
1851  painter->restore();
1852 }
1853 
1874 {
1875  Q_D(const QGraphicsScene);
1876  return d->indexMethod;
1877 }
1879 {
1881  if (d->indexMethod == method)
1882  return;
1883 
1884  d->indexMethod = method;
1885 
1886  QList<QGraphicsItem *> oldItems = d->index->items(Qt::DescendingOrder);
1887  delete d->index;
1888  if (method == BspTreeIndex)
1889  d->index = new QGraphicsSceneBspTreeIndex(this);
1890  else
1891  d->index = new QGraphicsSceneLinearIndex(this);
1892  for (int i = oldItems.size() - 1; i >= 0; --i)
1893  d->index->addItem(oldItems.at(i));
1894 }
1895 
1931 int QGraphicsScene::bspTreeDepth() const
1932 {
1933  Q_D(const QGraphicsScene);
1935  return bspTree ? bspTree->bspTreeDepth() : 0;
1936 }
1938 {
1940  if (depth < 0) {
1941  qWarning("QGraphicsScene::setBspTreeDepth: invalid depth %d ignored; must be >= 0", depth);
1942  return;
1943  }
1944 
1946  if (!bspTree) {
1947  qWarning("QGraphicsScene::setBspTreeDepth: can not apply if indexing method is not BSP");
1948  return;
1949  }
1950  bspTree->setBspTreeDepth(depth);
1951 }
1952 
1965 {
1966  Q_D(const QGraphicsScene);
1967  return d->sortCacheEnabled;
1968 }
1970 {
1972  if (d->sortCacheEnabled == enabled)
1973  return;
1974  d->sortCacheEnabled = enabled;
1975 }
1976 
1985 {
1986  // Does not take untransformable items into account.
1988  foreach (QGraphicsItem *item, items())
1989  boundingRect |= item->sceneBoundingRect();
1990  return boundingRect;
1991 }
1992 
1999 {
2000  Q_D(const QGraphicsScene);
2001  return d->index->items(Qt::DescendingOrder);
2002 }
2003 
2011 {
2012  Q_D(const QGraphicsScene);
2013  return d->index->items(order);
2014 }
2015 
2033 {
2034  Q_D(const QGraphicsScene);
2035  return d->index->items(pos, Qt::IntersectsItemShape, Qt::DescendingOrder);
2036 }
2037 
2058 {
2059  Q_D(const QGraphicsScene);
2060  return d->index->items(rectangle, mode, Qt::DescendingOrder);
2061 }
2062 
2109 {
2110  Q_D(const QGraphicsScene);
2111  return d->index->items(polygon, mode, Qt::DescendingOrder);
2112 }
2113 
2132 {
2133  Q_D(const QGraphicsScene);
2134  return d->index->items(path, mode, Qt::DescendingOrder);
2135 }
2136 
2156  Qt::SortOrder order, const QTransform &deviceTransform) const
2157 {
2158  Q_D(const QGraphicsScene);
2159  return d->index->items(pos, mode, order, deviceTransform);
2160 }
2161 
2183  Qt::SortOrder order, const QTransform &deviceTransform) const
2184 {
2185  Q_D(const QGraphicsScene);
2186  return d->index->items(rect, mode, order, deviceTransform);
2187 }
2188 
2210  Qt::SortOrder order, const QTransform &deviceTransform) const
2211 {
2212  Q_D(const QGraphicsScene);
2213  return d->index->items(polygon, mode, order, deviceTransform);
2214 }
2215 
2237  Qt::SortOrder order, const QTransform &deviceTransform) const
2238 {
2239  Q_D(const QGraphicsScene);
2240  return d->index->items(path, mode, order, deviceTransform);
2241 }
2242 
2256  Qt::ItemSelectionMode mode) const
2257 {
2258  Q_D(const QGraphicsScene);
2259  if (!item) {
2260  qWarning("QGraphicsScene::collidingItems: cannot find collisions for null item");
2261  return QList<QGraphicsItem *>();
2262  }
2263 
2264  // Does not support ItemIgnoresTransformations.
2266  foreach (QGraphicsItem *itemInVicinity, d->index->estimateItems(item->sceneBoundingRect(), Qt::DescendingOrder)) {
2267  if (item != itemInVicinity && item->collidesWithItem(itemInVicinity, mode))
2268  tmp << itemInVicinity;
2269  }
2270  return tmp;
2271 }
2272 
2290 {
2291  QList<QGraphicsItem *> itemsAtPoint = items(position);
2292  return itemsAtPoint.isEmpty() ? 0 : itemsAtPoint.first();
2293 }
2294 
2309 QGraphicsItem *QGraphicsScene::itemAt(const QPointF &position, const QTransform &deviceTransform) const
2310 {
2311  QList<QGraphicsItem *> itemsAtPoint = items(position, Qt::IntersectsItemShape,
2312  Qt::DescendingOrder, deviceTransform);
2313  return itemsAtPoint.isEmpty() ? 0 : itemsAtPoint.first();
2314 }
2315 
2360 {
2361  Q_D(const QGraphicsScene);
2362 
2363  // Optimization: Lazily removes items that are not selected.
2364  QGraphicsScene *that = const_cast<QGraphicsScene *>(this);
2365  QSet<QGraphicsItem *> actuallySelectedSet;
2366  foreach (QGraphicsItem *item, that->d_func()->selectedItems) {
2367  if (item->isSelected())
2368  actuallySelectedSet << item;
2369  }
2370 
2371  that->d_func()->selectedItems = actuallySelectedSet;
2372 
2373  return d->selectedItems.values();
2374 }
2375 
2384 {
2385  Q_D(const QGraphicsScene);
2386  return d->selectionArea;
2387 }
2388 
2407 void QGraphicsScene::setSelectionArea(const QPainterPath &path, const QTransform &deviceTransform)
2408 {
2409  setSelectionArea(path, Qt::IntersectsItemShape, deviceTransform);
2410 }
2411 
2426 {
2428 }
2429 
2444 {
2445  setSelectionArea(path, mode, QTransform());
2446 }
2447 
2464  const QTransform &deviceTransform)
2465 {
2467 
2468  // Note: with boolean path operations, we can improve performance here
2469  // quite a lot by "growing" the old path instead of replacing it. That
2470  // allows us to only check the intersect area for changes, instead of
2471  // reevaluating the whole path over again.
2472  d->selectionArea = path;
2473 
2474  QSet<QGraphicsItem *> unselectItems = d->selectedItems;
2475 
2476  // Disable emitting selectionChanged() for individual items.
2477  ++d->selectionChanging;
2478  bool changed = false;
2479 
2480  // Set all items in path to selected.
2481  foreach (QGraphicsItem *item, items(path, mode, Qt::DescendingOrder, deviceTransform)) {
2482  if (item->flags() & QGraphicsItem::ItemIsSelectable) {
2483  if (!item->isSelected())
2484  changed = true;
2485  unselectItems.remove(item);
2486  item->setSelected(true);
2487  }
2488  }
2489 
2490  // Unselect all items outside path.
2491  foreach (QGraphicsItem *item, unselectItems) {
2492  item->setSelected(false);
2493  changed = true;
2494  }
2495 
2496  // Reenable emitting selectionChanged() for individual items.
2497  --d->selectionChanging;
2498 
2499  if (!d->selectionChanging && changed)
2501 }
2502 
2509 {
2511 
2512  // Disable emitting selectionChanged
2513  ++d->selectionChanging;
2514  bool changed = !d->selectedItems.isEmpty();
2515 
2516  foreach (QGraphicsItem *item, d->selectedItems)
2517  item->setSelected(false);
2518  d->selectedItems.clear();
2519 
2520  // Reenable emitting selectionChanged() for individual items.
2521  --d->selectionChanging;
2522 
2523  if (!d->selectionChanging && changed)
2525 }
2526 
2539 {
2541  // NB! We have to clear the index before deleting items; otherwise the
2542  // index might try to access dangling item pointers.
2543  d->index->clear();
2544  // NB! QGraphicsScenePrivate::unregisterTopLevelItem() removes items
2545  while (!d->topLevelItems.isEmpty())
2546  delete d->topLevelItems.first();
2547  Q_ASSERT(d->topLevelItems.isEmpty());
2548  d->lastItemCount = 0;
2549  d->allItemsIgnoreHoverEvents = true;
2550  d->allItemsUseDefaultCursor = true;
2551  d->allItemsIgnoreTouchEvents = true;
2552 }
2553 
2568 {
2569  // Build a list of the first item's ancestors
2570  QList<QGraphicsItem *> ancestors;
2571  int n = 0;
2572  if (!items.isEmpty()) {
2573  QGraphicsItem *parent = items.at(n++);
2574  while ((parent = parent->parentItem()))
2575  ancestors.append(parent);
2576  }
2577 
2578  // Find the common ancestor for all items
2579  QGraphicsItem *commonAncestor = 0;
2580  if (!ancestors.isEmpty()) {
2581  while (n < items.size()) {
2582  int commonIndex = -1;
2583  QGraphicsItem *parent = items.at(n++);
2584  do {
2585  int index = ancestors.indexOf(parent, qMax(0, commonIndex));
2586  if (index != -1) {
2587  commonIndex = index;
2588  break;
2589  }
2590  } while ((parent = parent->parentItem()));
2591 
2592  if (commonIndex == -1) {
2593  commonAncestor = 0;
2594  break;
2595  }
2596 
2597  commonAncestor = ancestors.at(commonIndex);
2598  }
2599  }
2600 
2601  // Create a new group at that level
2602  QGraphicsItemGroup *group = new QGraphicsItemGroup(commonAncestor);
2603  if (!commonAncestor)
2604  addItem(group);
2605  foreach (QGraphicsItem *item, items)
2606  group->addToGroup(item);
2607  return group;
2608 }
2609 
2618 {
2619  foreach (QGraphicsItem *item, group->children())
2620  group->removeFromGroup(item);
2621  removeItem(group);
2622  delete group;
2623 }
2624 
2651 {
2653  if (!item) {
2654  qWarning("QGraphicsScene::addItem: cannot add null item");
2655  return;
2656  }
2657  if (item->d_ptr->scene == this) {
2658  qWarning("QGraphicsScene::addItem: item has already been added to this scene");
2659  return;
2660  }
2661  // Remove this item from its existing scene
2662  if (QGraphicsScene *oldScene = item->d_ptr->scene)
2663  oldScene->removeItem(item);
2664 
2665  // Notify the item that its scene is changing, and allow the item to
2666  // react.
2667  const QVariant newSceneVariant(item->itemChange(QGraphicsItem::ItemSceneChange,
2668  QVariant::fromValue<QGraphicsScene *>(this)));
2669  QGraphicsScene *targetScene = qvariant_cast<QGraphicsScene *>(newSceneVariant);
2670  if (targetScene != this) {
2671  if (targetScene && item->d_ptr->scene != targetScene)
2672  targetScene->addItem(item);
2673  return;
2674  }
2675 
2676  // QDeclarativeItems do not rely on initial itemChanged message, as the componentComplete
2677  // function allows far more opportunity for delayed-construction optimization.
2678  if (!item->d_ptr->isDeclarativeItem) {
2679  if (d->unpolishedItems.isEmpty()) {
2680  QMetaMethod method = metaObject()->method(d->polishItemsIndex);
2681  method.invoke(this, Qt::QueuedConnection);
2682  }
2683  d->unpolishedItems.append(item);
2684  item->d_ptr->pendingPolish = true;
2685  }
2686 
2687  // Detach this item from its parent if the parent's scene is different
2688  // from this scene.
2689  if (QGraphicsItem *itemParent = item->d_ptr->parent) {
2690  if (itemParent->d_ptr->scene != this)
2691  item->setParentItem(0);
2692  }
2693 
2694  // Add the item to this scene
2695  item->d_func()->scene = targetScene;
2696 
2697  // Add the item in the index
2698  d->index->addItem(item);
2699 
2700  // Add to list of toplevels if this item is a toplevel.
2701  if (!item->d_ptr->parent)
2702  d->registerTopLevelItem(item);
2703 
2704  // Add to list of items that require an update. We cannot assume that the
2705  // item is fully constructed, so calling item->update() can lead to a pure
2706  // virtual function call to boundingRect().
2707  d->markDirty(item);
2708  d->dirtyGrowingItemsBoundingRect = true;
2709 
2710  // Disable selectionChanged() for individual items
2711  ++d->selectionChanging;
2712  int oldSelectedItemSize = d->selectedItems.size();
2713 
2714  // Enable mouse tracking if the item accepts hover events or has a cursor set.
2715  if (d->allItemsIgnoreHoverEvents && d->itemAcceptsHoverEvents_helper(item)) {
2716  d->allItemsIgnoreHoverEvents = false;
2717  d->enableMouseTrackingOnViews();
2718  }
2719 #ifndef QT_NO_CURSOR
2720  if (d->allItemsUseDefaultCursor && item->d_ptr->hasCursor) {
2721  d->allItemsUseDefaultCursor = false;
2722  if (d->allItemsIgnoreHoverEvents) // already enabled otherwise
2723  d->enableMouseTrackingOnViews();
2724  }
2725 #endif //QT_NO_CURSOR
2726 
2727  // Enable touch events if the item accepts touch events.
2728  if (d->allItemsIgnoreTouchEvents && item->d_ptr->acceptTouchEvents) {
2729  d->allItemsIgnoreTouchEvents = false;
2730  d->enableTouchEventsOnViews();
2731  }
2732 
2733 #ifndef QT_NO_GESTURES
2734  foreach (Qt::GestureType gesture, item->d_ptr->gestureContext.keys())
2735  d->grabGesture(item, gesture);
2736 #endif
2737 
2738  // Update selection lists
2739  if (item->isSelected())
2740  d->selectedItems << item;
2741  if (item->isWidget() && item->isVisible() && static_cast<QGraphicsWidget *>(item)->windowType() == Qt::Popup)
2742  d->addPopup(static_cast<QGraphicsWidget *>(item));
2743  if (item->isPanel() && item->isVisible() && item->panelModality() != QGraphicsItem::NonModal)
2744  d->enterModal(item);
2745 
2746  // Update creation order focus chain. Make sure to leave the widget's
2747  // internal tab order intact.
2748  if (item->isWidget()) {
2749  QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
2750  if (!d->tabFocusFirst) {
2751  // No first tab focus widget - make this the first tab focus
2752  // widget.
2753  d->tabFocusFirst = widget;
2754  } else if (!widget->parentWidget()) {
2755  // Adding a widget that is not part of a tab focus chain.
2756  QGraphicsWidget *last = d->tabFocusFirst->d_func()->focusPrev;
2757  QGraphicsWidget *lastNew = widget->d_func()->focusPrev;
2758  last->d_func()->focusNext = widget;
2759  widget->d_func()->focusPrev = last;
2760  d->tabFocusFirst->d_func()->focusPrev = lastNew;
2761  lastNew->d_func()->focusNext = d->tabFocusFirst;
2762  }
2763  }
2764 
2765  // Add all children recursively
2766  item->d_ptr->ensureSortedChildren();
2767  for (int i = 0; i < item->d_ptr->children.size(); ++i)
2768  addItem(item->d_ptr->children.at(i));
2769 
2770  // Resolve font and palette.
2771  item->d_ptr->resolveFont(d->font.resolve());
2772  item->d_ptr->resolvePalette(d->palette.resolve());
2773 
2774 
2775  // Reenable selectionChanged() for individual items
2776  --d->selectionChanging;
2777  if (!d->selectionChanging && d->selectedItems.size() != oldSelectedItemSize)
2779 
2780  // Deliver post-change notification
2781  item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant);
2782 
2783  // Update explicit activation
2784  bool autoActivate = true;
2785  if (!d->childExplicitActivation && item->d_ptr->explicitActivate)
2786  d->childExplicitActivation = item->d_ptr->wantsActive ? 1 : 2;
2787  if (d->childExplicitActivation && item->isPanel()) {
2788  if (d->childExplicitActivation == 1)
2789  setActivePanel(item);
2790  else
2791  autoActivate = false;
2792  d->childExplicitActivation = 0;
2793  } else if (!item->d_ptr->parent) {
2794  d->childExplicitActivation = 0;
2795  }
2796 
2797  // Auto-activate this item's panel if nothing else has been activated
2798  if (autoActivate) {
2799  if (!d->lastActivePanel && !d->activePanel && item->isPanel()) {
2800  if (isActive())
2801  setActivePanel(item);
2802  else
2803  d->lastActivePanel = item;
2804  }
2805  }
2806 
2808  d->registerScenePosItem(item);
2809 
2810  // Ensure that newly added items that have subfocus set, gain
2811  // focus automatically if there isn't a focus item already.
2812  if (!d->focusItem && item != d->lastFocusItem && item->focusItem() == item)
2813  item->focusItem()->setFocus();
2814 
2815  d->updateInputMethodSensitivityInViews();
2816 }
2817 
2833 QGraphicsEllipseItem *QGraphicsScene::addEllipse(const QRectF &rect, const QPen &pen, const QBrush &brush)
2834 {
2835  QGraphicsEllipseItem *item = new QGraphicsEllipseItem(rect);
2836  item->setPen(pen);
2837  item->setBrush(brush);
2838  addItem(item);
2839  return item;
2840 }
2841 
2866 {
2867  QGraphicsLineItem *item = new QGraphicsLineItem(line);
2868  item->setPen(pen);
2869  addItem(item);
2870  return item;
2871 }
2872 
2896 QGraphicsPathItem *QGraphicsScene::addPath(const QPainterPath &path, const QPen &pen, const QBrush &brush)
2897 {
2898  QGraphicsPathItem *item = new QGraphicsPathItem(path);
2899  item->setPen(pen);
2900  item->setBrush(brush);
2901  addItem(item);
2902  return item;
2903 }
2904 
2920 {
2921  QGraphicsPixmapItem *item = new QGraphicsPixmapItem(pixmap);
2922  addItem(item);
2923  return item;
2924 }
2925 
2942  const QPen &pen, const QBrush &brush)
2943 {
2944  QGraphicsPolygonItem *item = new QGraphicsPolygonItem(polygon);
2945  item->setPen(pen);
2946  item->setBrush(brush);
2947  addItem(item);
2948  return item;
2949 }
2950 
2968 QGraphicsRectItem *QGraphicsScene::addRect(const QRectF &rect, const QPen &pen, const QBrush &brush)
2969 {
2970  QGraphicsRectItem *item = new QGraphicsRectItem(rect);
2971  item->setPen(pen);
2972  item->setBrush(brush);
2973  addItem(item);
2974  return item;
2975 }
2976 
3000 {
3001  QGraphicsTextItem *item = new QGraphicsTextItem(text);
3002  item->setFont(font);
3003  addItem(item);
3004  return item;
3005 }
3006 
3022 {
3024  item->setFont(font);
3025  addItem(item);
3026  return item;
3027 }
3028 
3048 {
3049  QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget(0, wFlags);
3050  proxy->setWidget(widget);
3051  addItem(proxy);
3052  return proxy;
3053 }
3054 
3063 {
3064  // ### Refactoring: This function shares much functionality with _q_removeItemLater()
3066  if (!item) {
3067  qWarning("QGraphicsScene::removeItem: cannot remove 0-item");
3068  return;
3069  }
3070  if (item->scene() != this) {
3071  qWarning("QGraphicsScene::removeItem: item %p's scene (%p)"
3072  " is different from this scene (%p)",
3073  item, item->scene(), this);
3074  return;
3075  }
3076 
3077  // Notify the item that it's scene is changing to 0, allowing the item to
3078  // react.
3079  const QVariant newSceneVariant(item->itemChange(QGraphicsItem::ItemSceneChange,
3080  QVariant::fromValue<QGraphicsScene *>(0)));
3081  QGraphicsScene *targetScene = qvariant_cast<QGraphicsScene *>(newSceneVariant);
3082  if (targetScene != 0 && targetScene != this) {
3083  targetScene->addItem(item);
3084  return;
3085  }
3086 
3087  d->removeItemHelper(item);
3088 
3089  // Deliver post-change notification
3090  item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant);
3091 
3092  d->updateInputMethodSensitivityInViews();
3093 }
3094 
3107 {
3108  Q_D(const QGraphicsScene);
3109  return isActive() ? d->focusItem : d->passiveFocusItem;
3110 }
3111 
3129 {
3131  if (item)
3132  item->setFocus(focusReason);
3133  else
3134  d->setFocusItemHelper(item, focusReason);
3135 }
3136 
3145 {
3146  Q_D(const QGraphicsScene);
3147  return d->hasFocus;
3148 }
3149 
3161 {
3163  if (d->hasFocus || !isActive())
3164  return;
3165  QFocusEvent event(QEvent::FocusIn, focusReason);
3166  QCoreApplication::sendEvent(this, &event);
3167 }
3168 
3179 {
3181  if (d->hasFocus) {
3182  d->hasFocus = false;
3183  d->passiveFocusItem = d->focusItem;
3185  }
3186 }
3187 
3210 {
3212  d->stickyFocus = enabled;
3213 }
3214 bool QGraphicsScene::stickyFocus() const
3215 {
3216  Q_D(const QGraphicsScene);
3217  return d->stickyFocus;
3218 }
3219 
3243 {
3244  Q_D(const QGraphicsScene);
3245  return !d->mouseGrabberItems.isEmpty() ? d->mouseGrabberItems.last() : 0;
3246 }
3247 
3268 {
3269  Q_D(const QGraphicsScene);
3270  return d->backgroundBrush;
3271 }
3273 {
3275  d->backgroundBrush = brush;
3276  foreach (QGraphicsView *view, d->views) {
3277  view->resetCachedContent();
3278  view->viewport()->update();
3279  }
3280  update();
3281 }
3282 
3307 {
3308  Q_D(const QGraphicsScene);
3309  return d->foregroundBrush;
3310 }
3312 {
3314  d->foregroundBrush = brush;
3315  foreach (QGraphicsView *view, views())
3316  view->viewport()->update();
3317  update();
3318 }
3319 
3330 {
3331  Q_D(const QGraphicsScene);
3332  if (!d->focusItem || !(d->focusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod))
3333  return QVariant();
3334  const QTransform matrix = d->focusItem->sceneTransform();
3335  QVariant value = d->focusItem->inputMethodQuery(query);
3336  if (value.type() == QVariant::RectF)
3337  value = matrix.mapRect(value.toRectF());
3338  else if (value.type() == QVariant::PointF)
3339  value = matrix.map(value.toPointF());
3340  else if (value.type() == QVariant::Rect)
3341  value = matrix.mapRect(value.toRect());
3342  else if (value.type() == QVariant::Point)
3343  value = matrix.map(value.toPoint());
3344  return value;
3345 }
3346 
3357 {
3359  if (d->updateAll || (rect.isEmpty() && !rect.isNull()))
3360  return;
3361 
3362  // Check if anyone's connected; if not, we can send updates directly to
3363  // the views. Otherwise or if there are no views, use old behavior.
3364  bool directUpdates = !(d->isSignalConnected(d->changedSignalIndex)) && !d->views.isEmpty();
3365  if (rect.isNull()) {
3366  d->updateAll = true;
3367  d->updatedRects.clear();
3368  if (directUpdates) {
3369  // Update all views.
3370  for (int i = 0; i < d->views.size(); ++i)
3371  d->views.at(i)->d_func()->fullUpdatePending = true;
3372  }
3373  } else {
3374  if (directUpdates) {
3375  // Update all views.
3376  for (int i = 0; i < d->views.size(); ++i) {
3377  QGraphicsView *view = d->views.at(i);
3378  if (view->isTransformed())
3379  view->d_func()->updateRectF(view->viewportTransform().mapRect(rect));
3380  else
3381  view->d_func()->updateRectF(rect);
3382  }
3383  } else {
3384  d->updatedRects << rect;
3385  }
3386  }
3387 
3388  if (!d->calledEmitUpdated) {
3389  d->calledEmitUpdated = true;
3390  QMetaObject::invokeMethod(this, "_q_emitUpdated", Qt::QueuedConnection);
3391  }
3392 }
3393 
3424 void QGraphicsScene::invalidate(const QRectF &rect, SceneLayers layers)
3425 {
3426  foreach (QGraphicsView *view, views())
3427  view->invalidateScene(rect, layers);
3428  update(rect);
3429 }
3430 
3446 {
3447  Q_D(const QGraphicsScene);
3448  return d->views;
3449 }
3450 
3462 {
3463  for (int i = 0; i < 2; ++i) {
3464  foreach (QGraphicsItem *item, items())
3465  item->advance(i);
3466  }
3467 }
3468 
3488 {
3490 
3491  switch (event->type()) {
3499  case QEvent::TouchBegin:
3500  case QEvent::TouchUpdate:
3501  case QEvent::TouchEnd:
3502  // Reset the under-mouse list to ensure that this event gets fresh
3503  // item-under-mouse data. Be careful about this list; if people delete
3504  // items from inside event handlers, this list can quickly end up
3505  // having stale pointers in it. We need to clear it before dispatching
3506  // events that use it.
3507  // ### this should only be cleared if we received a new mouse move event,
3508  // which relies on us fixing the replay mechanism in QGraphicsView.
3509  d->cachedItemsUnderMouse.clear();
3510  default:
3511  break;
3512  }
3513 
3514  switch (event->type()) {
3516  dragEnterEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
3517  break;
3519  dragMoveEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
3520  break;
3522  dragLeaveEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
3523  break;
3525  dropEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
3526  break;
3528  contextMenuEvent(static_cast<QGraphicsSceneContextMenuEvent *>(event));
3529  break;
3530  case QEvent::KeyPress:
3531  if (!d->focusItem) {
3532  QKeyEvent *k = static_cast<QKeyEvent *>(event);
3533  if (k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) {
3534  if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier?
3535  bool res = false;
3536  if (k->key() == Qt::Key_Backtab
3537  || (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier))) {
3538  res = focusNextPrevChild(false);
3539  } else if (k->key() == Qt::Key_Tab) {
3540  res = focusNextPrevChild(true);
3541  }
3542  if (!res)
3543  event->ignore();
3544  return true;
3545  }
3546  }
3547  }
3548  keyPressEvent(static_cast<QKeyEvent *>(event));
3549  break;
3550  case QEvent::KeyRelease:
3551  keyReleaseEvent(static_cast<QKeyEvent *>(event));
3552  break;
3553  case QEvent::ShortcutOverride: {
3555  while (parent) {
3556  d->sendEvent(parent, event);
3557  if (event->isAccepted())
3558  return true;
3559  parent = parent->parentItem();
3560  }
3561  }
3562  return false;
3564  {
3566  d->lastSceneMousePos = mouseEvent->scenePos();
3567  mouseMoveEvent(mouseEvent);
3568  break;
3569  }
3571  mousePressEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
3572  break;
3574  mouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
3575  break;
3577  mouseDoubleClickEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
3578  break;
3580  wheelEvent(static_cast<QGraphicsSceneWheelEvent *>(event));
3581  break;
3582  case QEvent::FocusIn:
3583  focusInEvent(static_cast<QFocusEvent *>(event));
3584  break;
3585  case QEvent::FocusOut:
3586  focusOutEvent(static_cast<QFocusEvent *>(event));
3587  break;
3591  {
3592  QGraphicsSceneHoverEvent *hoverEvent = static_cast<QGraphicsSceneHoverEvent *>(event);
3593  d->lastSceneMousePos = hoverEvent->scenePos();
3594  d->dispatchHoverEvent(hoverEvent);
3595  break;
3596  }
3597  case QEvent::Leave:
3598  // hackieshly unpacking the viewport pointer from the leave event.
3599  d->leaveScene(reinterpret_cast<QWidget *>(event->d));
3600  break;
3602  helpEvent(static_cast<QGraphicsSceneHelpEvent *>(event));
3603  break;
3604  case QEvent::InputMethod:
3605  inputMethodEvent(static_cast<QInputMethodEvent *>(event));
3606  break;
3608  if (!d->activationRefCount++) {
3609  if (d->lastActivePanel) {
3610  // Activate the last panel.
3611  d->setActivePanelHelper(d->lastActivePanel, true);
3612  } else if (d->tabFocusFirst && d->tabFocusFirst->isPanel()) {
3613  // Activate the panel of the first item in the tab focus
3614  // chain.
3615  d->setActivePanelHelper(d->tabFocusFirst, true);
3616  } else {
3617  // Activate all toplevel items.
3619  foreach (QGraphicsItem *item, items()) {
3620  if (item->isVisible() && !item->isPanel() && !item->parentItem())
3621  sendEvent(item, &event);
3622  }
3623  }
3624  }
3625  break;
3627  if (d->activationRefCount > 0)
3628  --d->activationRefCount;
3629  if (!d->activationRefCount) {
3630  if (d->activePanel) {
3631  // Deactivate the active panel (but keep it so we can
3632  // reactivate it later).
3633  QGraphicsItem *lastActivePanel = d->activePanel;
3634  d->setActivePanelHelper(0, true);
3635  d->lastActivePanel = lastActivePanel;
3636  } else {
3637  // Activate all toplevel items.
3639  foreach (QGraphicsItem *item, items()) {
3640  if (item->isVisible() && !item->isPanel() && !item->parentItem())
3641  sendEvent(item, &event);
3642  }
3643  }
3644  }
3645  break;
3647  // Resolve the existing scene font.
3648  d->resolveFont();
3649  break;
3650  }
3651  case QEvent::FontChange:
3652  // Update the entire scene when the font changes.
3653  update();
3654  break;
3656  // Resolve the existing scene palette.
3657  d->resolvePalette();
3658  break;
3659  }
3660  case QEvent::PaletteChange:
3661  // Update the entire scene when the palette changes.
3662  update();
3663  break;
3664  case QEvent::StyleChange:
3665  // Reresolve all widgets' styles. Update all top-level widgets'
3666  // geometries that do not have an explicit style set.
3667  update();
3668  break;
3669  case QEvent::TouchBegin:
3670  case QEvent::TouchUpdate:
3671  case QEvent::TouchEnd:
3672  d->touchEventHandler(static_cast<QTouchEvent *>(event));
3673  break;
3674 #ifndef QT_NO_GESTURES
3675  case QEvent::Gesture:
3677  d->gestureEventHandler(static_cast<QGestureEvent *>(event));
3678  break;
3679 #endif // QT_NO_GESTURES
3680  default:
3681  return QObject::event(event);
3682  }
3683  return true;
3684 }
3685 
3696 {
3697  if (watched != qApp)
3698  return false;
3699 
3700  switch (event->type()) {
3703  break;
3706  break;
3707  default:
3708  break;
3709  }
3710  return false;
3711 }
3712 
3723 {
3725  // Ignore by default.
3726  contextMenuEvent->ignore();
3727 
3728  // Send the event to all items at this position until one item accepts the
3729  // event.
3730  foreach (QGraphicsItem *item, d->itemsAtPosition(contextMenuEvent->screenPos(),
3731  contextMenuEvent->scenePos(),
3732  contextMenuEvent->widget())) {
3733  contextMenuEvent->setPos(item->d_ptr->genericMapFromScene(contextMenuEvent->scenePos(),
3734  contextMenuEvent->widget()));
3735  contextMenuEvent->accept();
3736  if (!d->sendEvent(item, contextMenuEvent))
3737  break;
3738 
3739  if (contextMenuEvent->isAccepted())
3740  break;
3741  }
3742 }
3743 
3755 {
3757  d->dragDropItem = 0;
3758  d->lastDropAction = Qt::IgnoreAction;
3759  event->accept();
3760 }
3761 
3770 {
3772  event->ignore();
3773 
3774  if (!d->mouseGrabberItems.isEmpty()) {
3775  // Mouse grabbers that start drag events lose the mouse grab.
3776  d->clearMouseGrabber();
3777  d->mouseGrabberButtonDownPos.clear();
3778  d->mouseGrabberButtonDownScenePos.clear();
3779  d->mouseGrabberButtonDownScreenPos.clear();
3780  }
3781 
3782  bool eventDelivered = false;
3783 
3784  // Find the topmost enabled items under the cursor. They are all
3785  // candidates for accepting drag & drop events.
3786  foreach (QGraphicsItem *item, d->itemsAtPosition(event->screenPos(),
3787  event->scenePos(),
3788  event->widget())) {
3789  if (!item->isEnabled() || !item->acceptDrops())
3790  continue;
3791 
3792  if (item != d->dragDropItem) {
3793  // Enter the new drag drop item. If it accepts the event, we send
3794  // the leave to the parent item.
3796  d->cloneDragDropEvent(&dragEnter, event);
3797  dragEnter.setDropAction(event->proposedAction());
3798  d->sendDragDropEvent(item, &dragEnter);
3799  event->setAccepted(dragEnter.isAccepted());
3800  event->setDropAction(dragEnter.dropAction());
3801  if (!event->isAccepted()) {
3802  // Propagate to the item under
3803  continue;
3804  }
3805 
3806  d->lastDropAction = event->dropAction();
3807 
3808  if (d->dragDropItem) {
3809  // Leave the last drag drop item. A perfect implementation
3810  // would set the position of this event to the point where
3811  // this event and the last event intersect with the item's
3812  // shape, but that's not easy to do. :-)
3814  d->cloneDragDropEvent(&dragLeave, event);
3815  d->sendDragDropEvent(d->dragDropItem, &dragLeave);
3816  }
3817 
3818  // We've got a new drag & drop item
3819  d->dragDropItem = item;
3820  }
3821 
3822  // Send the move event.
3823  event->setDropAction(d->lastDropAction);
3824  event->accept();
3825  d->sendDragDropEvent(item, event);
3826  if (event->isAccepted())
3827  d->lastDropAction = event->dropAction();
3828  eventDelivered = true;
3829  break;
3830  }
3831 
3832  if (!eventDelivered) {
3833  if (d->dragDropItem) {
3834  // Leave the last drag drop item
3836  d->cloneDragDropEvent(&dragLeave, event);
3837  d->sendDragDropEvent(d->dragDropItem, &dragLeave);
3838  d->dragDropItem = 0;
3839  }
3840  // Propagate
3841  event->setDropAction(Qt::IgnoreAction);
3842  }
3843 }
3844 
3853 {
3855  if (d->dragDropItem) {
3856  // Leave the last drag drop item
3857  d->sendDragDropEvent(d->dragDropItem, event);
3858  d->dragDropItem = 0;
3859  }
3860 }
3861 
3870 {
3871  Q_UNUSED(event);
3873  if (d->dragDropItem) {
3874  // Drop on the last drag drop item
3875  d->sendDragDropEvent(d->dragDropItem, event);
3876  d->dragDropItem = 0;
3877  }
3878 }
3879 
3890 {
3892 
3893  d->hasFocus = true;
3894  switch (focusEvent->reason()) {
3895  case Qt::TabFocusReason:
3896  if (!focusNextPrevChild(true))
3897  focusEvent->ignore();
3898  break;
3900  if (!focusNextPrevChild(false))
3901  focusEvent->ignore();
3902  break;
3903  default:
3904  if (d->passiveFocusItem) {
3905  // Set focus on the last focus item
3906  setFocusItem(d->passiveFocusItem, focusEvent->reason());
3907  }
3908  break;
3909  }
3910 }
3911 
3922 {
3924  d->hasFocus = false;
3925  d->passiveFocusItem = d->focusItem;
3926  setFocusItem(0, focusEvent->reason());
3927 
3928  // Remove all popups when the scene loses focus.
3929  if (!d->popupWidgets.isEmpty())
3930  d->removePopup(d->popupWidgets.first());
3931 }
3932 
3947 {
3948 #ifdef QT_NO_TOOLTIP
3949  Q_UNUSED(helpEvent);
3950 #else
3951  // Find the first item that does tooltips
3953  QList<QGraphicsItem *> itemsAtPos = d->itemsAtPosition(helpEvent->screenPos(),
3954  helpEvent->scenePos(),
3955  helpEvent->widget());
3956  QGraphicsItem *toolTipItem = 0;
3957  for (int i = 0; i < itemsAtPos.size(); ++i) {
3958  QGraphicsItem *tmp = itemsAtPos.at(i);
3959  if (tmp->d_func()->isProxyWidget()) {
3960  // if the item is a proxy widget, the event is forwarded to it
3961  sendEvent(tmp, helpEvent);
3962  if (helpEvent->isAccepted())
3963  return;
3964  }
3965  if (!tmp->toolTip().isEmpty()) {
3966  toolTipItem = tmp;
3967  break;
3968  }
3969  }
3970 
3971  // Show or hide the tooltip
3972  QString text;
3973  QPoint point;
3974  if (toolTipItem && !toolTipItem->toolTip().isEmpty()) {
3975  text = toolTipItem->toolTip();
3976  point = helpEvent->screenPos();
3977  }
3978  QToolTip::showText(point, text, helpEvent->widget());
3979  helpEvent->setAccepted(!text.isEmpty());
3980 #endif
3981 }
3982 
3984 {
3985  return (item->d_ptr->acceptsHover
3986  || (item->d_ptr->isWidget
3987  && static_cast<const QGraphicsWidget *>(item)->d_func()->hasDecoration()))
3988  && !item->isBlockedByModalPanel();
3989 }
3990 
4000 {
4001  if (allItemsIgnoreHoverEvents)
4002  return false;
4003 
4004  // Find the first item that accepts hover events, reusing earlier
4005  // calculated data is possible.
4006  if (cachedItemsUnderMouse.isEmpty()) {
4007  cachedItemsUnderMouse = itemsAtPosition(hoverEvent->screenPos(),
4008  hoverEvent->scenePos(),
4009  hoverEvent->widget());
4010  }
4011 
4012  QGraphicsItem *item = 0;
4013  for (int i = 0; i < cachedItemsUnderMouse.size(); ++i) {
4014  QGraphicsItem *tmp = cachedItemsUnderMouse.at(i);
4015  if (itemAcceptsHoverEvents_helper(tmp)) {
4016  item = tmp;
4017  break;
4018  }
4019  }
4020 
4021  // Find the common ancestor item for the new topmost hoverItem and the
4022  // last item in the hoverItem list.
4023  QGraphicsItem *commonAncestorItem = (item && !hoverItems.isEmpty()) ? item->commonAncestorItem(hoverItems.last()) : 0;
4024  while (commonAncestorItem && !itemAcceptsHoverEvents_helper(commonAncestorItem))
4025  commonAncestorItem = commonAncestorItem->parentItem();
4026  if (commonAncestorItem && commonAncestorItem->panel() != item->panel()) {
4027  // The common ancestor isn't in the same panel as the two hovered
4028  // items.
4029  commonAncestorItem = 0;
4030  }
4031 
4032  // Check if the common ancestor item is known.
4033  int index = commonAncestorItem ? hoverItems.indexOf(commonAncestorItem) : -1;
4034  // Send hover leaves to any existing hovered children of the common
4035  // ancestor item.
4036  for (int i = hoverItems.size() - 1; i > index; --i) {
4037  QGraphicsItem *lastItem = hoverItems.takeLast();
4038  if (itemAcceptsHoverEvents_helper(lastItem))
4039  sendHoverEvent(QEvent::GraphicsSceneHoverLeave, lastItem, hoverEvent);
4040  }
4041 
4042  // Item is a child of a known item. Generate enter events for the
4043  // missing links.
4044  QList<QGraphicsItem *> parents;
4045  QGraphicsItem *parent = item;
4046  while (parent && parent != commonAncestorItem) {
4047  parents.prepend(parent);
4048  if (parent->isPanel()) {
4049  // Stop at the panel - we don't deliver beyond this point.
4050  break;
4051  }
4052  parent = parent->parentItem();
4053  }
4054  for (int i = 0; i < parents.size(); ++i) {
4055  parent = parents.at(i);
4056  hoverItems << parent;
4057  if (itemAcceptsHoverEvents_helper(parent))
4058  sendHoverEvent(QEvent::GraphicsSceneHoverEnter, parent, hoverEvent);
4059  }
4060 
4061  // Generate a move event for the item itself
4062  if (item
4063  && !hoverItems.isEmpty()
4064  && item == hoverItems.last()) {
4065  sendHoverEvent(QEvent::GraphicsSceneHoverMove, item, hoverEvent);
4066  return true;
4067  }
4068  return false;
4069 }
4070 
4081 {
4082 #ifndef QT_NO_TOOLTIP
4084 #endif
4085  QGraphicsView *view = qobject_cast<QGraphicsView *>(viewport->parent());
4086  // Send HoverLeave events to all existing hover items, topmost first.
4087  QGraphicsSceneHoverEvent hoverEvent;
4088  hoverEvent.setWidget(viewport);
4089 
4090  if (view) {
4091  QPoint cursorPos = QCursor::pos();
4092  hoverEvent.setScenePos(view->mapToScene(viewport->mapFromGlobal(cursorPos)));
4093  hoverEvent.setLastScenePos(hoverEvent.scenePos());
4094  hoverEvent.setScreenPos(cursorPos);
4095  hoverEvent.setLastScreenPos(hoverEvent.screenPos());
4096  }
4097 
4098  while (!hoverItems.isEmpty()) {
4099  QGraphicsItem *lastItem = hoverItems.takeLast();
4100  if (itemAcceptsHoverEvents_helper(lastItem))
4101  sendHoverEvent(QEvent::GraphicsSceneHoverLeave, lastItem, &hoverEvent);
4102  }
4103 }
4104 
4113 {
4114  // ### Merge this function with keyReleaseEvent; they are identical
4115  // ### (except this comment).
4117  QGraphicsItem *item = !d->keyboardGrabberItems.isEmpty() ? d->keyboardGrabberItems.last() : 0;
4118  if (!item)
4119  item = focusItem();
4120  if (item) {
4121  QGraphicsItem *p = item;
4122  do {
4123  // Accept the event by default
4124  keyEvent->accept();
4125  // Send it; QGraphicsItem::keyPressEvent ignores it. If the event
4126  // is filtered out, stop propagating it.
4127  if (p->isBlockedByModalPanel())
4128  break;
4129  if (!d->sendEvent(p, keyEvent))
4130  break;
4131  } while (!keyEvent->isAccepted() && !p->isPanel() && (p = p->parentItem()));
4132  } else {
4133  keyEvent->ignore();
4134  }
4135 }
4136 
4145 {
4146  // ### Merge this function with keyPressEvent; they are identical (except
4147  // ### this comment).
4149  QGraphicsItem *item = !d->keyboardGrabberItems.isEmpty() ? d->keyboardGrabberItems.last() : 0;
4150  if (!item)
4151  item = focusItem();
4152  if (item) {
4153  QGraphicsItem *p = item;
4154  do {
4155  // Accept the event by default
4156  keyEvent->accept();
4157  // Send it; QGraphicsItem::keyPressEvent ignores it. If the event
4158  // is filtered out, stop propagating it.
4159  if (p->isBlockedByModalPanel())
4160  break;
4161  if (!d->sendEvent(p, keyEvent))
4162  break;
4163  } while (!keyEvent->isAccepted() && !p->isPanel() && (p = p->parentItem()));
4164  } else {
4165  keyEvent->ignore();
4166  }
4167 }
4168 
4187 {
4189  if (d->mouseGrabberItems.isEmpty()) {
4190  // Dispatch hover events
4192  _q_hoverFromMouseEvent(&hover, mouseEvent);
4193  d->dispatchHoverEvent(&hover);
4194  }
4195 
4196  d->mousePressEventHandler(mouseEvent);
4197 }
4198 
4212 {
4214  if (d->mouseGrabberItems.isEmpty()) {
4215  if (mouseEvent->buttons())
4216  return;
4218  _q_hoverFromMouseEvent(&hover, mouseEvent);
4219  mouseEvent->setAccepted(d->dispatchHoverEvent(&hover));
4220  return;
4221  }
4222 
4223  // Forward the event to the mouse grabber
4224  d->sendMouseEvent(mouseEvent);
4225  mouseEvent->accept();
4226 }
4227 
4242 {
4244  if (d->mouseGrabberItems.isEmpty()) {
4245  mouseEvent->ignore();
4246  return;
4247  }
4248 
4249  // Forward the event to the mouse grabber
4250  d->sendMouseEvent(mouseEvent);
4251  mouseEvent->accept();
4252 
4253  // Reset the mouse grabber when the last mouse button has been released.
4254  if (!mouseEvent->buttons()) {
4255  if (!d->mouseGrabberItems.isEmpty()) {
4256  d->lastMouseGrabberItem = d->mouseGrabberItems.last();
4257  if (d->lastMouseGrabberItemHasImplicitMouseGrab)
4258  d->mouseGrabberItems.last()->ungrabMouse();
4259  } else {
4260  d->lastMouseGrabberItem = 0;
4261  }
4262 
4263  // Generate a hoverevent
4264  QGraphicsSceneHoverEvent hoverEvent;
4265  _q_hoverFromMouseEvent(&hoverEvent, mouseEvent);
4266  d->dispatchHoverEvent(&hoverEvent);
4267  }
4268 }
4269 
4288 {
4290  d->mousePressEventHandler(mouseEvent);
4291 }
4292 
4305 {
4307  QList<QGraphicsItem *> wheelCandidates = d->itemsAtPosition(wheelEvent->screenPos(),
4308  wheelEvent->scenePos(),
4309  wheelEvent->widget());
4310 
4311 #ifdef Q_WS_MAC
4312  // On Mac, ignore the event if the first item under the mouse is not the last opened
4313  // popup (or one of its descendant)
4314  if (!d->popupWidgets.isEmpty() && !wheelCandidates.isEmpty() && wheelCandidates.first() != d->popupWidgets.back() && !d->popupWidgets.back()->isAncestorOf(wheelCandidates.first())) {
4315  wheelEvent->accept();
4316  return;
4317  }
4318 #else
4319  // Find the first popup under the mouse (including the popup's descendants) starting from the last.
4320  // Remove all popups after the one found, or all or them if no popup is under the mouse.
4321  // Then continue with the event.
4322  QList<QGraphicsWidget *>::const_iterator iter = d->popupWidgets.end();
4323  while (--iter >= d->popupWidgets.begin() && !wheelCandidates.isEmpty()) {
4324  if (wheelCandidates.first() == *iter || (*iter)->isAncestorOf(wheelCandidates.first()))
4325  break;
4326  d->removePopup(*iter);
4327  }
4328 #endif
4329 
4330  bool hasSetFocus = false;
4331  foreach (QGraphicsItem *item, wheelCandidates) {
4332  if (!hasSetFocus && item->isEnabled()
4333  && ((item->flags() & QGraphicsItem::ItemIsFocusable) && item->d_ptr->mouseSetsFocus)) {
4334  if (item->isWidget() && static_cast<QGraphicsWidget *>(item)->focusPolicy() == Qt::WheelFocus) {
4335  hasSetFocus = true;
4336  if (item != focusItem())
4338  }
4339  }
4340 
4341  wheelEvent->setPos(item->d_ptr->genericMapFromScene(wheelEvent->scenePos(),
4342  wheelEvent->widget()));
4343  wheelEvent->accept();
4344  bool isPanel = item->isPanel();
4345  d->sendEvent(item, wheelEvent);
4346  if (isPanel || wheelEvent->isAccepted())
4347  break;
4348  }
4349 }
4350 
4362 {
4364  if (d->focusItem && (d->focusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod))
4365  d->sendEvent(d->focusItem, event);
4366 }
4367 
4382 {
4384 
4385  if (d->backgroundBrush.style() != Qt::NoBrush) {
4386  if (d->painterStateProtection)
4387  painter->save();
4388  painter->setBrushOrigin(0, 0);
4389  painter->fillRect(rect, backgroundBrush());
4390  if (d->painterStateProtection)
4391  painter->restore();
4392  }
4393 }
4394 
4409 {
4411 
4412  if (d->foregroundBrush.style() != Qt::NoBrush) {
4413  if (d->painterStateProtection)
4414  painter->save();
4415  painter->setBrushOrigin(0, 0);
4416  painter->fillRect(rect, foregroundBrush());
4417  if (d->painterStateProtection)
4418  painter->restore();
4419  }
4420 }
4421 
4422 static void _q_paintItem(QGraphicsItem *item, QPainter *painter,
4423  const QStyleOptionGraphicsItem *option, QWidget *widget,
4424  bool useWindowOpacity, bool painterStateProtection)
4425 {
4426  if (!item->isWidget()) {
4427  item->paint(painter, option, widget);
4428  return;
4429  }
4430  QGraphicsWidget *widgetItem = static_cast<QGraphicsWidget *>(item);
4431  QGraphicsProxyWidget *proxy = qobject_cast<QGraphicsProxyWidget *>(widgetItem);
4432  const qreal windowOpacity = (proxy && proxy->widget() && useWindowOpacity)
4433  ? proxy->widget()->windowOpacity() : qreal(1.0);
4434  const qreal oldPainterOpacity = painter->opacity();
4435 
4436  if (qFuzzyIsNull(windowOpacity))
4437  return;
4438  // Set new painter opacity.
4439  if (windowOpacity < 1.0)
4440  painter->setOpacity(oldPainterOpacity * windowOpacity);
4441 
4442  // set layoutdirection on the painter
4443  Qt::LayoutDirection oldLayoutDirection = painter->layoutDirection();
4444  painter->setLayoutDirection(widgetItem->layoutDirection());
4445 
4446  if (widgetItem->isWindow() && widgetItem->windowType() != Qt::Popup && widgetItem->windowType() != Qt::ToolTip
4447  && !(widgetItem->windowFlags() & Qt::FramelessWindowHint)) {
4448  if (painterStateProtection)
4449  painter->save();
4450  widgetItem->paintWindowFrame(painter, option, widget);
4451  if (painterStateProtection)
4452  painter->restore();
4453  } else if (widgetItem->autoFillBackground()) {
4454  painter->fillRect(option->exposedRect, widgetItem->palette().window());
4455  }
4456 
4457  widgetItem->paint(painter, option, widget);
4458 
4459  // Restore layoutdirection on the painter.
4460  painter->setLayoutDirection(oldLayoutDirection);
4461  // Restore painter opacity.
4462  if (windowOpacity < 1.0)
4463  painter->setOpacity(oldPainterOpacity);
4464 }
4465 
4466 static void _q_paintIntoCache(QPixmap *pix, QGraphicsItem *item, const QRegion &pixmapExposed,
4467  const QTransform &itemToPixmap, QPainter::RenderHints renderHints,
4468  const QStyleOptionGraphicsItem *option, bool painterStateProtection)
4469 {
4470  QPixmap subPix;
4471  QPainter pixmapPainter;
4472  QRect br = pixmapExposed.boundingRect();
4473 
4474  // Don't use subpixmap if we get a full update.
4475  if (pixmapExposed.isEmpty() || (pixmapExposed.rectCount() == 1 && br.contains(pix->rect()))) {
4476  pix->fill(Qt::transparent);
4477  pixmapPainter.begin(pix);
4478  } else {
4479  subPix = QPixmap(br.size());
4480  subPix.fill(Qt::transparent);
4481  pixmapPainter.begin(&subPix);
4482  pixmapPainter.translate(-br.topLeft());
4483  if (!pixmapExposed.isEmpty()) {
4484  // Applied to subPix; paint is adjusted to the coordinate space is
4485  // correct.
4486  pixmapPainter.setClipRegion(pixmapExposed);
4487  }
4488  }
4489 
4490  pixmapPainter.setRenderHints(pixmapPainter.renderHints(), false);
4491  pixmapPainter.setRenderHints(renderHints, true);
4492  pixmapPainter.setWorldTransform(itemToPixmap, true);
4493 
4494  // Render.
4495  _q_paintItem(item, &pixmapPainter, option, 0, false, painterStateProtection);
4496  pixmapPainter.end();
4497 
4498  if (!subPix.isNull()) {
4499  // Blit the subpixmap into the main pixmap.
4500  pixmapPainter.begin(pix);
4502  pixmapPainter.setClipRegion(pixmapExposed);
4503  pixmapPainter.drawPixmap(br.topLeft(), subPix);
4504  pixmapPainter.end();
4505  }
4506 }
4507 
4508 // Copied from qpaintengine_vg.cpp
4509 // Returns true for 90, 180, and 270 degree rotations.
4510 static inline bool transformIsSimple(const QTransform& transform)
4511 {
4513  if (type <= QTransform::TxScale) {
4514  return true;
4515  } else if (type == QTransform::TxRotate) {
4516  // Check for 90, and 270 degree rotations.
4517  qreal m11 = transform.m11();
4518  qreal m12 = transform.m12();
4519  qreal m21 = transform.m21();
4520  qreal m22 = transform.m22();
4521  if (m11 == 0.0f && m22 == 0.0f) {
4522  if (m12 == 1.0f && m21 == -1.0f)
4523  return true; // 90 degrees.
4524  else if (m12 == -1.0f && m21 == 1.0f)
4525  return true; // 270 degrees.
4526  else if (m12 == -1.0f && m21 == -1.0f)
4527  return true; // 90 degrees inverted y.
4528  else if (m12 == 1.0f && m21 == 1.0f)
4529  return true; // 270 degrees inverted y.
4530  }
4531  }
4532  return false;
4533 }
4534 
4544  const QStyleOptionGraphicsItem *option, QWidget *widget,
4545  bool painterStateProtection)
4546 {
4547  QGraphicsItemPrivate *itemd = item->d_ptr.data();
4549 
4550  // Render directly, using no cache.
4551  if (cacheMode == QGraphicsItem::NoCache
4552 #ifdef Q_WS_X11
4553  || !X11->use_xrender
4554 #endif
4555  ) {
4556  _q_paintItem(static_cast<QGraphicsWidget *>(item), painter, option, widget, true, painterStateProtection);
4557  return;
4558  }
4559 
4560  const qreal oldPainterOpacity = painter->opacity();
4561  qreal newPainterOpacity = oldPainterOpacity;
4562  QGraphicsProxyWidget *proxy = item->isWidget() ? qobject_cast<QGraphicsProxyWidget *>(static_cast<QGraphicsWidget *>(item)) : 0;
4563  if (proxy && proxy->widget()) {
4564  const qreal windowOpacity = proxy->widget()->windowOpacity();
4565  if (windowOpacity < 1.0)
4566  newPainterOpacity *= windowOpacity;
4567  }
4568 
4569  // Item's (local) bounding rect
4570  QRectF brect = item->boundingRect();
4571  QRectF adjustedBrect(brect);
4572  _q_adjustRect(&adjustedBrect);
4573  if (adjustedBrect.isEmpty())
4574  return;
4575 
4576  // Fetch the off-screen transparent buffer and exposed area info.
4577  QPixmapCache::Key pixmapKey;
4578  QPixmap pix;
4579  bool pixmapFound;
4580  QGraphicsItemCache *itemCache = itemd->extraItemCache();
4581  if (cacheMode == QGraphicsItem::ItemCoordinateCache) {
4582  pixmapKey = itemCache->key;
4583  } else {
4584  pixmapKey = itemCache->deviceData.value(widget).key;
4585  }
4586 
4587  // Find pixmap in cache.
4588  pixmapFound = QPixmapCache::find(pixmapKey, &pix);
4589 
4590  // Render using item coordinate cache mode.
4591  if (cacheMode == QGraphicsItem::ItemCoordinateCache) {
4592  QSize pixmapSize;
4593  bool fixedCacheSize = false;
4594  QRect br = brect.toAlignedRect();
4595  if ((fixedCacheSize = itemCache->fixedSize.isValid())) {
4596  pixmapSize = itemCache->fixedSize;
4597  } else {
4598  pixmapSize = br.size();
4599  }
4600 
4601  // Create or recreate the pixmap.
4602  int adjust = itemCache->fixedSize.isValid() ? 0 : 2;
4603  QSize adjustSize(adjust*2, adjust*2);
4604  br.adjust(-adjust, -adjust, adjust, adjust);
4605  if (pix.isNull() || (!fixedCacheSize && (pixmapSize + adjustSize) != pix.size())) {
4606  pix = QPixmap(pixmapSize + adjustSize);
4607  itemCache->boundingRect = br;
4608  itemCache->exposed.clear();
4609  itemCache->allExposed = true;
4610  } else if (itemCache->boundingRect != br) {
4611  itemCache->boundingRect = br;
4612  itemCache->exposed.clear();
4613  itemCache->allExposed = true;
4614  }
4615 
4616  // Redraw any newly exposed areas.
4617  if (itemCache->allExposed || !itemCache->exposed.isEmpty()) {
4618 
4619  //We know that we will modify the pixmap, removing it from the cache
4620  //will detach the one we have and avoid a deep copy
4621  if (pixmapFound)
4622  QPixmapCache::remove(pixmapKey);
4623 
4624  // Fit the item's bounding rect into the pixmap's coordinates.
4625  QTransform itemToPixmap;
4626  if (fixedCacheSize) {
4627  const QPointF scale(pixmapSize.width() / brect.width(), pixmapSize.height() / brect.height());
4628  itemToPixmap.scale(scale.x(), scale.y());
4629  }
4630  itemToPixmap.translate(-br.x(), -br.y());
4631 
4632  // Generate the item's exposedRect and map its list of expose
4633  // rects to device coordinates.
4634  styleOptionTmp = *option;
4635  QRegion pixmapExposed;
4636  QRectF exposedRect;
4637  if (!itemCache->allExposed) {
4638  for (int i = 0; i < itemCache->exposed.size(); ++i) {
4639  QRectF r = itemCache->exposed.at(i);
4640  exposedRect |= r;
4641  pixmapExposed += itemToPixmap.mapRect(r).toAlignedRect();
4642  }
4643  } else {
4644  exposedRect = brect;
4645  }
4646  styleOptionTmp.exposedRect = exposedRect;
4647 
4648  // Render.
4649  _q_paintIntoCache(&pix, item, pixmapExposed, itemToPixmap, painter->renderHints(),
4650  &styleOptionTmp, painterStateProtection);
4651 
4652  // insert this pixmap into the cache.
4653  itemCache->key = QPixmapCache::insert(pix);
4654 
4655  // Reset expose data.
4656  itemCache->allExposed = false;
4657  itemCache->exposed.clear();
4658  }
4659 
4660  // Redraw the exposed area using the transformed painter. Depending on
4661  // the hardware, this may be a server-side operation, or an expensive
4662  // qpixmap-image-transform-pixmap roundtrip.
4663  if (newPainterOpacity != oldPainterOpacity) {
4664  painter->setOpacity(newPainterOpacity);
4665  painter->drawPixmap(br.topLeft(), pix);
4666  painter->setOpacity(oldPainterOpacity);
4667  } else {
4668  painter->drawPixmap(br.topLeft(), pix);
4669  }
4670  return;
4671  }
4672 
4673  // Render using device coordinate cache mode.
4674  if (cacheMode == QGraphicsItem::DeviceCoordinateCache) {
4675  // Find the item's bounds in device coordinates.
4676  QRectF deviceBounds = painter->worldTransform().mapRect(brect);
4677  QRect deviceRect = deviceBounds.toRect().adjusted(-1, -1, 1, 1);
4678  if (deviceRect.isEmpty())
4679  return;
4680  QRect viewRect = widget ? widget->rect() : QRect();
4681  if (widget && !viewRect.intersects(deviceRect))
4682  return;
4683 
4684  // Resort to direct rendering if the device rect exceeds the
4685  // (optional) maximum bounds. (QGraphicsSvgItem uses this).
4686  QSize maximumCacheSize =
4688  if (!maximumCacheSize.isEmpty()
4689  && (deviceRect.width() > maximumCacheSize.width()
4690  || deviceRect.height() > maximumCacheSize.height())) {
4691  _q_paintItem(static_cast<QGraphicsWidget *>(item), painter, option, widget,
4692  oldPainterOpacity != newPainterOpacity, painterStateProtection);
4693  return;
4694  }
4695 
4696  // Create or reuse offscreen pixmap, possibly scroll/blit from the old one.
4697  // If the world transform is rotated we always recreate the cache to avoid
4698  // wrong blending.
4699  bool pixModified = false;
4700  QGraphicsItemCache::DeviceData *deviceData = &itemCache->deviceData[widget];
4701  bool invertable = true;
4702  QTransform diff = deviceData->lastTransform.inverted(&invertable);
4703  if (invertable)
4704  diff *= painter->worldTransform();
4705  deviceData->lastTransform = painter->worldTransform();
4706  bool allowPartialCacheExposure = false;
4707  bool simpleTransform = invertable && diff.type() <= QTransform::TxTranslate
4708  && transformIsSimple(painter->worldTransform());
4709  if (!simpleTransform) {
4710  pixModified = true;
4711  itemCache->allExposed = true;
4712  itemCache->exposed.clear();
4713  deviceData->cacheIndent = QPoint();
4714  pix = QPixmap();
4715  } else if (!viewRect.isNull()) {
4716  allowPartialCacheExposure = deviceData->cacheIndent != QPoint();
4717  }
4718 
4719  // Allow partial cache exposure if the device rect isn't fully contained and
4720  // deviceRect is 20% taller or wider than the viewRect.
4721  if (!allowPartialCacheExposure && !viewRect.isNull() && !viewRect.contains(deviceRect)) {
4722  allowPartialCacheExposure = (viewRect.width() * 1.2 < deviceRect.width())
4723  || (viewRect.height() * 1.2 < deviceRect.height());
4724  }
4725 
4726  QRegion scrollExposure;
4727  if (allowPartialCacheExposure) {
4728  // Part of pixmap is drawn. Either device contains viewrect (big
4729  // item covers whole screen) or parts of device are outside the
4730  // viewport. In either case the device rect must be the intersect
4731  // between the two.
4732  int dx = deviceRect.left() < viewRect.left() ? viewRect.left() - deviceRect.left() : 0;
4733  int dy = deviceRect.top() < viewRect.top() ? viewRect.top() - deviceRect.top() : 0;
4734  QPoint newCacheIndent(dx, dy);
4735  deviceRect &= viewRect;
4736 
4737  if (pix.isNull()) {
4738  deviceData->cacheIndent = QPoint();
4739  itemCache->allExposed = true;
4740  itemCache->exposed.clear();
4741  pixModified = true;
4742  }
4743 
4744  // Copy / "scroll" the old pixmap onto the new ole and calculate
4745  // scrolled exposure.
4746  if (newCacheIndent != deviceData->cacheIndent || deviceRect.size() != pix.size()) {
4747  QPoint diff = newCacheIndent - deviceData->cacheIndent;
4748  QPixmap newPix(deviceRect.size());
4749  // ### Investigate removing this fill (test with Plasma and
4750  // graphicssystem raster).
4751  newPix.fill(Qt::transparent);
4752  if (!pix.isNull()) {
4753  QPainter newPixPainter(&newPix);
4754  newPixPainter.drawPixmap(-diff, pix);
4755  newPixPainter.end();
4756  }
4757  QRegion exposed;
4758  exposed += newPix.rect();
4759  if (!pix.isNull())
4760  exposed -= QRect(-diff, pix.size());
4761  scrollExposure = exposed;
4762 
4763  pix = newPix;
4764  pixModified = true;
4765  }
4766  deviceData->cacheIndent = newCacheIndent;
4767  } else {
4768  // Full pixmap is drawn.
4769  deviceData->cacheIndent = QPoint();
4770 
4771  // Auto-adjust the pixmap size.
4772  if (deviceRect.size() != pix.size()) {
4773  // exposed needs to cover the whole pixmap
4774  pix = QPixmap(deviceRect.size());
4775  pixModified = true;
4776  itemCache->allExposed = true;
4777  itemCache->exposed.clear();
4778  }
4779  }
4780 
4781  // Check for newly invalidated areas.
4782  if (itemCache->allExposed || !itemCache->exposed.isEmpty() || !scrollExposure.isEmpty()) {
4783  //We know that we will modify the pixmap, removing it from the cache
4784  //will detach the one we have and avoid a deep copy
4785  if (pixmapFound)
4786  QPixmapCache::remove(pixmapKey);
4787 
4788  // Construct an item-to-pixmap transform.
4789  QPointF p = deviceRect.topLeft();
4790  QTransform itemToPixmap = painter->worldTransform();
4791  if (!p.isNull())
4792  itemToPixmap *= QTransform::fromTranslate(-p.x(), -p.y());
4793 
4794  // Map the item's logical expose to pixmap coordinates.
4795  QRegion pixmapExposed = scrollExposure;
4796  if (!itemCache->allExposed) {
4797  const QVector<QRectF> &exposed = itemCache->exposed;
4798  for (int i = 0; i < exposed.size(); ++i)
4799  pixmapExposed += itemToPixmap.mapRect(exposed.at(i)).toRect().adjusted(-1, -1, 1, 1);
4800  }
4801 
4802  // Calculate the style option's exposedRect.
4803  QRectF br;
4804  if (itemCache->allExposed) {
4805  br = item->boundingRect();
4806  } else {
4807  const QVector<QRectF> &exposed = itemCache->exposed;
4808  for (int i = 0; i < exposed.size(); ++i)
4809  br |= exposed.at(i);
4810  QTransform pixmapToItem = itemToPixmap.inverted();
4811  foreach (QRect r, scrollExposure.rects())
4812  br |= pixmapToItem.mapRect(r);
4813  }
4814  styleOptionTmp = *option;
4815  styleOptionTmp.exposedRect = br.adjusted(-1, -1, 1, 1);
4816 
4817  // Render the exposed areas.
4818  _q_paintIntoCache(&pix, item, pixmapExposed, itemToPixmap, painter->renderHints(),
4819  &styleOptionTmp, painterStateProtection);
4820 
4821  // Reset expose data.
4822  pixModified = true;
4823  itemCache->allExposed = false;
4824  itemCache->exposed.clear();
4825  }
4826 
4827  if (pixModified) {
4828  // Insert this pixmap into the cache.
4829  deviceData->key = QPixmapCache::insert(pix);
4830  }
4831 
4832  // Redraw the exposed area using an untransformed painter. This
4833  // effectively becomes a bitblit that does not transform the cache.
4834  QTransform restoreTransform = painter->worldTransform();
4835  painter->setWorldTransform(QTransform());
4836  if (newPainterOpacity != oldPainterOpacity) {
4837  painter->setOpacity(newPainterOpacity);
4838  painter->drawPixmap(deviceRect.topLeft(), pix);
4839  painter->setOpacity(oldPainterOpacity);
4840  } else {
4841  painter->drawPixmap(deviceRect.topLeft(), pix);
4842  }
4843  painter->setWorldTransform(restoreTransform);
4844  return;
4845  }
4846 }
4847 
4848 void QGraphicsScenePrivate::drawItems(QPainter *painter, const QTransform *const viewTransform,
4849  QRegion *exposedRegion, QWidget *widget)
4850 {
4851  // Make sure we don't have unpolished items before we draw.
4852  if (!unpolishedItems.isEmpty())
4853  _q_polishItems();
4854 
4855  updateAll = false;
4856  QRectF exposedSceneRect;
4857  if (exposedRegion && indexMethod != QGraphicsScene::NoIndex) {
4858  exposedSceneRect = exposedRegion->boundingRect().adjusted(-1, -1, 1, 1);
4859  if (viewTransform)
4860  exposedSceneRect = viewTransform->inverted().mapRect(exposedSceneRect);
4861  }
4862  const QList<QGraphicsItem *> tli = index->estimateTopLevelItems(exposedSceneRect, Qt::AscendingOrder);
4863  for (int i = 0; i < tli.size(); ++i)
4864  drawSubtreeRecursive(tli.at(i), painter, viewTransform, exposedRegion, widget);
4865 }
4866 
4868  const QTransform *const viewTransform,
4869  QRegion *exposedRegion, QWidget *widget,
4870  qreal parentOpacity, const QTransform *const effectTransform)
4871 {
4872  Q_ASSERT(item);
4873 
4874  if (!item->d_ptr->visible)
4875  return;
4876 
4877  const bool itemHasContents = !(item->d_ptr->flags & QGraphicsItem::ItemHasNoContents);
4878  const bool itemHasChildren = !item->d_ptr->children.isEmpty();
4879  if (!itemHasContents && !itemHasChildren)
4880  return; // Item has neither contents nor children!(?)
4881 
4882  const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity);
4883  const bool itemIsFullyTransparent = QGraphicsItemPrivate::isOpacityNull(opacity);
4884  if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity()))
4885  return;
4886 
4887  QTransform transform(Qt::Uninitialized);
4888  QTransform *transformPtr = 0;
4889  bool translateOnlyTransform = false;
4890 #define ENSURE_TRANSFORM_PTR \
4891  if (!transformPtr) { \
4892  Q_ASSERT(!itemIsUntransformable); \
4893  if (viewTransform) { \
4894  transform = item->d_ptr->sceneTransform; \
4895  transform *= *viewTransform; \
4896  transformPtr = &transform; \
4897  } else { \
4898  transformPtr = &item->d_ptr->sceneTransform; \
4899  translateOnlyTransform = item->d_ptr->sceneTransformTranslateOnly; \
4900  } \
4901  }
4902 
4903  // Update the item's scene transform if the item is transformable;
4904  // otherwise calculate the full transform,
4905  bool wasDirtyParentSceneTransform = false;
4906  const bool itemIsUntransformable = item->d_ptr->itemIsUntransformable();
4907  if (itemIsUntransformable) {
4908  transform = item->deviceTransform(viewTransform ? *viewTransform : QTransform());
4909  transformPtr = &transform;
4910  } else if (item->d_ptr->dirtySceneTransform) {
4913  wasDirtyParentSceneTransform = true;
4914  }
4915 
4916  const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape);
4917  bool drawItem = itemHasContents && !itemIsFullyTransparent;
4918  if (drawItem) {
4919  const QRectF brect = adjustedItemEffectiveBoundingRect(item);
4921  QRect viewBoundingRect = translateOnlyTransform ? brect.translated(transformPtr->dx(), transformPtr->dy()).toAlignedRect()
4922  : transformPtr->mapRect(brect).toAlignedRect();
4923  viewBoundingRect.adjust(-int(rectAdjust), -int(rectAdjust), rectAdjust, rectAdjust);
4924  if (widget)
4925  item->d_ptr->paintedViewBoundingRects.insert(widget, viewBoundingRect);
4926  drawItem = exposedRegion ? exposedRegion->intersects(viewBoundingRect)
4927  : !viewBoundingRect.normalized().isEmpty();
4928  if (!drawItem) {
4929  if (!itemHasChildren)
4930  return;
4931  if (itemClipsChildrenToShape) {
4932  if (wasDirtyParentSceneTransform)
4934  return;
4935  }
4936  }
4937  } // else we know for sure this item has children we must process.
4938 
4939  if (itemHasChildren && itemClipsChildrenToShape)
4941 
4942 #ifndef QT_NO_GRAPHICSEFFECT
4943  if (item->d_ptr->graphicsEffect && item->d_ptr->graphicsEffect->isEnabled()) {
4945  QGraphicsItemPaintInfo info(viewTransform, transformPtr, effectTransform, exposedRegion, widget, &styleOptionTmp,
4946  painter, opacity, wasDirtyParentSceneTransform, itemHasContents && !itemIsFullyTransparent);
4947  QGraphicsEffectSource *source = item->d_ptr->graphicsEffect->d_func()->source;
4949  (source->d_func());
4950  sourced->info = &info;
4951  const QTransform restoreTransform = painter->worldTransform();
4952  if (effectTransform)
4953  painter->setWorldTransform(*transformPtr * *effectTransform);
4954  else
4955  painter->setWorldTransform(*transformPtr);
4956  painter->setOpacity(opacity);
4957 
4959  && sourced->lastEffectTransform != painter->worldTransform())
4960  {
4962  && painter->worldTransform().type() <= QTransform::TxTranslate)
4963  {
4964  QRectF sourceRect = sourced->boundingRect(Qt::DeviceCoordinates);
4965  QRect effectRect = sourced->paddedEffectRect(Qt::DeviceCoordinates, sourced->currentCachedMode(), sourceRect);
4966 
4967  sourced->setCachedOffset(effectRect.topLeft());
4968  } else {
4970  }
4971 
4972  sourced->lastEffectTransform = painter->worldTransform();
4973  }
4974 
4975  item->d_ptr->graphicsEffect->draw(painter);
4976  painter->setWorldTransform(restoreTransform);
4977  sourced->info = 0;
4978  } else
4979 #endif //QT_NO_GRAPHICSEFFECT
4980  {
4981  draw(item, painter, viewTransform, transformPtr, exposedRegion, widget, opacity,
4982  effectTransform, wasDirtyParentSceneTransform, drawItem);
4983  }
4984 }
4985 
4986 static inline void setClip(QPainter *painter, QGraphicsItem *item)
4987 {
4988  painter->save();
4989  QRectF clipRect;
4990  const QPainterPath clipPath(item->shape());
4991  if (QPathClipper::pathToRect(clipPath, &clipRect))
4992  painter->setClipRect(clipRect, Qt::IntersectClip);
4993  else
4994  painter->setClipPath(clipPath, Qt::IntersectClip);
4995 }
4996 
4997 static inline void setWorldTransform(QPainter *painter, const QTransform *const transformPtr,
4998  const QTransform *effectTransform)
4999 {
5000  Q_ASSERT(transformPtr);
5001  if (effectTransform)
5002  painter->setWorldTransform(*transformPtr * *effectTransform);
5003  else
5004  painter->setWorldTransform(*transformPtr);
5005 }
5006 
5007 void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const QTransform *const viewTransform,
5008  const QTransform *const transformPtr, QRegion *exposedRegion, QWidget *widget,
5009  qreal opacity, const QTransform *effectTransform,
5010  bool wasDirtyParentSceneTransform, bool drawItem)
5011 {
5012  const bool itemIsFullyTransparent = QGraphicsItemPrivate::isOpacityNull(opacity);
5013  const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape);
5014  const bool itemHasChildren = !item->d_ptr->children.isEmpty();
5015  bool setChildClip = itemClipsChildrenToShape;
5016  bool itemHasChildrenStackedBehind = false;
5017 
5018  int i = 0;
5019  if (itemHasChildren) {
5020  if (itemClipsChildrenToShape)
5021  setWorldTransform(painter, transformPtr, effectTransform);
5022 
5023  item->d_ptr->ensureSortedChildren();
5024  // Items with the 'ItemStacksBehindParent' flag are put in front of the list
5025  // so all we have to do is to check the first item.
5026  itemHasChildrenStackedBehind = (item->d_ptr->children.at(0)->d_ptr->flags
5028 
5029  if (itemHasChildrenStackedBehind) {
5030  if (itemClipsChildrenToShape) {
5031  setClip(painter, item);
5032  setChildClip = false;
5033  }
5034 
5035  // Draw children behind
5036  for (i = 0; i < item->d_ptr->children.size(); ++i) {
5037  QGraphicsItem *child = item->d_ptr->children.at(i);
5038  if (wasDirtyParentSceneTransform)
5039  child->d_ptr->dirtySceneTransform = 1;
5041  break;
5042  if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
5043  continue;
5044  drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget, opacity, effectTransform);
5045  }
5046  }
5047  }
5048 
5049  // Draw item
5050  if (drawItem) {
5051  Q_ASSERT(!itemIsFullyTransparent);
5053  Q_ASSERT(transformPtr);
5054  item->d_ptr->initStyleOption(&styleOptionTmp, *transformPtr, exposedRegion
5055  ? *exposedRegion : QRegion(), exposedRegion == 0);
5056 
5057  const bool itemClipsToShape = item->d_ptr->flags & QGraphicsItem::ItemClipsToShape;
5058  bool restorePainterClip = false;
5059 
5060  if (!itemHasChildren || !itemClipsChildrenToShape) {
5061  // Item does not have children or clip children to shape.
5062  setWorldTransform(painter, transformPtr, effectTransform);
5063  if ((restorePainterClip = itemClipsToShape))
5064  setClip(painter, item);
5065  } else if (itemHasChildrenStackedBehind){
5066  // Item clips children to shape and has children stacked behind, which means
5067  // the painter is already clipped to the item's shape.
5068  if (itemClipsToShape) {
5069  // The clip is already correct. Ensure correct world transform.
5070  setWorldTransform(painter, transformPtr, effectTransform);
5071  } else {
5072  // Remove clip (this also ensures correct world transform).
5073  painter->restore();
5074  setChildClip = true;
5075  }
5076  } else if (itemClipsToShape) {
5077  // Item clips children and itself to shape. It does not have hildren stacked
5078  // behind, which means the clip has not yet been set. We set it now and re-use it
5079  // for the children.
5080  setClip(painter, item);
5081  setChildClip = false;
5082  }
5083 
5084  if (painterStateProtection && !restorePainterClip)
5085  painter->save();
5086 
5087  painter->setOpacity(opacity);
5088  if (!item->d_ptr->cacheMode && !item->d_ptr->isWidget)
5089  item->paint(painter, &styleOptionTmp, widget);
5090  else
5091  drawItemHelper(item, painter, &styleOptionTmp, widget, painterStateProtection);
5092 
5093  if (painterStateProtection || restorePainterClip)
5094  painter->restore();
5095 
5096  static int drawRect = qgetenv("QT_DRAW_SCENE_ITEM_RECTS").toInt();
5097  if (drawRect) {
5098  QPen oldPen = painter->pen();
5099  QBrush oldBrush = painter->brush();
5100  quintptr ptr = reinterpret_cast<quintptr>(item);
5101  const QColor color = QColor::fromHsv(ptr % 255, 255, 255);
5102  painter->setPen(color);
5103  painter->setBrush(Qt::NoBrush);
5104  painter->drawRect(adjustedItemBoundingRect(item));
5105  painter->setPen(oldPen);
5106  painter->setBrush(oldBrush);
5107  }
5108  }
5109 
5110  // Draw children in front
5111  if (itemHasChildren) {
5112  if (setChildClip)
5113  setClip(painter, item);
5114 
5115  for (; i < item->d_ptr->children.size(); ++i) {
5116  QGraphicsItem *child = item->d_ptr->children.at(i);
5117  if (wasDirtyParentSceneTransform)
5118  child->d_ptr->dirtySceneTransform = 1;
5119  if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
5120  continue;
5121  drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget, opacity, effectTransform);
5122  }
5123 
5124  // Restore child clip
5125  if (itemClipsChildrenToShape)
5126  painter->restore();
5127  }
5128 }
5129 
5130 void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, bool invalidateChildren,
5131  bool force, bool ignoreOpacity, bool removingItemFromScene,
5132  bool updateBoundingRect)
5133 {
5134  Q_ASSERT(item);
5135  if (updateAll)
5136  return;
5137 
5138  if (removingItemFromScene && !ignoreOpacity && !item->d_ptr->ignoreOpacity) {
5139  // If any of the item's ancestors ignore opacity, it means that the opacity
5140  // was set to 0 (and the update request has not yet been processed). That
5141  // also means that we have to ignore the opacity for the item itself; otherwise
5142  // things like: parent->setOpacity(0); scene->removeItem(child) won't work.
5143  // Note that we only do this when removing items from the scene. In all other
5144  // cases the ignoreOpacity bit propagates properly in processDirtyItems, but
5145  // since the item is removed immediately it won't be processed there.
5146  QGraphicsItem *p = item->d_ptr->parent;
5147  while (p) {
5148  if (p->d_ptr->ignoreOpacity) {
5149  item->d_ptr->ignoreOpacity = true;
5150  break;
5151  }
5152  p = p->d_ptr->parent;
5153  }
5154  }
5155 
5156  if (item->d_ptr->discardUpdateRequest(/*ignoreVisibleBit=*/force,
5157  /*ignoreDirtyBit=*/removingItemFromScene || invalidateChildren,
5158  /*ignoreOpacity=*/ignoreOpacity)) {
5159  if (item->d_ptr->dirty) {
5160  // The item is already marked as dirty and will be processed later. However,
5161  // we have to make sure ignoreVisible and ignoreOpacity are set properly;
5162  // otherwise things like: item->update(); item->hide() (force is now true)
5163  // won't work as expected.
5164  if (force)
5165  item->d_ptr->ignoreVisible = 1;
5166  if (ignoreOpacity)
5167  item->d_ptr->ignoreOpacity = 1;
5168  }
5169  return;
5170  }
5171 
5172  const bool fullItemUpdate = rect.isNull();
5173  if (!fullItemUpdate && rect.isEmpty())
5174  return;
5175 
5176  if (!processDirtyItemsEmitted) {
5177  QMetaMethod method = q_ptr->metaObject()->method(processDirtyItemsIndex);
5178  method.invoke(q_ptr, Qt::QueuedConnection);
5179 // QMetaObject::invokeMethod(q_ptr, "_q_processDirtyItems", Qt::QueuedConnection);
5180  processDirtyItemsEmitted = true;
5181  }
5182 
5183  if (removingItemFromScene) {
5184  // Note that this function can be called from the item's destructor, so
5185  // do NOT call any virtual functions on it within this block.
5186  if (isSignalConnected(changedSignalIndex) || views.isEmpty()) {
5187  // This block of code is kept for compatibility. Since 4.5, by default
5188  // QGraphicsView does not connect the signal and we use the below
5189  // method of delivering updates.
5190  q_func()->update();
5191  return;
5192  }
5193 
5194  for (int i = 0; i < views.size(); ++i) {
5195  QGraphicsViewPrivate *viewPrivate = views.at(i)->d_func();
5196  QRect rect = item->d_ptr->paintedViewBoundingRects.value(viewPrivate->viewport);
5197  rect.translate(viewPrivate->dirtyScrollOffset);
5198  viewPrivate->updateRect(rect);
5199  }
5200  return;
5201  }
5202 
5203  bool hasNoContents = item->d_ptr->flags & QGraphicsItem::ItemHasNoContents;
5204  if (!hasNoContents) {
5205  item->d_ptr->dirty = 1;
5206  if (fullItemUpdate)
5207  item->d_ptr->fullUpdatePending = 1;
5208  else if (!item->d_ptr->fullUpdatePending)
5209  item->d_ptr->needsRepaint |= rect;
5210  } else if (item->d_ptr->graphicsEffect) {
5211  invalidateChildren = true;
5212  }
5213 
5214  if (invalidateChildren) {
5215  item->d_ptr->allChildrenDirty = 1;
5216  item->d_ptr->dirtyChildren = 1;
5217  }
5218 
5219  if (force)
5220  item->d_ptr->ignoreVisible = 1;
5221  if (ignoreOpacity)
5222  item->d_ptr->ignoreOpacity = 1;
5223 
5224  if (!updateBoundingRect)
5225  item->d_ptr->markParentDirty();
5226 }
5227 
5229  const QRectF &rect, bool itemIsUntransformable)
5230 {
5231  Q_ASSERT(view);
5232  Q_ASSERT(item);
5233 
5234  QGraphicsItem *itemq = static_cast<QGraphicsItem *>(item->q_ptr);
5235  QGraphicsView *viewq = static_cast<QGraphicsView *>(view->q_ptr);
5236 
5237  if (itemIsUntransformable) {
5238  const QTransform xform = itemq->deviceTransform(viewq->viewportTransform());
5239  if (!item->hasBoundingRegionGranularity)
5240  return view->updateRectF(xform.mapRect(rect));
5241  return view->updateRegion(rect, xform);
5242  }
5243 
5244  if (item->sceneTransformTranslateOnly && view->identityMatrix) {
5245  const qreal dx = item->sceneTransform.dx();
5246  const qreal dy = item->sceneTransform.dy();
5247  QRectF r(rect);
5248  r.translate(dx - view->horizontalScroll(), dy - view->verticalScroll());
5249  return view->updateRectF(r);
5250  }
5251 
5252  if (!viewq->isTransformed()) {
5253  if (!item->hasBoundingRegionGranularity)
5254  return view->updateRectF(item->sceneTransform.mapRect(rect));
5255  return view->updateRegion(rect, item->sceneTransform);
5256  }
5257 
5258  QTransform xform = item->sceneTransform;
5259  xform *= viewq->viewportTransform();
5260  if (!item->hasBoundingRegionGranularity)
5261  return view->updateRectF(xform.mapRect(rect));
5262  return view->updateRegion(rect, xform);
5263 }
5264 
5265 void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren,
5266  qreal parentOpacity)
5267 {
5269  Q_ASSERT(item);
5270  Q_ASSERT(!updateAll);
5271 
5272  if (!item->d_ptr->dirty && !item->d_ptr->dirtyChildren) {
5273  resetDirtyItem(item);
5274  return;
5275  }
5276 
5277  const bool itemIsHidden = !item->d_ptr->ignoreVisible && !item->d_ptr->visible;
5278  if (itemIsHidden) {
5279  resetDirtyItem(item, /*recursive=*/true);
5280  return;
5281  }
5282 
5283  bool itemHasContents = !(item->d_ptr->flags & QGraphicsItem::ItemHasNoContents);
5284  const bool itemHasChildren = !item->d_ptr->children.isEmpty();
5285  if (!itemHasContents) {
5286  if (!itemHasChildren) {
5287  resetDirtyItem(item);
5288  return; // Item has neither contents nor children!(?)
5289  }
5290  if (item->d_ptr->graphicsEffect)
5291  itemHasContents = true;
5292  }
5293 
5294  const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity);
5295  const bool itemIsFullyTransparent = !item->d_ptr->ignoreOpacity
5297  if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity())) {
5298  resetDirtyItem(item, /*recursive=*/itemHasChildren);
5299  return;
5300  }
5301 
5302  bool wasDirtyParentSceneTransform = item->d_ptr->dirtySceneTransform;
5303  const bool itemIsUntransformable = item->d_ptr->itemIsUntransformable();
5304  if (wasDirtyParentSceneTransform && !itemIsUntransformable) {
5307  }
5308 
5309  const bool wasDirtyParentViewBoundingRects = item->d_ptr->paintedViewBoundingRectsNeedRepaint;
5310  if (itemIsFullyTransparent || !itemHasContents || dirtyAncestorContainsChildren) {
5311  // Make sure we don't process invisible items or items with no content.
5312  item->d_ptr->dirty = 0;
5313  item->d_ptr->fullUpdatePending = 0;
5314  // Might have a dirty view bounding rect otherwise.
5315  if (itemIsFullyTransparent || !itemHasContents)
5317  }
5318 
5319  if (!hasSceneRect && item->d_ptr->geometryChanged && item->d_ptr->visible) {
5320  // Update growingItemsBoundingRect.
5321  if (item->d_ptr->sceneTransformTranslateOnly) {
5322  growingItemsBoundingRect |= item->boundingRect().translated(item->d_ptr->sceneTransform.dx(),
5323  item->d_ptr->sceneTransform.dy());
5324  } else {
5325  growingItemsBoundingRect |= item->d_ptr->sceneTransform.mapRect(item->boundingRect());
5326  }
5327  }
5328 
5329  // Process item.
5330  if (item->d_ptr->dirty || item->d_ptr->paintedViewBoundingRectsNeedRepaint) {
5331  const bool useCompatUpdate = views.isEmpty() || isSignalConnected(changedSignalIndex);
5332  const QRectF itemBoundingRect = adjustedItemEffectiveBoundingRect(item);
5333 
5334  if (useCompatUpdate && !itemIsUntransformable && qFuzzyIsNull(item->boundingRegionGranularity())) {
5335  // This block of code is kept for compatibility. Since 4.5, by default
5336  // QGraphicsView does not connect the signal and we use the below
5337  // method of delivering updates.
5338  if (item->d_ptr->sceneTransformTranslateOnly) {
5339  q->update(itemBoundingRect.translated(item->d_ptr->sceneTransform.dx(),
5340  item->d_ptr->sceneTransform.dy()));
5341  } else {
5342  QRectF rect = item->d_ptr->sceneTransform.mapRect(itemBoundingRect);
5343  if (!rect.isEmpty())
5344  q->update(rect);
5345  }
5346  } else {
5347  QRectF dirtyRect;
5348  bool uninitializedDirtyRect = true;
5349 
5350  for (int j = 0; j < views.size(); ++j) {
5351  QGraphicsView *view = views.at(j);
5352  QGraphicsViewPrivate *viewPrivate = view->d_func();
5353  QRect &paintedViewBoundingRect = item->d_ptr->paintedViewBoundingRects[viewPrivate->viewport];
5354  if (viewPrivate->fullUpdatePending
5356  // Okay, if we have a full update pending or no viewport update, this item's
5357  // paintedViewBoundingRect will be updated correctly in the next paintEvent if
5358  // it is inside the viewport, but for now we can pretend that it is outside.
5359  paintedViewBoundingRect = QRect(-1, -1, -1, -1);
5360  continue;
5361  }
5362 
5364  paintedViewBoundingRect.translate(viewPrivate->dirtyScrollOffset);
5365  if (!viewPrivate->updateRect(paintedViewBoundingRect))
5366  paintedViewBoundingRect = QRect(-1, -1, -1, -1); // Outside viewport.
5367  }
5368 
5369  if (!item->d_ptr->dirty)
5370  continue;
5371 
5373  && paintedViewBoundingRect.x() == -1 && paintedViewBoundingRect.y() == -1
5374  && paintedViewBoundingRect.width() == -1 && paintedViewBoundingRect.height() == -1) {
5375  continue; // Outside viewport.
5376  }
5377 
5378  if (uninitializedDirtyRect) {
5379  dirtyRect = itemBoundingRect;
5380  if (!item->d_ptr->fullUpdatePending) {
5381  _q_adjustRect(&item->d_ptr->needsRepaint);
5382  dirtyRect &= item->d_ptr->needsRepaint;
5383  }
5384  uninitializedDirtyRect = false;
5385  }
5386 
5387  if (dirtyRect.isEmpty())
5388  continue; // Discard updates outside the bounding rect.
5389 
5390  if (!updateHelper(viewPrivate, item->d_ptr.data(), dirtyRect, itemIsUntransformable)
5392  paintedViewBoundingRect = QRect(-1, -1, -1, -1); // Outside viewport.
5393  }
5394  }
5395  }
5396  }
5397 
5398  // Process children.
5399  if (itemHasChildren && item->d_ptr->dirtyChildren) {
5400  const bool itemClipsChildrenToShape = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape;
5401  // Items with no content are threated as 'dummy' items which means they are never drawn and
5402  // 'processed', so the painted view bounding rect is never up-to-date. This means that whenever
5403  // such an item changes geometry, its children have to take care of the update regardless
5404  // of whether the item clips children to shape or not.
5405  const bool bypassUpdateClip = !itemHasContents && wasDirtyParentViewBoundingRects;
5406  if (itemClipsChildrenToShape && !bypassUpdateClip) {
5407  // Make sure child updates are clipped to the item's bounding rect.
5408  for (int i = 0; i < views.size(); ++i)
5409  views.at(i)->d_func()->setUpdateClip(item);
5410  }
5411  if (!dirtyAncestorContainsChildren) {
5412  dirtyAncestorContainsChildren = item->d_ptr->fullUpdatePending
5413  && itemClipsChildrenToShape;
5414  }
5415  const bool allChildrenDirty = item->d_ptr->allChildrenDirty;
5416  const bool parentIgnoresVisible = item->d_ptr->ignoreVisible;
5417  const bool parentIgnoresOpacity = item->d_ptr->ignoreOpacity;
5418  for (int i = 0; i < item->d_ptr->children.size(); ++i) {
5419  QGraphicsItem *child = item->d_ptr->children.at(i);
5420  if (wasDirtyParentSceneTransform)
5421  child->d_ptr->dirtySceneTransform = 1;
5422  if (wasDirtyParentViewBoundingRects)
5424  if (parentIgnoresVisible)
5425  child->d_ptr->ignoreVisible = 1;
5426  if (parentIgnoresOpacity)
5427  child->d_ptr->ignoreOpacity = 1;
5428  if (allChildrenDirty) {
5429  child->d_ptr->dirty = 1;
5430  child->d_ptr->fullUpdatePending = 1;
5431  child->d_ptr->dirtyChildren = 1;
5432  child->d_ptr->allChildrenDirty = 1;
5433  }
5434  processDirtyItemsRecursive(child, dirtyAncestorContainsChildren, opacity);
5435  }
5436 
5437  if (itemClipsChildrenToShape) {
5438  // Reset updateClip.
5439  for (int i = 0; i < views.size(); ++i)
5440  views.at(i)->d_func()->setUpdateClip(0);
5441  }
5442  } else if (wasDirtyParentSceneTransform) {
5444  }
5445 
5446  resetDirtyItem(item);
5447 }
5448 
5484  int numItems,
5485  QGraphicsItem *items[],
5486  const QStyleOptionGraphicsItem options[], QWidget *widget)
5487 {
5489  // Make sure we don't have unpolished items before we draw.
5490  if (!d->unpolishedItems.isEmpty())
5491  d->_q_polishItems();
5492 
5493  const qreal opacity = painter->opacity();
5494  QTransform viewTransform = painter->worldTransform();
5495  Q_UNUSED(options);
5496 
5497  // Determine view, expose and flags.
5498  QGraphicsView *view = widget ? qobject_cast<QGraphicsView *>(widget->parentWidget()) : 0;
5499  QRegion *expose = 0;
5500  const quint32 oldRectAdjust = d->rectAdjust;
5501  if (view) {
5502  d->updateAll = false;
5503  expose = &view->d_func()->exposedRegion;
5505  d->rectAdjust = 1;
5506  else
5507  d->rectAdjust = 2;
5508  }
5509 
5510  // Find all toplevels, they are already sorted.
5511  QList<QGraphicsItem *> topLevelItems;
5512  for (int i = 0; i < numItems; ++i) {
5513  QGraphicsItem *item = items[i]->topLevelItem();
5514  if (!item->d_ptr->itemDiscovered) {
5515  topLevelItems << item;
5516  item->d_ptr->itemDiscovered = 1;
5517  d->drawSubtreeRecursive(item, painter, &viewTransform, expose, widget);
5518  }
5519  }
5520 
5521  d->rectAdjust = oldRectAdjust;
5522  // Reset discovery bits.
5523  for (int i = 0; i < topLevelItems.size(); ++i)
5524  topLevelItems.at(i)->d_ptr->itemDiscovered = 0;
5525 
5526  painter->setWorldTransform(viewTransform);
5527  painter->setOpacity(opacity);
5528 }
5529 
5547 {
5549 
5550  QGraphicsItem *item = focusItem();
5551  if (item && !item->isWidget()) {
5552  // Tab out of the scene.
5553  return false;
5554  }
5555  if (!item) {
5556  if (d->lastFocusItem && !d->lastFocusItem->isWidget()) {
5557  // Restore focus to the last focusable non-widget item that had
5558  // focus.
5559  setFocusItem(d->lastFocusItem, next ? Qt::TabFocusReason : Qt::BacktabFocusReason);
5560  return true;
5561  }
5562  }
5563  if (!d->tabFocusFirst) {
5564  // No widgets...
5565  return false;
5566  }
5567 
5568  // The item must be a widget.
5569  QGraphicsWidget *widget = 0;
5570  if (!item) {
5571  widget = next ? d->tabFocusFirst : d->tabFocusFirst->d_func()->focusPrev;
5572  } else {
5573  QGraphicsWidget *test = static_cast<QGraphicsWidget *>(item);
5574  widget = next ? test->d_func()->focusNext : test->d_func()->focusPrev;
5575  if ((next && widget == d->tabFocusFirst) || (!next && widget == d->tabFocusFirst->d_func()->focusPrev))
5576  return false;
5577  }
5578  QGraphicsWidget *widgetThatHadFocus = widget;
5579 
5580  // Run around the focus chain until we find a widget that can take tab focus.
5581  do {
5582  if (widget->flags() & QGraphicsItem::ItemIsFocusable
5583  && widget->isEnabled() && widget->isVisibleTo(0)
5584  && (widget->focusPolicy() & Qt::TabFocus)
5585  && (!item || !item->isPanel() || item->isAncestorOf(widget))
5586  ) {
5588  return true;
5589  }
5590  widget = next ? widget->d_func()->focusNext : widget->d_func()->focusPrev;
5591  if ((next && widget == d->tabFocusFirst) || (!next && widget == d->tabFocusFirst->d_func()->focusPrev))
5592  return false;
5593  } while (widget != widgetThatHadFocus);
5594 
5595  return false;
5596 }
5597 
5660 {
5661  Q_D(const QGraphicsScene);
5662  // ### This function, and the use of styles in general, is non-reentrant.
5663  return d->style ? d->style : QApplication::style();
5664 }
5665 
5687 {
5689  // ### This function, and the use of styles in general, is non-reentrant.
5690  if (style == d->style)
5691  return;
5692 
5693  // Delete the old style,
5694  delete d->style;
5695  if ((d->style = style))
5696  d->style->setParent(this);
5697 
5698  // Notify the scene.
5700  QApplication::sendEvent(this, &event);
5701 
5702  // Notify all widgets that don't have a style explicitly set.
5703  foreach (QGraphicsItem *item, items()) {
5704  if (item->isWidget()) {
5705  QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
5706  if (!widget->testAttribute(Qt::WA_SetStyle))
5707  QApplication::sendEvent(widget, &event);
5708  }
5709  }
5710 }
5711 
5739 {
5740  Q_D(const QGraphicsScene);
5741  return d->font;
5742 }
5744 {
5746  QFont naturalFont = QApplication::font();
5747  naturalFont.resolve(0);
5748  QFont resolvedFont = font.resolve(naturalFont);
5749  d->setFont_helper(resolvedFont);
5750 }
5751 
5779 {
5780  Q_D(const QGraphicsScene);
5781  return d->palette;
5782 }
5784 {
5786  QPalette naturalPalette = QApplication::palette();
5787  naturalPalette.resolve(0);
5788  QPalette resolvedPalette = palette.resolve(naturalPalette);
5789  d->setPalette_helper(resolvedPalette);
5790 }
5791 
5804 {
5805  Q_D(const QGraphicsScene);
5806  return d->activationRefCount > 0;
5807 }
5808 
5819 {
5820  Q_D(const QGraphicsScene);
5821  return d->activePanel;
5822 }
5823 
5839 {
5841  d->setActivePanelHelper(item, false);
5842 }
5843 
5856 {
5857  Q_D(const QGraphicsScene);
5858  if (d->activePanel && d->activePanel->isWindow())
5859  return static_cast<QGraphicsWidget *>(d->activePanel);
5860  return 0;
5861 }
5862 
5875 {
5876  if (widget && widget->scene() != this) {
5877  qWarning("QGraphicsScene::setActiveWindow: widget %p must be part of this scene",
5878  widget);
5879  return;
5880  }
5881 
5882  // Activate the widget's panel (all windows are panels).
5883  QGraphicsItem *panel = widget ? widget->panel() : 0;
5884  setActivePanel(panel);
5885 
5886  // Raise
5887  if (panel) {
5888  QList<QGraphicsItem *> siblingWindows;
5889  QGraphicsItem *parent = panel->parentItem();
5890  // Raise ### inefficient for toplevels
5891  foreach (QGraphicsItem *sibling, parent ? parent->children() : items()) {
5892  if (sibling != panel && sibling->isWindow())
5893  siblingWindows << sibling;
5894  }
5895 
5896  // Find the highest z value.
5897  qreal z = panel->zValue();
5898  for (int i = 0; i < siblingWindows.size(); ++i)
5899  z = qMax(z, siblingWindows.at(i)->zValue());
5900 
5901  // This will probably never overflow.
5902  const qreal litt = qreal(0.001);
5903  panel->setZValue(z + litt);
5904  }
5905 }
5906 
5923 {
5925  if (!item) {
5926  qWarning("QGraphicsScene::sendEvent: cannot send event to a null item");
5927  return false;
5928  }
5929  if (item->scene() != this) {
5930  qWarning("QGraphicsScene::sendEvent: item %p's scene (%p)"
5931  " is different from this scene (%p)",
5932  item, item->scene(), this);
5933  return false;
5934  }
5935  return d->sendEvent(item, event);
5936 }
5937 
5939 {
5940  views << view;
5941 #ifndef QT_NO_GESTURES
5942  foreach (Qt::GestureType gesture, grabbedGestures.keys())
5943  view->viewport()->grabGesture(gesture);
5944 #endif
5945 }
5946 
5948 {
5949  views.removeAll(view);
5950 }
5951 
5953 {
5954  QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
5955  for (int i = 0; i < touchPoints.count(); ++i) {
5956  QTouchEvent::TouchPoint &touchPoint = touchPoints[i];
5957  touchPoint.setRect(item->mapFromScene(touchPoint.sceneRect()).boundingRect());
5958  touchPoint.setStartPos(item->d_ptr->genericMapFromScene(touchPoint.startScenePos(), touchEvent->widget()));
5959  touchPoint.setLastPos(item->d_ptr->genericMapFromScene(touchPoint.lastScenePos(), touchEvent->widget()));
5960  }
5961  touchEvent->setTouchPoints(touchPoints);
5962 }
5963 
5965 {
5966  int closestTouchPointId = -1;
5967  qreal closestDistance = qreal(0.);
5968  foreach (const QTouchEvent::TouchPoint &touchPoint, sceneCurrentTouchPoints) {
5969  qreal distance = QLineF(scenePos, touchPoint.scenePos()).length();
5970  if (closestTouchPointId == -1|| distance < closestDistance) {
5971  closestTouchPointId = touchPoint.id();
5972  closestDistance = distance;
5973  }
5974  }
5975  return closestTouchPointId;
5976 }
5977 
5979 {
5980  typedef QPair<Qt::TouchPointStates, QList<QTouchEvent::TouchPoint> > StatesAndTouchPoints;
5982 
5983  for (int i = 0; i < sceneTouchEvent->touchPoints().count(); ++i) {
5984  const QTouchEvent::TouchPoint &touchPoint = sceneTouchEvent->touchPoints().at(i);
5985 
5986  // update state
5987  QGraphicsItem *item = 0;
5988  if (touchPoint.state() == Qt::TouchPointPressed) {
5989  if (sceneTouchEvent->deviceType() == QTouchEvent::TouchPad) {
5990  // on touch-pad devices, send all touch points to the same item
5991  item = itemForTouchPointId.isEmpty()
5992  ? 0
5993  : itemForTouchPointId.constBegin().value();
5994  }
5995 
5996  if (!item) {
5997  // determine which item this touch point will go to
5998  cachedItemsUnderMouse = itemsAtPosition(touchPoint.screenPos().toPoint(),
5999  touchPoint.scenePos(),
6000  sceneTouchEvent->widget());
6001  item = cachedItemsUnderMouse.isEmpty() ? 0 : cachedItemsUnderMouse.first();
6002  }
6003 
6004  if (sceneTouchEvent->deviceType() == QTouchEvent::TouchScreen) {
6005  // on touch-screens, combine this touch point with the closest one we find
6006  int closestTouchPointId = findClosestTouchPointId(touchPoint.scenePos());
6007  QGraphicsItem *closestItem = itemForTouchPointId.value(closestTouchPointId);
6008  if (!item || (closestItem && cachedItemsUnderMouse.contains(closestItem)))
6009  item = closestItem;
6010  }
6011  if (!item)
6012  continue;
6013 
6014  itemForTouchPointId.insert(touchPoint.id(), item);
6015  sceneCurrentTouchPoints.insert(touchPoint.id(), touchPoint);
6016  } else if (touchPoint.state() == Qt::TouchPointReleased) {
6017  item = itemForTouchPointId.take(touchPoint.id());
6018  if (!item)
6019  continue;
6020 
6021  sceneCurrentTouchPoints.remove(touchPoint.id());
6022  } else {
6023  item = itemForTouchPointId.value(touchPoint.id());
6024  if (!item)
6025  continue;
6026  Q_ASSERT(sceneCurrentTouchPoints.contains(touchPoint.id()));
6027  sceneCurrentTouchPoints[touchPoint.id()] = touchPoint;
6028  }
6029 
6030  StatesAndTouchPoints &statesAndTouchPoints = itemsNeedingEvents[item];
6031  statesAndTouchPoints.first |= touchPoint.state();
6032  statesAndTouchPoints.second.append(touchPoint);
6033  }
6034 
6035  if (itemsNeedingEvents.isEmpty()) {
6036  sceneTouchEvent->accept();
6037  return;
6038  }
6039 
6040  bool ignoreSceneTouchEvent = true;
6043  for (; it != end; ++it) {
6044  QGraphicsItem *item = it.key();
6045 
6046  (void) item->isBlockedByModalPanel(&item);
6047 
6048  // determine event type from the state mask
6049  QEvent::Type eventType;
6050  switch (it.value().first) {
6051  case Qt::TouchPointPressed:
6052  // all touch points have pressed state
6053  eventType = QEvent::TouchBegin;
6054  break;
6056  // all touch points have released state
6057  eventType = QEvent::TouchEnd;
6058  break;
6060  // don't send the event if nothing changed
6061  continue;
6062  default:
6063  // all other combinations
6064  eventType = QEvent::TouchUpdate;
6065  break;
6066  }
6067 
6068  QTouchEvent touchEvent(eventType);
6069  touchEvent.setWidget(sceneTouchEvent->widget());
6070  touchEvent.setDeviceType(sceneTouchEvent->deviceType());
6071  touchEvent.setModifiers(sceneTouchEvent->modifiers());
6072  touchEvent.setTouchPointStates(it.value().first);
6073  touchEvent.setTouchPoints(it.value().second);
6074 
6075  switch (touchEvent.type()) {
6076  case QEvent::TouchBegin:
6077  {
6078  // if the TouchBegin handler recurses, we assume that means the event
6079  // has been implicitly accepted and continue to send touch events
6080  item->d_ptr->acceptedTouchBeginEvent = true;
6081  bool res = sendTouchBeginEvent(item, &touchEvent)
6082  && touchEvent.isAccepted();
6083  if (!res) {
6084  // forget about these touch points, we didn't handle them
6085  for (int i = 0; i < touchEvent.touchPoints().count(); ++i) {
6086  const QTouchEvent::TouchPoint &touchPoint = touchEvent.touchPoints().at(i);
6087  itemForTouchPointId.remove(touchPoint.id());
6088  sceneCurrentTouchPoints.remove(touchPoint.id());
6089  }
6090  ignoreSceneTouchEvent = false;
6091  }
6092  break;
6093  }
6094  default:
6095  if (item->d_ptr->acceptedTouchBeginEvent) {
6096  updateTouchPointsForItem(item, &touchEvent);
6097  (void) sendEvent(item, &touchEvent);
6098  ignoreSceneTouchEvent = false;
6099  }
6100  break;
6101  }
6102  }
6103  sceneTouchEvent->setAccepted(ignoreSceneTouchEvent);
6104 }
6105 
6107 {
6109 
6110  if (cachedItemsUnderMouse.isEmpty() || cachedItemsUnderMouse.first() != origin) {
6111  const QTouchEvent::TouchPoint &firstTouchPoint = touchEvent->touchPoints().first();
6112  cachedItemsUnderMouse = itemsAtPosition(firstTouchPoint.screenPos().toPoint(),
6113  firstTouchPoint.scenePos(),
6114  touchEvent->widget());
6115  }
6116 
6117  // Set focus on the topmost enabled item that can take focus.
6118  bool setFocus = false;
6119 
6120  foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
6121  if (item->isEnabled() && ((item->flags() & QGraphicsItem::ItemIsFocusable) && item->d_ptr->mouseSetsFocus)) {
6122  if (!item->isWidget() || ((QGraphicsWidget *)item)->focusPolicy() & Qt::ClickFocus) {
6123  setFocus = true;
6124  if (item != q->focusItem())
6125  q->setFocusItem(item, Qt::MouseFocusReason);
6126  break;
6127  }
6128  }
6129  if (item->isPanel())
6130  break;
6132  break;
6134  // Make sure we don't clear focus.
6135  setFocus = true;
6136  break;
6137  }
6138  }
6139 
6140  // If nobody could take focus, clear it.
6141  if (!stickyFocus && !setFocus)
6142  q->setFocusItem(0, Qt::MouseFocusReason);
6143 
6144  bool res = false;
6145  bool eventAccepted = touchEvent->isAccepted();
6146  foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
6147  // first, try to deliver the touch event
6148  updateTouchPointsForItem(item, touchEvent);
6149  bool acceptTouchEvents = item->acceptTouchEvents();
6150  touchEvent->setAccepted(acceptTouchEvents);
6151  res = acceptTouchEvents && sendEvent(item, touchEvent);
6152  eventAccepted = touchEvent->isAccepted();
6153  if (itemForTouchPointId.value(touchEvent->touchPoints().first().id()) == 0) {
6154  // item was deleted
6155  item = 0;
6156  } else {
6157  item->d_ptr->acceptedTouchBeginEvent = (res && eventAccepted);
6158  }
6159  touchEvent->spont = false;
6160  if (res && eventAccepted) {
6161  // the first item to accept the TouchBegin gets an implicit grab.
6162  for (int i = 0; i < touchEvent->touchPoints().count(); ++i) {
6163  const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().at(i);
6164  itemForTouchPointId[touchPoint.id()] = item; // can be zero
6165  }
6166  break;
6167  }
6168  if (item && item->isPanel())
6169  break;
6170  }
6171 
6172  touchEvent->setAccepted(eventAccepted);
6173  return res;
6174 }
6175 
6177 {
6178  foreach (QGraphicsView *view, views)
6180 }
6181 
6183 {
6184  for (int i = 0; i < views.size(); ++i)
6185  views.at(i)->d_func()->updateInputMethodSensitivity();
6186 }
6187 
6189 {
6191  Q_ASSERT(panel && panel->isPanel());
6192 
6193  QGraphicsItem::PanelModality panelModality = panel->d_ptr->panelModality;
6194  if (previousModality != QGraphicsItem::NonModal) {
6195  // the panel is changing from one modality type to another... temporarily set it back so
6196  // that blockedPanels is populated correctly
6197  panel->d_ptr->panelModality = previousModality;
6198  }
6199 
6200  QSet<QGraphicsItem *> blockedPanels;
6201  QList<QGraphicsItem *> items = q->items(); // ### store panels separately
6202  for (int i = 0; i < items.count(); ++i) {
6203  QGraphicsItem *item = items.at(i);
6204  if (item->isPanel() && item->isBlockedByModalPanel())
6205  blockedPanels.insert(item);
6206  }
6207  // blockedPanels contains all currently blocked panels
6208 
6209  if (previousModality != QGraphicsItem::NonModal) {
6210  // reset the modality to the proper value, since we changed it above
6211  panel->d_ptr->panelModality = panelModality;
6212  // remove this panel so that it will be reinserted at the front of the stack
6213  modalPanels.removeAll(panel);
6214  }
6215 
6216  modalPanels.prepend(panel);
6217 
6218  if (!hoverItems.isEmpty()) {
6219  // send GraphicsSceneHoverLeave events to newly blocked hoverItems
6220  QGraphicsSceneHoverEvent hoverEvent;
6221  hoverEvent.setScenePos(lastSceneMousePos);
6222  dispatchHoverEvent(&hoverEvent);
6223  }
6224 
6225  if (!mouseGrabberItems.isEmpty() && lastMouseGrabberItemHasImplicitMouseGrab) {
6226  QGraphicsItem *item = mouseGrabberItems.last();
6227  if (item->isBlockedByModalPanel())
6228  ungrabMouse(item, /*itemIsDying =*/ false);
6229  }
6230 
6231  QEvent windowBlockedEvent(QEvent::WindowBlocked);
6232  QEvent windowUnblockedEvent(QEvent::WindowUnblocked);
6233  for (int i = 0; i < items.count(); ++i) {
6234  QGraphicsItem *item = items.at(i);
6235  if (item->isPanel()) {
6236  if (!blockedPanels.contains(item) && item->isBlockedByModalPanel()) {
6237  // send QEvent::WindowBlocked to newly blocked panels
6238  sendEvent(item, &windowBlockedEvent);
6239  } else if (blockedPanels.contains(item) && !item->isBlockedByModalPanel()) {
6240  // send QEvent::WindowUnblocked to unblocked panels when downgrading
6241  // a panel from SceneModal to PanelModal
6242  sendEvent(item, &windowUnblockedEvent);
6243  }
6244  }
6245  }
6246 }
6247 
6249 {
6251  Q_ASSERT(panel && panel->isPanel());
6252 
6253  QSet<QGraphicsItem *> blockedPanels;
6254  QList<QGraphicsItem *> items = q->items(); // ### same as above
6255  for (int i = 0; i < items.count(); ++i) {
6256  QGraphicsItem *item = items.at(i);
6257  if (item->isPanel() && item->isBlockedByModalPanel())
6258  blockedPanels.insert(item);
6259  }
6260 
6261  modalPanels.removeAll(panel);
6262 
6264  for (int i = 0; i < items.count(); ++i) {
6265  QGraphicsItem *item = items.at(i);
6266  if (item->isPanel() && blockedPanels.contains(item) && !item->isBlockedByModalPanel())
6267  sendEvent(item, &e);
6268  }
6269 
6270  // send GraphicsSceneHoverEnter events to newly unblocked items
6271  QGraphicsSceneHoverEvent hoverEvent;
6272  hoverEvent.setScenePos(lastSceneMousePos);
6273  dispatchHoverEvent(&hoverEvent);
6274 }
6275 
6276 #ifndef QT_NO_GESTURES
6278  Qt::GestureFlag flag,
6279  QHash<QGraphicsObject *, QSet<QGesture *> > *targets,
6280  QSet<QGraphicsObject *> *itemsSet,
6281  QSet<QGesture *> *normal,
6282  QSet<QGesture *> *conflicts)
6283 {
6284  QSet<QGesture *> normalGestures; // that are not in conflicted state.
6285  foreach (QGesture *gesture, gestures) {
6286  if (!gesture->hasHotSpot())
6287  continue;
6288  const Qt::GestureType gestureType = gesture->gestureType();
6289  QList<QGraphicsItem *> items = itemsAtPosition(QPoint(), gesture->d_func()->sceneHotSpot, 0);
6290  for (int j = 0; j < items.size(); ++j) {
6291  QGraphicsItem *item = items.at(j);
6292 
6293  // Check if the item is blocked by a modal panel and use it as
6294  // a target instead of this item.
6295  (void) item->isBlockedByModalPanel(&item);
6296 
6297  if (QGraphicsObject *itemobj = item->toGraphicsObject()) {
6298  QGraphicsItemPrivate *d = item->QGraphicsItem::d_func();
6300  d->gestureContext.find(gestureType);
6301  if (it != d->gestureContext.end() && (!flag || (it.value() & flag))) {
6302  if (normalGestures.contains(gesture)) {
6303  normalGestures.remove(gesture);
6304  if (conflicts)
6305  conflicts->insert(gesture);
6306  } else {
6307  normalGestures.insert(gesture);
6308  }
6309  if (targets)
6310  (*targets)[itemobj].insert(gesture);
6311  if (itemsSet)
6312  (*itemsSet).insert(itemobj);
6313  }
6314  }
6315  // Don't propagate through panels.
6316  if (item->isPanel())
6317  break;
6318  }
6319  }
6320  if (normal)
6321  *normal = normalGestures;
6322 }
6323 
6325 {
6326  QWidget *viewport = event->widget();
6327  if (!viewport)
6328  return;
6329  QGraphicsView *graphicsView = qobject_cast<QGraphicsView *>(viewport->parent());
6330  if (!graphicsView)
6331  return;
6332 
6333  QList<QGesture *> allGestures = event->gestures();
6334  G_DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
6335  << "Gestures:" << allGestures;
6336 
6337  QSet<QGesture *> startedGestures;
6338  QPoint delta = viewport->mapFromGlobal(QPoint());
6339  QTransform toScene = QTransform::fromTranslate(delta.x(), delta.y())
6340  * graphicsView->viewportTransform().inverted();
6341  foreach (QGesture *gesture, allGestures) {
6342  // cache scene coordinates of the hot spot
6343  if (gesture->hasHotSpot()) {
6344  gesture->d_func()->sceneHotSpot = toScene.map(gesture->hotSpot());
6345  } else {
6346  gesture->d_func()->sceneHotSpot = QPointF();
6347  }
6348 
6349  QGraphicsObject *target = gestureTargets.value(gesture, 0);
6350  if (!target) {
6351  // when we are not in started mode but don't have a target
6352  // then the only one interested in gesture is the view/scene
6353  if (gesture->state() == Qt::GestureStarted)
6354  startedGestures.insert(gesture);
6355  }
6356  }
6357 
6358  if (!startedGestures.isEmpty()) {
6359  QSet<QGesture *> normalGestures; // that have just one target
6360  QSet<QGesture *> conflictedGestures; // that have multiple possible targets
6361  gestureTargetsAtHotSpots(startedGestures, Qt::GestureFlag(0), &cachedItemGestures, 0,
6362  &normalGestures, &conflictedGestures);
6363  cachedTargetItems = cachedItemGestures.keys();
6364  qSort(cachedTargetItems.begin(), cachedTargetItems.end(), qt_closestItemFirst);
6365  G_DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
6366  << "Normal gestures:" << normalGestures
6367  << "Conflicting gestures:" << conflictedGestures;
6368 
6369  // deliver conflicted gestures as override events AND remember
6370  // initial gesture targets
6371  if (!conflictedGestures.isEmpty()) {
6372  for (int i = 0; i < cachedTargetItems.size(); ++i) {
6373  QWeakPointer<QGraphicsObject> item = cachedTargetItems.at(i);
6374 
6375  // get gestures to deliver to the current item
6376  QSet<QGesture *> gestures = conflictedGestures & cachedItemGestures.value(item.data());
6377  if (gestures.isEmpty())
6378  continue;
6379 
6380  G_DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
6381  << "delivering override to"
6382  << item.data() << gestures;
6383  // send gesture override
6384  QGestureEvent ev(gestures.toList());
6386  ev.setWidget(event->widget());
6387  // mark event and individual gestures as ignored
6388  ev.ignore();
6389  foreach(QGesture *g, gestures)
6390  ev.setAccepted(g, false);
6391  sendEvent(item.data(), &ev);
6392  // mark all accepted gestures to deliver them as normal gesture events
6393  foreach (QGesture *g, gestures) {
6394  if (ev.isAccepted() || ev.isAccepted(g)) {
6395  conflictedGestures.remove(g);
6396  // mark the item as a gesture target
6397  if (item) {
6398  gestureTargets.insert(g, item.data());
6400  it = cachedItemGestures.begin();
6401  e = cachedItemGestures.end();
6402  for(; it != e; ++it)
6403  it.value().remove(g);
6404  cachedItemGestures[item.data()].insert(g);
6405  }
6406  G_DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
6407  << "override was accepted:"
6408  << g << item.data();
6409  }
6410  // remember the first item that received the override event
6411  // as it most likely become a target if no one else accepts
6412  // the override event
6413  if (!gestureTargets.contains(g) && item)
6414  gestureTargets.insert(g, item.data());
6415 
6416  }
6417  if (conflictedGestures.isEmpty())
6418  break;
6419  }
6420  }
6421  // remember the initial target item for each gesture that was not in
6422  // the conflicted state.
6423  if (!normalGestures.isEmpty()) {
6424  for (int i = 0; i < cachedTargetItems.size() && !normalGestures.isEmpty(); ++i) {
6425  QGraphicsObject *item = cachedTargetItems.at(i);
6426 
6427  // get gestures to deliver to the current item
6428  foreach (QGesture *g, cachedItemGestures.value(item)) {
6429  if (!gestureTargets.contains(g)) {
6430  gestureTargets.insert(g, item);
6431  normalGestures.remove(g);
6432  }
6433  }
6434  }
6435  }
6436  }
6437 
6438 
6439  // deliver all gesture events
6440  QSet<QGesture *> undeliveredGestures;
6441  QSet<QGesture *> parentPropagatedGestures;
6442  foreach (QGesture *gesture, allGestures) {
6443  if (QGraphicsObject *target = gestureTargets.value(gesture, 0)) {
6444  cachedItemGestures[target].insert(gesture);
6445  cachedTargetItems.append(target);
6446  undeliveredGestures.insert(gesture);
6447  QGraphicsItemPrivate *d = target->QGraphicsItem::d_func();
6448  const Qt::GestureFlags flags = d->gestureContext.value(gesture->gestureType());
6450  parentPropagatedGestures.insert(gesture);
6451  } else {
6452  G_DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
6453  << "no target for" << gesture << "at"
6454  << gesture->hotSpot() << gesture->d_func()->sceneHotSpot;
6455  }
6456  }
6457  qSort(cachedTargetItems.begin(), cachedTargetItems.end(), qt_closestItemFirst);
6458  for (int i = 0; i < cachedTargetItems.size(); ++i) {
6459  QWeakPointer<QGraphicsObject> receiver = cachedTargetItems.at(i);
6460  QSet<QGesture *> gestures =
6461  undeliveredGestures & cachedItemGestures.value(receiver.data());
6462  gestures -= cachedAlreadyDeliveredGestures.value(receiver.data());
6463 
6464  if (gestures.isEmpty())
6465  continue;
6466 
6467  cachedAlreadyDeliveredGestures[receiver.data()] += gestures;
6468  const bool isPanel = receiver.data()->isPanel();
6469 
6470  G_DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
6471  << "delivering to"
6472  << receiver.data() << gestures;
6473  QGestureEvent ev(gestures.toList());
6474  ev.setWidget(event->widget());
6475  sendEvent(receiver.data(), &ev);
6476  QSet<QGesture *> ignoredGestures;
6477  foreach (QGesture *g, gestures) {
6478  if (!ev.isAccepted() && !ev.isAccepted(g)) {
6479  // if the gesture was ignored by its target, we will update the
6480  // targetItems list with a possible target items (items that
6481  // want to receive partial gestures).
6482  // ### wont' work if the target was destroyed in the event
6483  // we will just stop delivering it.
6484  if (receiver && receiver.data() == gestureTargets.value(g, 0))
6485  ignoredGestures.insert(g);
6486  } else {
6487  if (receiver && g->state() == Qt::GestureStarted) {
6488  // someone accepted the propagated initial GestureStarted
6489  // event, let it be the new target for all following events.
6490  gestureTargets[g] = receiver.data();
6491  }
6492  undeliveredGestures.remove(g);
6493  }
6494  }
6495  if (undeliveredGestures.isEmpty())
6496  break;
6497 
6498  // ignoredGestures list is only filled when delivering to the gesture
6499  // target item, so it is safe to assume item == target.
6500  if (!ignoredGestures.isEmpty() && !isPanel) {
6501  // look for new potential targets for gestures that were ignored
6502  // and should be propagated.
6503 
6504  QSet<QGraphicsObject *> targetsSet = cachedTargetItems.toSet();
6505 
6506  if (receiver) {
6507  // first if the gesture should be propagated to parents only
6508  for (QSet<QGesture *>::iterator it = ignoredGestures.begin();
6509  it != ignoredGestures.end();) {
6510  if (parentPropagatedGestures.contains(*it)) {
6511  QGesture *gesture = *it;
6512  const Qt::GestureType gestureType = gesture->gestureType();
6513  QGraphicsItem *item = receiver.data();
6514  while (item) {
6515  if (QGraphicsObject *obj = item->toGraphicsObject()) {
6516  if (item->d_func()->gestureContext.contains(gestureType)) {
6517  targetsSet.insert(obj);
6518  cachedItemGestures[obj].insert(gesture);
6519  }
6520  }
6521  if (item->isPanel())
6522  break;
6523  item = item->parentItem();
6524  }
6525 
6526  it = ignoredGestures.erase(it);
6527  continue;
6528  }
6529  ++it;
6530  }
6531  }
6532 
6533  gestureTargetsAtHotSpots(ignoredGestures, Qt::ReceivePartialGestures,
6534  &cachedItemGestures, &targetsSet, 0, 0);
6535 
6536  cachedTargetItems = targetsSet.toList();
6537  qSort(cachedTargetItems.begin(), cachedTargetItems.end(), qt_closestItemFirst);
6538  G_DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
6539  << "new targets:" << cachedTargetItems;
6540  i = -1; // start delivery again
6541  continue;
6542  }
6543  }
6544 
6545  foreach (QGesture *g, startedGestures) {
6547  G_DEBUG() << "lets try to cancel some";
6548  // find gestures in context in Qt::GestureStarted or Qt::GestureUpdated state and cancel them
6549  cancelGesturesForChildren(g);
6550  }
6551  }
6552 
6553  // forget about targets for gestures that have ended
6554  foreach (QGesture *g, allGestures) {
6555  switch (g->state()) {
6556  case Qt::GestureFinished:
6557  case Qt::GestureCanceled:
6558  gestureTargets.remove(g);
6559  break;
6560  default:
6561  break;
6562  }
6563  }
6564 
6565  cachedTargetItems.clear();
6566  cachedItemGestures.clear();
6567  cachedAlreadyDeliveredGestures.clear();
6568 }
6569 
6571 {
6572  Q_ASSERT(original);
6573  QGraphicsItem *originalItem = gestureTargets.value(original);
6574  if (originalItem == 0) // we only act on accepted gestures, which implies it has a target.
6575  return;
6576 
6577  // iterate over all active gestures and for each find the owner
6578  // if the owner is part of our sub-hierarchy, cancel it.
6579 
6580  QSet<QGesture *> canceledGestures;
6581  QHash<QGesture *, QGraphicsObject *>::Iterator iter = gestureTargets.begin();
6582  while (iter != gestureTargets.end()) {
6583  QGraphicsObject *item = iter.value();
6584  // note that we don't touch the gestures for our originalItem
6585  if (item != originalItem && originalItem->isAncestorOf(item)) {
6586  G_DEBUG() << " found a gesture to cancel" << iter.key();
6587  iter.key()->d_func()->state = Qt::GestureCanceled;
6588  canceledGestures << iter.key();
6589  }
6590  ++iter;
6591  }
6592 
6593  // sort them per target item by cherry picking from almostCanceledGestures and delivering
6594  QSet<QGesture *> almostCanceledGestures = canceledGestures;
6596  while (!almostCanceledGestures.isEmpty()) {
6597  QGraphicsObject *target = 0;
6598  QSet<QGesture*> gestures;
6599  setIter = almostCanceledGestures.begin();
6600  // sort per target item
6601  while (setIter != almostCanceledGestures.end()) {
6602  QGraphicsObject *item = gestureTargets.value(*setIter);
6603  if (target == 0)
6604  target = item;
6605  if (target == item) {
6606  gestures << *setIter;
6607  setIter = almostCanceledGestures.erase(setIter);
6608  } else {
6609  ++setIter;
6610  }
6611  }
6612  Q_ASSERT(target);
6613 
6614  QList<QGesture *> list = gestures.toList();
6615  QGestureEvent ev(list);
6616  sendEvent(target, &ev);
6617 
6618  foreach (QGesture *g, list) {
6619  if (ev.isAccepted() || ev.isAccepted(g))
6620  gestures.remove(g);
6621  }
6622 
6623  foreach (QGesture *g, gestures) {
6624  if (!g->hasHotSpot())
6625  continue;
6626 
6627  QList<QGraphicsItem *> items = itemsAtPosition(QPoint(), g->d_func()->sceneHotSpot, 0);
6628  for (int j = 0; j < items.size(); ++j) {
6629  QGraphicsObject *item = items.at(j)->toGraphicsObject();
6630  if (!item)
6631  continue;
6632  QGraphicsItemPrivate *d = item->QGraphicsItem::d_func();
6633  if (d->gestureContext.contains(g->gestureType())) {
6634  QList<QGesture *> list;
6635  list << g;
6636  QGestureEvent ev(list);
6637  sendEvent(item, &ev);
6638  if (ev.isAccepted() || ev.isAccepted(g))
6639  break; // successfully delivered
6640  }
6641  }
6642  }
6643  }
6644 
6646  Q_ASSERT(gestureManager); // it would be very odd if we got called without a manager.
6647  for (setIter = canceledGestures.begin(); setIter != canceledGestures.end(); ++setIter) {
6648  gestureManager->recycle(*setIter);
6649  gestureTargets.remove(*setIter);
6650  }
6651 }
6652 
6654 {
6655  (void)QGestureManager::instance(); // create a gesture manager
6656  if (!grabbedGestures[gesture]++) {
6657  foreach (QGraphicsView *view, views)
6658  view->viewport()->grabGesture(gesture);
6659  }
6660 }
6661 
6663 {
6664  // we know this can only be an object
6665  Q_ASSERT(item->d_ptr->isObject);
6666  QGraphicsObject *obj = static_cast<QGraphicsObject *>(item);
6668  if (!--grabbedGestures[gesture]) {
6669  foreach (QGraphicsView *view, views)
6670  view->viewport()->ungrabGesture(gesture);
6671  }
6672 }
6673 #endif // QT_NO_GESTURES
6674 
6676 
6677 #include "moc_qgraphicsscene.cpp"
6678 
6679 #endif // QT_NO_GRAPHICSVIEW
void setStickyFocus(bool enabled)
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
void unregisterScenePosItem(QGraphicsItem *item)
bool stickyFocus() const
T qobject_cast(QObject *object)
Definition: qobject.h:375
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
This event handler, for event mouseEvent, can be reimplemented in a subclass to receive mouse release...
Qt::DropAction dropAction() const
Returns the action that was performed in this drag and drop.
const QMimeData * mimeData() const
This function returns the MIME data of the event.
The QPainter class performs low-level painting on widgets and other paint devices.
Definition: qpainter.h:86
QPaintDevice * device() const
Returns the paint device on which this painter is currently painting, or 0 if the painter is not acti...
Definition: qpainter.cpp:1530
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
double d
Definition: qnumeric_p.h:62
QRect toAlignedRect() const
Returns a QRect based on the values of this rectangle that is the smallest possible integer rectangle...
Definition: qrect.cpp:2817
QGraphicsWidget * focusWidget() const
If this widget, a child or descendant of this widget currently has input focus, this function will re...
void setSource(QWidget *source)
This function set the source widget, i.
QGraphicsWidget * activeWindow() const
Returns the current active window, or 0 if no window is currently active.
void setFont(const QFont &font)
Sets the font that is used to draw the item&#39;s text to font.
void setScenePos(const QPointF &pos)
Sets the scene position of the mouse to pos.
bool updateRectF(const QRectF &rect)
void clear()
Removes and deletes all items from the scene, but otherwise leaves the state of the scene unchanged...
QMap< int, QGraphicsItem * > itemForTouchPointId
qreal height() const
This convenience function is equivalent to calling sceneRect().
int id() const
Returns the id number of this touch point.
Definition: qevent.cpp:4445
void squeeze()
Releases any memory not required to store the items.
Definition: qvector.h:145
static QRectF adjustedItemBoundingRect(const QGraphicsItem *item)
static void updateAccessibility(QObject *, int who, Event reason)
Notifies accessibility clients about a change in object&#39;s accessibility information.
QMap< Qt::MouseButton, QPoint > mouseGrabberButtonDownScreenPos
void setSelectionArea(const QPainterPath &path)
Sets the selection area to path.
QWidget * parentWidget() const
Returns the parent of this widget, or 0 if it does not have any parent widget.
Definition: qwidget.h:1035
Qt::WindowFlags windowFlags
the widget&#39;s window flags
const Key & key() const
Returns the current item&#39;s key as a const reference.
Definition: qmap.h:250
The QGraphicsScene class provides a surface for managing a large number of 2D graphical items...
qreal dy() const
Returns the vertical translation factor.
Definition: qtransform.h:277
QPointF scenePos() const
Returns the position of the mouse cursor in scene coordinates at the moment the help event was sent...
void setPen(const QPen &pen)
Sets the item&#39;s pen to pen.
ItemIndexMethod itemIndexMethod() const
void setLastPos(const QPointF &lastPos)
Definition: qevent.cpp:4743
QMap< QPaintDevice *, DeviceData > deviceData
QGraphicsItem * parent
bool itemAcceptsHoverEvents_helper(const QGraphicsItem *item) const
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
static void _q_paintItem(QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget, bool useWindowOpacity, bool painterStateProtection)
The QKeyEvent class describes a key event.
Definition: qevent.h:224
The QHash::const_iterator class provides an STL-style const iterator for QHash and QMultiHash...
Definition: qhash.h:395
QPoint screenPos() const
Returns the mouse cursor position in screen coordinates.
QList< QGraphicsItem * > keyboardGrabberItems
virtual bool sceneEvent(QEvent *event)
This virtual function receives events to this item.
QRect adjusted(int x1, int y1, int x2, int y2) const
Returns a new rectangle with dx1, dy1, dx2 and dy2 added respectively to the existing coordinates of ...
Definition: qrect.h:431
qreal combineOpacityFromParent(qreal parentOpacity) const
bool isNull() const
Returns true if the rectangle is a null rectangle, otherwise returns false.
Definition: qrect.h:231
static void setWorldTransform(QPainter *painter, const QTransform *const transformPtr, const QTransform *effectTransform)
double windowOpacity
The level of opacity for the window.
Definition: qwidget.h:201
int type
Definition: qmetatype.cpp:239
virtual void dropEvent(QGraphicsSceneDragDropEvent *event)
This event handler, for event event, can be reimplemented in a subclass to receive drop events for th...
void setBspTreeDepth(int depth)
void removeView(QGraphicsView *view)
double qreal
Definition: qglobal.h:1193
QIntegerForSizeof< void * >::Unsigned quintptr
Definition: qglobal.h:986
#define disabled
QGraphicsItem * focusItem() const
If this item, a child or descendant of this item currently has input focus, this function will return...
static mach_timebase_info_data_t info
QGraphicsItem * commonAncestorItem(const QGraphicsItem *other) const
Returns the closest common ancestor item of this item and other, or 0 if either other is 0...
static QRectF adjustedItemEffectiveBoundingRect(const QGraphicsItem *item)
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
QPointF mapToScene(const QPoint &point) const
Returns the viewport coordinate point mapped to scene coordinates.
void addView(QGraphicsView *view)
QGraphicsWidget * parentWidget() const
Returns a pointer to the item&#39;s parent widget.
bool isTransformed() const
Returns true if the view is transformed (i.
qreal opacity() const
Returns the opacity of the painter.
Definition: qpainter.cpp:2115
void recycle(QGesture *gesture)
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
The QGraphicsRectItem class provides a rectangle item that you can add to a QGraphicsScene.
QPointF toPointF() const
Returns the variant as a QPointF if the variant has type() Point or PointF ; otherwise returns a null...
Definition: qvariant.cpp:2509
void setModifiers(Qt::KeyboardModifiers modifiers)
QPointF startScenePos() const
Returns the starting scene position of this touch point.
Definition: qevent.cpp:4537
bool acceptDrops() const
Returns true if this item can accept drag and drop events; otherwise, returns false.
QGraphicsItem::PanelModality panelModality
EventRef event
bool isWindow() const
Returns true if the item is a QGraphicsWidget window, otherwise returns false.
QPointer< QWidget > widget
virtual void advance(int phase)
This virtual function is called twice for all items by the QGraphicsScene::advance() slot...
QSize size() const
Returns the size of the pixmap.
Definition: qpixmap.cpp:661
ushort t
Definition: qcoreevent.h:316
int findClosestTouchPointId(const QPointF &scenePos)
void removeFromGroup(QGraphicsItem *item)
Removes the specified item from this group.
Qt::TouchPointState state() const
Returns the current state of this touch point.
Definition: qevent.cpp:4453
void advance()
This slot advances the scene by one step, by calling QGraphicsItem::advance() for all items on the sc...
void resetFocusProxy()
Sets the focusProxy pointer to 0 for all items that have this item as their focusProxy.
int remove(const Key &key)
Removes all the items that have the key from the hash.
Definition: qhash.h:784
QScopedPointer< QGraphicsItemPrivate > d_ptr
static void keyEvent(KeyAction action, QWidget *widget, char ascii, Qt::KeyboardModifiers modifier=Qt::NoModifier, int delay=-1)
void setLastPos(const QPointF &pos)
void remove(int i)
Removes the element at index position i.
Definition: qvector.h:374
void setSelected(bool selected)
If selected is true and this item is selectable, this item is selected; otherwise, it is unselected.
virtual void drawBackground(QPainter *painter, const QRectF &rect)
Draws the background of the scene using painter, before any items and the foreground are drawn...
bool dispatchHoverEvent(QGraphicsSceneHoverEvent *hoverEvent)
This event handler, for event hoverEvent, can be reimplemented in a subclass to receive hover enter e...
virtual void focusInEvent(QFocusEvent *event)
This event handler, for event focusEvent, can be reimplemented in a subclass to receive focus in even...
void setFocus(Qt::FocusReason focusReason=Qt::OtherFocusReason)
Sets focus on the scene by sending a QFocusEvent to the scene, passing focusReason as the reason...
virtual void helpEvent(QGraphicsSceneHelpEvent *event)
This event handler, for event helpEvent, can be reimplemented in a subclass to receive help events...
T * data() const
Returns the value of the pointer referenced by this object.
void setRect(const QRectF &rect)
Definition: qevent.cpp:4775
void setFont(const QFont &font)
Sets the font used to render the text item to font.
#define it(className, varName)
QObject * q_ptr
Definition: qobject.h:91
The QPainterPath class provides a container for painting operations, enabling graphical shapes to be ...
Definition: qpainterpath.h:67
int count(const T &t) const
Returns the number of occurrences of value in the vector.
Definition: qvector.h:742
void setButtonDownScenePos(Qt::MouseButton button, const QPointF &pos)
static void postEvent(QObject *receiver, QEvent *event)
Adds the event event, with the object receiver as the receiver of the event, to an event queue and re...
void setScreenPos(const QPoint &pos)
void setScenePosItemEnabled(QGraphicsItem *item, bool enabled)
bool isEnabled() const
virtual QRectF boundingRect() const =0
This pure virtual function defines the outer bounds of the item as a rectangle; all painting must be ...
void setMimeData(const QMimeData *data)
This function sets the MIME data for the event.
QMap< Key, T >::iterator insert(const Key &key, const T &value)
Inserts a new item with the key key and a value of value.
Definition: qmap.h:982
QList< QGraphicsItem * > itemsAtPosition(const QPoint &screenPos, const QPointF &scenePos, QWidget *widget) const
Returns all items for the screen position in event.
qreal m21() const
Returns the horizontal shearing factor.
Definition: qtransform.h:249
int height() const
Definition: qpaintdevice.h:92
void clearFocus()
Takes keyboard input focus from the item.
bool remove(const T &value)
Definition: qset.h:89
QPoint screenPos() const
Returns the position of the mouse cursor in screen coordinates at the moment the hover event was sent...
void setClipRect(const QRectF &, Qt::ClipOperation op=Qt::ReplaceClip)
Enables clipping, and sets the clip region to the given rectangle using the given clip operation...
Definition: qpainter.cpp:2801
virtual void updateSceneTransformFromParent()
QGraphicsItem * focusItem
bool isEmpty() const
Definition: qset.h:77
void grabKeyboard(QGraphicsItem *item)
void setParentItem(QGraphicsItem *parent)
Sets this item&#39;s parent item to newParent.
static bool updateHelper(QGraphicsViewPrivate *view, QGraphicsItemPrivate *item, const QRectF &rect, bool itemIsUntransformable)
void setAccepted(bool accepted)
Definition: qcoreevent.h:306
static QColor fromHsv(int h, int s, int v, int a=255)
Static convenience function that returns a QColor constructed from the HSV color values, h (hue), s (saturation), v (value), and a (alpha-channel, i.e.
Definition: qcolor.cpp:2048
QGraphicsItem * q_ptr
#define SLOT(a)
Definition: qobjectdefs.h:226
static bool transformIsSimple(const QTransform &transform)
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:214
void clearFocus()
Clears focus from the scene.
The QGraphicsItem class is the base class for all graphical items in a QGraphicsScene.
Definition: qgraphicsitem.h:89
The QGraphicsSceneMouseEvent class provides mouse events in the graphics view framework.
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value)
This virtual function is called by QGraphicsItem to notify custom items that some part of the item&#39;s ...
void grabGesture(QGraphicsItem *, Qt::GestureType gesture)
void invalidate(qreal x, qreal y, qreal w, qreal h, SceneLayers layers=AllLayers)
This is an overloaded member function, provided for convenience. It differs from the above function o...
qreal left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:525
bool isVisible() const
Returns true if the item is visible; otherwise, false is returned.
bool filterEvent(QWidget *receiver, QEvent *event)
static qreal position(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine)
void setWidget(QWidget *widget)
Embeds widget into this proxy widget.
void restore()
Restores the current painter state (pops a saved state off the stack).
Definition: qpainter.cpp:1620
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
qreal m22() const
Returns the vertical scaling factor.
Definition: qtransform.h:253
iterator begin()
Returns an STL-style iterator pointing to the first item in the list.
Definition: qlist.h:267
QGraphicsScene * scene
QList< QGraphicsItem * > modalPanels
Qt::MouseButton button() const
Returns the mouse button (if any) that caused the event.
The QGraphicsEllipseItem class provides an ellipse item that you can add to a QGraphicsScene.
QGesture::GestureCancelPolicy gestureCancelPolicy
the policy for deciding what happens on accepting a gesture
Definition: qgesture.h:71
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
Qt::MouseButtons buttons() const
Returns a Qt::MouseButtons value indicating which buttons were pressed on the mouse when this mouse e...
The QGraphicsSceneBspTreeIndex class provides an implementation of a BSP indexing algorithm for disco...
int width() const
Returns the width of the rectangle.
Definition: qrect.h:303
QPointF genericMapFromScene(const QPointF &pos, const QWidget *viewport) const
Maps the point pos from scene to item coordinates.
The QList::const_iterator class provides an STL-style const iterator for QList and QQueue...
Definition: qlist.h:228
bool isBlockedByModalPanel(QGraphicsItem **blockingPanel=0) const
Returns true if this item is blocked by a modal panel, false otherwise.
The QGraphicsEffectSource class represents the source on which a QGraphicsEffect is installed on...
void setFont(const QFont &font)
void setButtonDownPos(Qt::MouseButton button, const QPointF &pos)
virtual void dragEnterEvent(QGraphicsSceneDragDropEvent *event)
This event handler, for event event, can be reimplemented in a subclass to receive drag enter events ...
QList< QGraphicsItem * > items() const
Returns a list of all items in the scene in descending stacking order.
QList< QGraphicsItem * > cachedItemsUnderMouse
QPointF scenePos() const
Returns the position of the mouse cursor in scene coordinates at the moment the the context menu was ...
static QApplicationPrivate * instance()
QWidget * widget() const
Returns the widget where the event originated, or 0 if the event originates from another application...
virtual void drawForeground(QPainter *painter, const QRectF &rect)
Draws the foreground of the scene using painter, after the background and all items have been drawn...
QPointF lastScenePos() const
Returns the scene position of this touch point from the previous touch event.
Definition: qevent.cpp:4587
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
static QPalette palette()
Returns the application palette.
Qt::KeyboardModifiers modifiers() const
Returns the keyboard modifiers that were pressed when the drag and drop event was created...
ItemSelectionMode
Definition: qnamespace.h:1503
QRect boundingRect() const
Returns the bounding rectangle of this region.
Definition: qregion.cpp:4363
QVector< QGraphicsItem * > unpolishedItems
QGraphicsEllipseItem * addEllipse(const QRectF &rect, const QPen &pen=QPen(), const QBrush &brush=QBrush())
Creates and adds an ellipse item to the scene, and returns the item pointer.
static QStyle * style()
Returns the application&#39;s style object.
void setButtons(Qt::MouseButtons buttons)
iterator find(const Key &key)
Returns an iterator pointing to the item with key key in the map.
Definition: qmap.h:618
void addItem(QGraphicsItem *item)
Adds or moves the item and all its childen to this scene.
bool isOpacityNull() const
T & value() const
Returns a modifiable reference to the current item&#39;s value.
Definition: qhash.h:348
QGraphicsSceneIndex * index
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event)
This event handler, for event mouseEvent, can be reimplemented in a subclass to receive mouse press e...
QTransform & translate(qreal dx, qreal dy)
Moves the coordinate system dx along the x axis and dy along the y axis, and returns a reference to t...
Definition: qtransform.cpp:417
void setScenePos(const QPointF &pos)
void setWidget(QWidget *widget)
Sets the widget related to this event.
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
void destroyItemGroup(QGraphicsItemGroup *group)
Reparents all items in group to group&#39;s parent item, then removes group from the scene, and finally deletes it.
The QString class provides a Unicode character string.
Definition: qstring.h:83
T * qobject_cast(QObject *object)
Definition: qobject.h:375
QRectF toRectF() const
Returns the variant as a QRectF if the variant has type() Rect or RectF ; otherwise returns an invali...
Definition: qvariant.cpp:2463
static void updateTouchPointsForItem(QGraphicsItem *item, QTouchEvent *touchEvent)
QPointF scenePos() const
Returns the scene position of this touch point.
Definition: qevent.cpp:4488
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qdatastream.h:66
QGraphicsItem * mouseGrabberItem() const
Returns the current mouse grabber item, or 0 if no item is currently grabbing the mouse...
PanelModality panelModality() const
Returns the modality for this item.
void removeSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter)
qint64 horizontalScroll() const
Returns the horizontal scroll value (the X value of the left edge of the viewport).
bool isEnabled() const
Returns true if the item is enabled; otherwise, false is returned.
The QGraphicsTextItem class provides a text item that you can add to a QGraphicsScene to display form...
QSet< QGraphicsItem * > scenePosItems
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
void invalidateScene(const QRectF &rect=QRectF(), QGraphicsScene::SceneLayers layers=QGraphicsScene::AllLayers)
Invalidates and schedules a redraw of layers inside rect.
void cleanupCachedGestures(QObject *target, Qt::GestureType type)
TransformationType type() const
Returns the transformation type of this matrix.
virtual void keyPressEvent(QKeyEvent *event)
This event handler, for event keyEvent, can be reimplemented in a subclass to receive keypress events...
virtual bool event(QEvent *)
This virtual function receives events to an object and should return true if the event e was recogniz...
Definition: qobject.cpp:1200
#define X11
Definition: qt_x11_p.h:724
bool isSelected() const
Returns true if this item is selected; otherwise, false is returned.
The QGraphicsPolygonItem class provides a polygon item that you can add to a QGraphicsScene.
bool focusNextPrevChild(bool next)
Finds a new widget to give the keyboard focus to, as appropriate for Tab and Shift+Tab, and returns true if it can find a new widget, or false if it cannot.
iterator begin()
Definition: qset.h:166
#define Q_D(Class)
Definition: qglobal.h:2482
static void _q_paintIntoCache(QPixmap *pix, QGraphicsItem *item, const QRegion &pixmapExposed, const QTransform &itemToPixmap, QPainter::RenderHints renderHints, const QStyleOptionGraphicsItem *option, bool painterStateProtection)
The QPen class defines how a QPainter should draw lines and outlines of shapes.
Definition: qpen.h:64
void setBrushOrigin(int x, int y)
Sets the brush&#39;s origin to point (x, y).
Definition: qpainter.h:825
void setTouchPointStates(Qt::TouchPointStates aTouchPointStates)
Sets a bitwise OR of all the touch point states for this event.
Definition: qevent.h:825
void setStartPos(const QPointF &startPos)
Definition: qevent.cpp:4711
T * data() const
virtual int devType() const
Definition: qpaintdevice.h:167
The QSizeF class defines the size of a two-dimensional object using floating point precision...
Definition: qsize.h:202
void storeMouseButtonsForMouseGrabber(QGraphicsSceneMouseEvent *event)
static void _q_hoverFromMouseEvent(QGraphicsSceneHoverEvent *hover, const QGraphicsSceneMouseEvent *mouseEvent)
QMap< Qt::MouseButton, QPointF > mouseGrabberButtonDownScenePos
QRectF sceneRect() const
Returns the rect for this touch point in scene coordinates.
Definition: qevent.cpp:4636
Qt::WindowType windowType() const
Returns the widgets window type.
static QGestureManager * instance()
virtual QPainterPath shape() const
Returns the shape of this item as a QPainterPath in local coordinates.
int rectCount() const
Returns the number of rectangles that will be returned in rects().
Definition: qregion.cpp:4461
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
bool eventFilter(QObject *watched, QEvent *event)
QGraphicsScene filters QApplication&#39;s events to detect palette and font changes.
void cloneDragDropEvent(QGraphicsSceneDragDropEvent *dest, QGraphicsSceneDragDropEvent *source)
void setForegroundBrush(const QBrush &brush)
void save()
Saves the current painter state (pushes the state onto a stack).
Definition: qpainter.cpp:1590
bool sendEvent(QGraphicsItem *item, QEvent *event)
Sends event event to item item through possible event filters.
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
void gestureEventHandler(QGestureEvent *event)
QTransform inverted(bool *invertible=0) const
Returns an inverted copy of this matrix.
Definition: qtransform.cpp:364
QSet< QGraphicsItem * > selectedItems
static QPixmap * find(const QString &key)
void grabGesture(Qt::GestureType type, Qt::GestureFlags flags=Qt::GestureFlags())
Subscribes the widget to a given gesture with specific flags.
Definition: qwidget.cpp:12964
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
qreal x() const
Returns the x-coordinate of this point.
Definition: qpoint.h:282
void sendMouseEvent(QGraphicsSceneMouseEvent *mouseEvent)
#define Q_Q(Class)
Definition: qglobal.h:2483
bool begin(QPaintDevice *)
Begins painting the paint device and returns true if successful; otherwise returns false...
Definition: qpainter.cpp:1723
void setFont_helper(const QFont &font)
Set the font and propagate the changes if the font is different from the current font.
static QFont font()
Returns the default application font.
QTransform viewportTransform() const
Returns a matrix that maps viewport coordinates to scene coordinates.
void registerScenePosItem(QGraphicsItem *item)
The QLineF class provides a two-dimensional vector using floating point precision.
Definition: qline.h:212
int size() const
Definition: qset.h:75
QList< QGraphicsView * > views
virtual void removeItem(QGraphicsItem *item)=0
This pure virtual function removes an item to the scene index.
qreal zValue() const
Returns the Z-value of the item.
T & value() const
Returns a modifiable reference to the current item&#39;s value.
Definition: qmap.h:251
QBrush backgroundBrush() const
Qt::CoordinateSystem currentCachedSystem() const
QGraphicsItem * passiveFocusItem
static void setClip(QPainter *painter, QGraphicsItem *item)
void update()
Updates the widget unless updates are disabled or the widget is hidden.
Definition: qwidget.cpp:10883
QPointF buttonDownScenePos(Qt::MouseButton button) const
Returns the mouse cursor position in scene coordinates where the specified button was clicked...
static const QRectF boundingRect(const QPointF *points, int pointCount)
QGraphicsObject * toGraphicsObject()
Return the graphics item cast to a QGraphicsObject, if the class is actually a graphics object...
void drawItemHelper(QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget, bool painterStateProtection)
Draws items directly, or using cache.
const Key & key() const
Returns the current item&#39;s key.
Definition: qhash.h:419
virtual void paintWindowFrame(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget=0)
This virtual function is called by QGraphicsScene to draw the window frame for windows using painter...
QWidget * viewport() const
Returns the viewport widget.
QGraphicsItem * dragDropItem
QPointF lastScenePos() const
Returns the last recorded, the scene coordinates of the previous mouse or hover event received by the...
bool removeOne(const T &t)
Removes the first occurrence of value in the list and returns true on success; otherwise returns fals...
Definition: qlist.h:796
Qt::KeyboardModifiers modifiers() const
Returns the keyboard modifier flags that existed immediately after the event occurred.
Definition: qevent.cpp:999
int key() const
Returns the code of the key that was pressed or released.
Definition: qevent.h:231
QGraphicsPolygonItem * addPolygon(const QPolygonF &polygon, const QPen &pen=QPen(), const QBrush &brush=QBrush())
Creates and adds a polygon item to the scene, and returns the item pointer.
#define SIGNAL(a)
Definition: qobjectdefs.h:227
qreal m12() const
Returns the vertical shearing factor.
Definition: qtransform.h:241
quint32 hasBoundingRegionGranularity
void invalidateCache(InvalidateReason reason=SourceChanged) const
QGraphicsLineItem * addLine(const QLineF &line, const QPen &pen=QPen())
Creates and adds a line item to the scene, and returns the item pointer.
QFont resolve(const QFont &) const
Returns a new QFont that has attributes copied from other that have not been previously set on this f...
Definition: qfont.cpp:1983
bool qt_closestItemFirst(const QGraphicsItem *item1, const QGraphicsItem *item2)
Returns true if item1 is on top of item2.
QRectF boundingRect(Qt::CoordinateSystem system) const
int width() const
Returns the width.
Definition: qsize.h:126
SortOrder
Definition: qnamespace.h:189
QWidget * source() const
This function returns the QGraphicsView that created the QGraphicsSceneDragDropEvent.
QRect mapRect(const QRect &) const
Creates and returns a QRect object that is a copy of the given rectangle, mapped into the coordinate ...
void ungrabMouse(QGraphicsItem *item, bool itemIsDying=false)
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
void updateFont(const QFont &font)
Update the font, and whether or not it has changed, reresolve all fonts in the scene.
void ungrabGesture(QGraphicsItem *, Qt::GestureType gesture)
static void _q_adjustRect(QRect *rect)
void mousePress(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers stateKey=0, QPoint pos=QPoint(), int delay=-1)
Simulates pressing a mouse button with an optional modifier on a widget.
Definition: qtestmouse.h:129
TransformationType
Definition: qtransform.h:68
void setPos(const QPointF &pos)
Sets the position associated with the context menu to the given point in item coordinates.
void sceneRectChanged(const QRectF &rect)
This signal is emitted by QGraphicsScene whenever the scene rect changes.
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget=0)
Reimplemented Function
QPointF lastScenePos() const
Returns the last recorded mouse cursor position in scene coordinates.
virtual void keyReleaseEvent(QKeyEvent *event)
This event handler, for event keyEvent, can be reimplemented in a subclass to receive key release eve...
const QPen & pen() const
Returns the painter&#39;s current pen.
Definition: qpainter.cpp:4152
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
void setZValue(qreal z)
Sets the Z-value of the item to z.
int bspTreeDepth
the depth of the BSP index tree
void setBackgroundBrush(const QBrush &brush)
int width() const
Definition: qpaintdevice.h:91
The QGestureEvent class provides the description of triggered gestures.
Definition: qevent.h:841
bool filterDescendantEvent(QGraphicsItem *item, QEvent *event)
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
void removePopup(QGraphicsWidget *widget, bool itemIsDying=false)
Remove widget from the popup list.
QBool contains(const T &t) const
Returns true if the list contains an occurrence of value; otherwise returns false.
Definition: qlist.h:880
bool isAccepted() const
Definition: qcoreevent.h:307
void markDirty(QGraphicsItem *item, const QRectF &rect=QRectF(), bool invalidateChildren=false, bool force=false, bool ignoreOpacity=false, bool removingItemFromScene=false, bool updateBoundingRect=false)
QGraphicsItem * focusItem() const
When the scene is active, this functions returns the scene&#39;s current focus item, or 0 if no item curr...
QList< QGraphicsItem * > mouseGrabberItems
void setPos(const QPointF &pos)
DragMode dragMode
the behavior for dragging the mouse over the scene while the left mouse button is pressed...
Definition: qgraphicsview.h:75
Qt::KeyboardModifiers modifiers() const
Returns the keyboard modifiers at the moment the hover event was sent.
QWidget * widget() const
Returns the widget on which the event occurred.
Definition: qevent.h:817
void setPossibleActions(Qt::DropActions actions)
Sets the possible drop actions that the drag can result in to actions.
int lastIndexOf(const T &t, int from=-1) const
Returns the index position of the last occurrence of value in the list, searching backward from index...
Definition: qlist.h:862
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event)
This event handler, for event mouseEvent, can be reimplemented in a subclass to receive mouse move ev...
QGraphicsView::ViewportUpdateMode viewportUpdateMode
QList< QGraphicsView * > views() const
Returns a list of all the views that display this scene.
void clear()
Removes all the elements from the vector and releases the memory used by the vector.
Definition: qvector.h:347
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
This event handler, for event mouseEvent, can be reimplemented in a subclass to receive mouse doublec...
bool contains(const T &value) const
Definition: qset.h:91
void resolvePalette()
Resolve the scene&#39;s palette against the application palette, and propagate the changes too all items ...
QList< T > toList() const
Definition: qset.h:296
QStyle * style() const
Returns the scene&#39;s style, or the same as QApplication::style() if the scene has not been explicitly ...
QTouchEvent::DeviceType deviceType() const
Returns the touch device Type, which is of type QTouchEvent::DeviceType {DeviceType}.
Definition: qevent.h:818
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
Definition: qobject.cpp:2580
void invalidateChildrenSceneTransform()
void setDropAction(Qt::DropAction action)
This function lets the receiver of the drop set the drop action that was performed to action...
void removeItem(QGraphicsItem *item)
Removes the item item and all its children from the scene.
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
bool isEmpty() const
Returns true if the region is empty; otherwise returns false.
Definition: qregion.cpp:4098
#define qApp
bool itemIsUntransformable() const
QGraphicsTextItem * addText(const QString &text, const QFont &font=QFont())
Creates and adds a text item to the scene, and returns the item pointer.
void updateInputMethodSensitivityInViews()
void initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform, const QRegion &exposedRegion, bool allItems=false) const
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the list...
Definition: qlist.h:270
QGraphicsItemGroup * createItemGroup(const QList< QGraphicsItem *> &items)
Groups all items in items into a new QGraphicsItemGroup, and returns a pointer to the group...
void enterModal(QGraphicsItem *item, QGraphicsItem::PanelModality panelModality=QGraphicsItem::NonModal)
void resetCachedContent()
Resets any cached content.
quint32 sceneTransformTranslateOnly
quint32 paintedViewBoundingRectsNeedRepaint
qreal height() const
Returns the height of the rectangle.
Definition: qrect.h:710
virtual bool collidesWithItem(const QGraphicsItem *other, Qt::ItemSelectionMode mode=Qt::IntersectsItemShape) const
Returns true if this item collides with other; otherwise returns false.
void setModifiers(Qt::KeyboardModifiers modifiers)
Sets the modifiers for the current hover event to modifiers.
const T value(const Key &key) const
Returns the value associated with the key key.
Definition: qmap.h:499
void setActiveWindow(QGraphicsWidget *widget)
Activates widget, which must be a widget in this scene.
QGraphicsItem * panel() const
Returns the item&#39;s panel, or 0 if this item does not have a panel.
void prepend(const T &t)
Inserts value at the beginning of the list.
Definition: qlist.h:541
QSize size() const
Returns the size of the rectangle.
Definition: qrect.h:309
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
#define emit
Definition: qobjectdefs.h:76
void setPos(const QPointF &pos)
Sets the position of the mouse to pos; this should be relative to the widget that generated the event...
void adjust(int x1, int y1, int x2, int y2)
Adds dx1, dy1, dx2 and dy2 respectively to the existing coordinates of the rectangle.
Definition: qrect.h:434
QPoint screenPos() const
Returns the position of the cursor in screen coordinates when the wheel event occurred.
void setPos(const QPointF &pos)
LayoutDirection
Definition: qnamespace.h:1580
QGraphicsEffect * graphicsEffect
The QPolygonF class provides a vector of points using floating point precision.
Definition: qpolygon.h:134
iterator end()
Definition: qset.h:169
void setPen(const QPen &pen)
Sets the pen for this item to pen.
bool isEmpty() const
Returns true if the hash contains no items; otherwise returns false.
Definition: qhash.h:297
GestureFlag
Definition: qnamespace.h:1772
const T & value() const
Returns the current item&#39;s value.
Definition: qhash.h:420
QPoint screenPos() const
Returns the position of the mouse relative to the screen.
Q_CORE_EXPORT void qWarning(const char *,...)
QPoint map(const QPoint &p) const
Creates and returns a QPoint object that is a copy of the given point, mapped into the coordinate sys...
void drawSubtreeRecursive(QGraphicsItem *item, QPainter *painter, const QTransform *const, QRegion *exposedRegion, QWidget *widget, qreal parentOpacity=qreal(1.0), const QTransform *const effectTransform=0)
const_iterator insert(const T &value)
Definition: qset.h:179
#define ENSURE_TRANSFORM_PTR
bool acceptTouchEvents() const
Returns true if an item accepts touch events; otherwise, returns false.
QPoint screenPos() const
Returns the position of the mouse cursor in screen coordinates at the moment the the context menu was...
virtual void inputMethodEvent(QInputMethodEvent *event)
This event handler, for event event, can be reimplemented in a subclass to receive input method event...
QRectF sceneRect() const
void setFocusItem(QGraphicsItem *item, Qt::FocusReason focusReason=Qt::OtherFocusReason)
Sets the scene&#39;s focus item to item, with the focus reason focusReason, after removing focus from any...
void updatePalette(const QPalette &palette)
Update the palette, and whether or not it has changed, reresolve all palettes in the scene...
static Bigint * diff(Bigint *a, Bigint *b)
static int distance(QWidget *source, QWidget *target, QAccessible::RelationFlag relation)
qreal width() const
Returns the width of the rectangle.
Definition: qrect.h:707
void changed(const QList< QRectF > &region)
This signal is emitted by QGraphicsScene when control reaches the event loop, if the scene content ch...
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
QPalette palette
the widget&#39;s palette
static QGraphicsScenePrivate * get(QGraphicsScene *q)
QPointF screenPos() const
Returns the screen position of this touch point.
Definition: qevent.cpp:4498
void setRect(qreal x, qreal y, qreal w, qreal h)
Sets the coordinates of the rectangle&#39;s top-left corner to (x, y), and its size to the given width an...
Definition: qrect.h:754
The QRegion class specifies a clip region for a painter.
Definition: qregion.h:68
T value(int i) const
Returns the value at index position i in the list.
Definition: qlist.h:661
const T * ptr(const T &t)
QGraphicsItem * itemAt(const QPointF &pos) const
Returns the topmost visible item at the specified position, or 0 if there are no items at this positi...
QList< Key > keys() const
Returns a list containing all the keys in the map in ascending order.
Definition: qmap.h:818
QGraphicsItem * topLevelItem() const
Returns this item&#39;s top-level item.
void setStyle(QStyle *style)
Sets or replaces the style of the scene to style, and reparents the style to this scene...
void clear()
Removes all items from the list.
Definition: qlist.h:764
QList< QGraphicsObject * > cachedTargetItems
const Key & key() const
Returns the current item&#39;s key as a const reference.
Definition: qhash.h:347
void drawItems(QPainter *painter, const QTransform *const viewTransform, QRegion *exposedRegion, QWidget *widget)
virtual void resolvePalette(uint inheritedMask)
void setSortCacheEnabled(bool enabled)
int indexOf(const T &t, int from=0) const
Returns the index position of the first occurrence of value in the vector, searching forward from ind...
Definition: qvector.h:698
QRectF adjusted(qreal x1, qreal y1, qreal x2, qreal y2) const
Returns a new rectangle with dx1, dy1, dx2 and dy2 added respectively to the existing coordinates of ...
Definition: qrect.h:781
void registerTopLevelItem(QGraphicsItem *item)
GraphicsItemFlags flags() const
Returns this item&#39;s flags.
static bool insertionOrder(QGraphicsItem *a, QGraphicsItem *b)
QGraphicsItem * activePanel() const
Returns the current active panel, or 0 if no panel is currently active.
void sendHoverEvent(QEvent::Type type, QGraphicsItem *item, QGraphicsSceneHoverEvent *hoverEvent)
QBrush foregroundBrush() const
void setPalette_helper(const QPalette &palette)
Set the palette and propagate the changes if the palette is different from the current palette...
static void hideText()
Hides the tool tip.
Definition: qtooltip.h:61
QVariant extra(Extra type) const
void translate(qreal dx, qreal dy)
Moves the rectangle dx along the x-axis and dy along the y-axis, relative to the current position...
Definition: qrect.h:716
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
This event handler, for event contextMenuEvent, can be reimplemented in a subclass to receive context...
QList< QGraphicsItem * > selectedItems() const
Returns a list of all currently selected items.
QSize toSize() const
Returns the variant as a QSize if the variant has type() Size ; otherwise returns an invalid QSize...
Definition: qvariant.cpp:2432
GestureType
Definition: qnamespace.h:1759
bool isSortCacheEnabled() const
qreal boundingRegionGranularity() const
Returns the item&#39;s bounding region granularity; a value between and including 0 and 1...
QRect toRect() const
Returns a QRect based on the values of this rectangle.
Definition: qrect.h:845
bool event(QEvent *event)
Processes the event event, and dispatches it to the respective event handlers.
QPoint screenPos() const
Returns the position of the mouse cursor in screen coordinates at the moment the help event was sent...
void qSort(RandomAccessIterator start, RandomAccessIterator end)
Definition: qalgorithms.h:177
QInputContext * inputContext()
This function returns the QInputContext for this widget.
Definition: qwidget.cpp:474
bool contains(const QPoint &p, bool proper=false) const
Returns true if the given point is inside or on the edge of the rectangle, otherwise returns false...
Definition: qrect.cpp:1101
void installSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter)
void clearSubFocus(QGraphicsItem *rootItem=0, QGraphicsItem *stopItem=0)
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
QMap< Qt::MouseButton, QPointF > mouseGrabberButtonDownPos
QMap< Qt::GestureType, Qt::GestureFlags > gestureContext
void ensureSequentialTopLevelSiblingIndexes()
Ensures that the list of toplevels is sorted by insertion order, and that the siblingIndexes are pack...
bool isAncestorOf(const QGraphicsItem *child) const
Returns true if this item is an ancestor of child (i.e., if this item is child&#39;s parent, or one of child&#39;s parent&#39;s ancestors).
The QGraphicsProxyWidget class provides a proxy layer for embedding a QWidget in a QGraphicsScene...
bool testAttribute(Qt::WidgetAttribute attribute) const
Returns true if attribute is enabled for this widget; otherwise, returns false.
QPointF mapFromScene(const QPointF &point) const
Maps the point point, which is in this item&#39;s scene&#39;s coordinate system, to this item&#39;s coordinate sy...
void setMouseTracking(bool enable)
Definition: qwidget.h:990
QGraphicsItem * lastActivePanel
iterator begin()
Returns an STL-style iterator pointing to the first item in the map.
Definition: qmap.h:372
bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event)
void update(qreal x, qreal y, qreal w, qreal h)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Qt::DropAction proposedAction() const
Returns the drop action that is proposed, i.e., preferred.
QTransform deviceTransform(const QTransform &viewportTransform) const
Returns this item&#39;s device transformation matrix, using viewportTransform to map from scene to device...
void processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren=false, qreal parentOpacity=qreal(1.0))
const QBrush & brush() const
Returns the painter&#39;s current brush.
Definition: qpainter.cpp:4232
Qt::LayoutDirection layoutDirection() const
Returns the layout direction used by the painter when drawing text.
Definition: qpainter.cpp:8729
T & first()
Returns a reference to the first item in the list.
Definition: qlist.h:282
virtual void dragMoveEvent(QGraphicsSceneDragDropEvent *event)
This event handler, for event event, can be reimplemented in a subclass to receive drag move events f...
void fill(const QColor &fillColor=Qt::white)
Fills the pixmap with the given color.
Definition: qpixmap.cpp:1080
QEventPrivate * d
Definition: qcoreevent.h:315
bool isEmpty() const
Returns true if the rectangle is empty, otherwise returns false.
Definition: qrect.h:234
InputMethodQuery
Definition: qnamespace.h:1541
void setRenderHints(RenderHints hints, bool on=true)
Sets the given render hints on the painter if on is true; otherwise clears the render hints...
Definition: qpainter.cpp:7649
The QBrush class defines the fill pattern of shapes drawn by QPainter.
Definition: qbrush.h:76
The QInputMethodEvent class provides parameters for input method events.
Definition: qevent.h:431
bool autoFillBackground
whether the widget background is filled automatically
QGraphicsWidget * tabFocusFirst
const_iterator constBegin() const
Returns a const STL-style iterator pointing to the first item in the hash.
Definition: qhash.h:466
int remove(const Key &key)
Removes all the items that have the key key from the map.
Definition: qmap.h:662
bool isActive() const
Returns true if the scene is active (e.
void setCachedOffset(const QPoint &offset)
Qt::DropActions possibleActions() const
Returns the possible drop actions that the drag and drop can result in.
void setActivePanel(QGraphicsItem *item)
Activates item, which must be an item in this scene.
void ensureSequentialSiblingIndex()
Ensures that the list of children is sorted by insertion order, and that the siblingIndexes are packe...
const_iterator constEnd() const
Returns a const STL-style iterator pointing to the imaginary item after the last item in the hash...
Definition: qhash.h:469
void setFocus()
Gives the keyboard input focus to this widget (or its focus proxy) if this widget or one of its paren...
Definition: qwidget.h:432
OptimizationFlags optimizationFlags
flags that can be used to tune QGraphicsView&#39;s performance.
Definition: qgraphicsview.h:83
QPalette palette() const
bool contains(const Key &key, const T &value) const
Returns true if the map contains an item with key key and value value; otherwise returns false...
Definition: qmap.h:1048
The QGraphicsSimpleTextItem class provides a simple text path item that you can add to a QGraphicsSce...
QWidget * widget() const
Returns the widget on which the event occurred.
Definition: qevent.cpp:5047
The QGraphicsLineItem class provides a line item that you can add to a QGraphicsScene.
#define Q_ASSERT_X(cond, where, what)
Definition: qglobal.h:1837
void grabMouse(QGraphicsItem *item, bool implicit=false)
The QGraphicsSceneHelpEvent class provides events when a tooltip is requested.
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
QGraphicsItem * parentItem() const
Returns a pointer to this item&#39;s parent item.
bool isSignalConnected(uint signalIdx) const
Returns true if the signal with index signal_index from object sender is connected.
Definition: qobject_p.h:237
void selectionChanged()
This signal is emitted by QGraphicsScene whenever the selection changes.
CacheMode
This enum describes QGraphicsItem&#39;s cache modes.
void setLastScreenPos(const QPoint &pos)
QPointF scenePos() const
Returns the position of the cursor in scene coordinates when the wheel event occurred.
The QPixmapCache::Key class can be used for efficient access to the QPixmapCache. ...
Definition: qpixmapcache.h:61
void setClipRegion(const QRegion &, Qt::ClipOperation op=Qt::ReplaceClip)
Sets the clip region to the given region using the specified clip operation.
Definition: qpainter.cpp:2917
int indexOf(const T &t, int from=0) const
Returns the index position of the first occurrence of value in the list, searching forward from index...
Definition: qlist.h:847
const QTransform & worldTransform() const
Returns the world transformation matrix.
Definition: qpainter.cpp:9652
void setCompositionMode(CompositionMode mode)
Sets the composition mode to the given mode.
Definition: qpainter.cpp:2422
QFont font() const
void unregisterTopLevelItem(QGraphicsItem *item)
The QGraphicsSceneDragDropEvent class provides events for drag and drop in the graphics view framewor...
FocusReason
Definition: qnamespace.h:1521
The QMap::iterator class provides an STL-style non-const iterator for QMap and QMultiMap.
Definition: qmap.h:233
Type
This enum type defines the valid event types in Qt.
Definition: qcoreevent.h:62
QList< QGraphicsItem * > topLevelItems
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the hash...
Definition: qhash.h:467
QPoint lastScreenPos() const
Returns the last recorded mouse cursor position in screen coordinates.
QPointF scenePos() const
Returns the mouse cursor position in scene coordinates.
void leaveModal(QGraphicsItem *item)
QRect rect
the internal geometry of the widget excluding any window frame
Definition: qwidget.h:168
void cancelGesturesForChildren(QGesture *original)
virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const
This method is used by input methods to query a set of properties of the scene to be able to support ...
The QFont class specifies a font used for drawing text.
Definition: qfont.h:64
The QGesture class represents a gesture, containing properties that describe the corresponding user i...
Definition: qgesture.h:64
int y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:255
QHash< QGesture *, QGraphicsObject * > gestureTargets
void touchEventHandler(QTouchEvent *touchEvent)
QPixmapCache::Key key
bool isPanel() const
Returns true if the item is a panel; otherwise returns false.
QPointF hotSpot
The point that is used to find the receiver for the gesture event.
Definition: qgesture.h:72
Qt::GestureType gestureType
the type of the gesture
Definition: qgesture.h:70
QRect toRect() const
Returns the variant as a QRect if the variant has type() Rect ; otherwise returns an invalid QRect...
Definition: qvariant.cpp:2416
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the map...
Definition: qmap.h:375
void setActivePanelHelper(QGraphicsItem *item, bool duringActivationEvent)
QPoint toPoint() const
Rounds the coordinates of this point to the nearest integer, and returns a QPoint object with the rou...
Definition: qpoint.h:376
virtual void focusOutEvent(QFocusEvent *event)
This event handler, for event focusEvent, can be reimplemented in a subclass to receive focus out eve...
bool hasFocus() const
Returns true if the scene has focus; otherwise returns false.
QGraphicsRectItem * addRect(const QRectF &rect, const QPen &pen=QPen(), const QBrush &brush=QBrush())
Creates and adds a rectangle item to the scene, and returns the item pointer.
bool updateRegion(const QRectF &rect, const QTransform &xform)
QString toolTip() const
Returns the item&#39;s tool tip, or an empty QString if no tool tip has been set.
Type type() const
Returns the storage type of the value stored in the variant.
Definition: qvariant.cpp:1901
QList< QGraphicsItem * > hoverItems
bool updateRect(const QRect &rect)
void clearSelection()
Clears the current selection.
iterator insert(const Key &key, const T &value)
Inserts a new item with the key key and a value of value.
Definition: qmap.h:559
int x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:252
int toInt(bool *ok=0, int base=10) const
Returns the byte array converted to an int using base base, which is 10 by default and must be betwee...
void setPalette(const QPalette &palette)
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
void setLastScenePos(const QPointF &pos)
static bool insert(const QString &key, const QPixmap &pixmap)
Inserts a copy of the pixmap pixmap associated with the key into the cache.
void setDeviceType(DeviceType adeviceType)
Sets the device type to deviceType, which is of type QTouchEvent::DeviceType {DeviceType}.
Definition: qevent.h:824
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
QVector< QRect > rects() const
Returns an array of non-overlapping rectangles that make up the region.
Definition: qregion.cpp:4412
void setBrush(const QBrush &brush)
Sets the painter&#39;s brush to the given brush.
Definition: qpainter.cpp:4171
T & last()
Returns a reference to the last item in the list.
Definition: qlist.h:284
#define G_DEBUG
The QHash::iterator class provides an STL-style non-const iterator for QHash and QMultiHash.
Definition: qhash.h:330
const QList< QTouchEvent::TouchPoint > & touchPoints() const
Returns the list of touch points contained in the touch event.
Definition: qevent.h:820
unsigned int quint32
Definition: qglobal.h:938
QGraphicsScene(QObject *parent=0)
Constructs a QGraphicsScene object.
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
static bool pathToRect(const QPainterPath &path, QRectF *rect=0)
void setModifiers(Qt::KeyboardModifiers modifiers)
Sets the keyboard modifiers that were pressed when the event was created to modifiers.
The QStyle class is an abstract base class that encapsulates the look and feel of a GUI...
Definition: qstyle.h:68
void setWidget(QWidget *widget)
Sets the widget for this event to the widget specified.
Definition: qevent.cpp:5039
quint32 scenePosDescendantsUpdatePending
void setScreenPos(const QPoint &pos)
Sets the position associated with the hover event to the given point in screen coordinates.
QHash< QGraphicsObject *, QSet< QGesture * > > cachedItemGestures
void setPen(const QColor &color)
Sets the painter&#39;s pen to have style Qt::SolidLine, width 0 and the specified color.
Definition: qpainter.cpp:4047
QGraphicsWidget * window() const
Returns the item&#39;s window, or 0 if this item does not have a window.
void addToGroup(QGraphicsItem *item)
Adds the given item and item&#39;s child items to this item group.
void removeItemHelper(QGraphicsItem *item)
Schedules an item for removal.
void mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent)
int height() const
Returns the height.
Definition: qsize.h:129
if(void) toggleToolbarShown
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
bool isValid() const
Returns true if both the width and height is equal to or greater than 0; otherwise returns false...
Definition: qsize.h:123
Definition: qnamespace.h:54
QRect paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded=0) const
void leaveScene(QWidget *viewport)
Handles all actions necessary to clean up the scene when the mouse leaves the view.
bool isWidget() const
Returns true if this item is a widget (i.
virtual void reset()=0
This function can be reimplemented in a subclass to reset the state of the input method.
QFuture< void > filter(Sequence &sequence, FilterFunction filterFunction)
iterator begin()
Returns an STL-style iterator pointing to the first item in the hash.
Definition: qhash.h:464
virtual void resolveFont(uint inheritedMask)
QPoint buttonDownScreenPos(Qt::MouseButton button) const
Returns the mouse cursor position in screen coordinates where the specified button was clicked...
virtual bool contains(const QPointF &point) const
Returns true if this item contains point, which is in local coordinates; otherwise, false is returned.
bool isNull() const
Returns true if both the x and y coordinates are set to +0.
Definition: qpoint.h:277
Qt::FocusReason reason()
Definition: qevent.cpp:1197
bool contains(const Key &key) const
Returns true if the map contains an item with key key; otherwise returns false.
Definition: qmap.h:553
void setButtons(Qt::MouseButtons buttons)
Sets the mouse buttons that were pressed when the event was created to buttons.
void setWorldTransform(const QTransform &matrix, bool combine=false)
Sets the world transformation matrix.
Definition: qpainter.cpp:9630
T qvariant_cast(const QVariant &)
Definition: qvariant.h:571
ItemIndexMethod
This enum describes the indexing algorithms QGraphicsScene provides for managing positional informati...
void setProposedAction(Qt::DropAction action)
Sets the proposed action to action.
QGraphicsItem * lastMouseGrabberItem
QVector< QRectF > exposed
static void mouseEvent(MouseAction action, QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers stateKey, QPoint pos, int delay=-1)
Definition: qtestmouse.h:71
QPointF scenePos() const
Returns the position of the mouse in scene coordinates.
qreal dx() const
Returns the horizontal translation factor.
Definition: qtransform.h:273
void setPos(const QPointF &pos)
Sets the position associated with the hover event to the given point in item coordinates.
void drawRect(const QRectF &rect)
Draws the current rectangle with the current pen and brush.
Definition: qpainter.h:650
friend class QGraphicsSceneBspTreeIndex
QRect rect() const
Returns the pixmap&#39;s enclosing rectangle.
Definition: qpixmap.cpp:676
QMap< int, QTouchEvent::TouchPoint > sceneCurrentTouchPoints
int y() const
Returns the y coordinate of this point.
Definition: qpoint.h:131
void setAttribute(Qt::WidgetAttribute, bool on=true)
Sets the attribute attribute on this widget if on is true; otherwise clears the attribute.
Definition: qwidget.cpp:11087
qreal y() const
Returns the y-coordinate of this point.
Definition: qpoint.h:287
The QGraphicsItemGroup class provides a container that treats a group of items as a single item...
quint16 index
QPointF scenePos() const
Returns the position of the mouse cursor in scene coordinates at the moment the hover event was sent...
void resolveFont()
Resolve the scene&#39;s font against the application font, and propagate the changes too all items in the...
QPoint mapFromGlobal(const QPoint &) const
Translates the global screen coordinate pos to widget coordinates.
The QPixmap class is an off-screen image representation that can be used as a paint device...
Definition: qpixmap.h:71
QObject * parent
Definition: qobject.h:92
bool intersects(const QRegion &r) const
Returns true if this region intersects with region, otherwise returns false.
Definition: qregion.cpp:766
QGraphicsItemPaintInfo * info
The TouchPoint class provides information about a touch point in a QTouchEvent.
Definition: qevent.h:744
QScopedPointer< QObjectData > d_ptr
Definition: qobject.h:320
The QGraphicsView class provides a widget for displaying the contents of a QGraphicsScene.
Definition: qgraphicsview.h:64
QPointF pos() const
Returns the mouse cursor position in item coordinates.
QPointF buttonDownPos(Qt::MouseButton button) const
Returns the mouse cursor position in item coordinates where the specified button was clicked...
virtual ~QGraphicsScene()
Removes and deletes all items from the scene object before destroying the scene object.
bool isAccepted(QGesture *) const
Returns true if the gesture is accepted; otherwise returns false.
Definition: qevent.cpp:4968
qreal top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:526
iterator erase(iterator it)
Removes the (key, value) pair pointed to by the iterator pos from the map, and returns an iterator to...
Definition: qmap.h:717
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(0), 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())
Invokes the member (a signal or a slot name) on the object obj.
The QGraphicsSceneLinearIndex class provides an implementation of a linear indexing algorithm for dis...
void drawPixmap(const QRectF &targetRect, const QPixmap &pixmap, const QRectF &sourceRect)
Draws the rectangular portion source of the given pixmap into the given target in the paint device...
Definition: qpainter.cpp:5619
T takeLast()
Removes the last item in the list and returns it.
Definition: qlist.h:492
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget=0)=0
This function, which is usually called by QGraphicsView, paints the contents of an item in local coor...
iterator upperBound(const Key &key)
Returns an iterator pointing to the item that immediately follows the last item with key key in the m...
Definition: qmap.h:918
bool isVisibleTo(const QGraphicsItem *parent) const
Returns true if the item is visible to parent; otherwise, false is returned.
QGraphicsEffect::PixmapPadMode currentCachedMode() const
static Q_DECL_CONSTEXPR bool qFuzzyIsNull(double d)
Definition: qglobal.h:2043
Qt::KeyboardModifiers modifiers() const
Returns the keyboard modifiers in use at the time the event was sent.
QMetaMethod method(int index) const
Returns the meta-data for the method with the given index.
QList< QRectF > updatedRects
void ignore()
Clears the accept flag parameter of the event object, the equivalent of calling setAccepted(false).
Definition: qcoreevent.h:310
void accept()
Sets the accept flag of the event object, the equivalent of calling setAccepted(true).
Definition: qcoreevent.h:309
Qt::GestureState state
the current state of the gesture
Definition: qgesture.h:69
The QTouchEvent class contains parameters that describe a touch event.
Definition: qevent.h:741
static void remove(const QString &key)
Removes the pixmap associated with key from the cache.
QMap< QWidget *, QRect > paintedViewBoundingRects
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
void addPopup(QGraphicsWidget *widget)
static QTransform fromTranslate(qreal dx, qreal dy)
Creates a matrix which corresponds to a translation of dx along the x axis and dy along the y axis...
Definition: qtransform.cpp:462
QTransform & scale(qreal sx, qreal sy)
Scales the coordinate system by sx horizontally and sy vertically, and returns a reference to the mat...
Definition: qtransform.cpp:485
void setWidget(QWidget *awidget)
Definition: qevent.h:823
bool isEmpty() const
Returns true if the vector has size 0; otherwise returns false.
Definition: qvector.h:139
QGraphicsScene * scene() const
Returns the current scene for the item, or 0 if the item is not stored in a scene.
void gestureTargetsAtHotSpots(const QSet< QGesture *> &gestures, Qt::GestureFlag flag, QHash< QGraphicsObject *, QSet< QGesture *> > *targets, QSet< QGraphicsObject *> *itemsSet=0, QSet< QGesture *> *normal=0, QSet< QGesture *> *conflicts=0)
Qt::LayoutDirection layoutDirection
the layout direction for this widget.
bool intersects(const QRect &r) const
Returns true if this rectangle intersects with the given rectangle (i.
Definition: qrect.cpp:1429
RenderHints renderHints() const
Returns a flag that specifies the rendering hints that are set for this painter.
Definition: qpainter.cpp:7675
QPainterPath selectionArea() const
Returns the selection area that was previously set with setSelectionArea(), or an empty QPainterPath ...
void setClipPath(const QPainterPath &path, Qt::ClipOperation op=Qt::ReplaceClip)
Enables clipping, and sets the clip path for the painter to the given path, with the clip operation...
Definition: qpainter.cpp:3365
iterator lowerBound(const Key &key)
Returns an iterator pointing to the first item with key key in the map.
Definition: qmap.h:899
void ungrabGesture(Qt::GestureType type)
Unsubscribes the widget from a given gesture type.
Definition: qwidget.cpp:12977
int x() const
Returns the x coordinate of this point.
Definition: qpoint.h:128
QGraphicsProxyWidget * addWidget(QWidget *widget, Qt::WindowFlags wFlags=0)
Creates a new QGraphicsProxyWidget for widget, adds it to the scene, and returns a pointer to the pro...
void setLayoutDirection(Qt::LayoutDirection direction)
Sets the layout direction used by the painter when drawing text, to the specified direction...
Definition: qpainter.cpp:8717
QPoint lastScreenPos() const
Returns the last recorded mouse cursor position in screen coordinates.
qint64 verticalScroll() const
Returns the vertical scroll value (the X value of the top edge of the viewport).
void ungrabMouse()
Releases the mouse grab.
QGraphicsItemCache * extraItemCache() const
The QGraphicsSceneWheelEvent class provides wheel events in the graphics view framework.
void setOpacity(qreal opacity)
Sets the opacity of the painter to opacity.
Definition: qpainter.cpp:2139
QTouchEventSequence touchEvent(QWidget *widget=0, QTouchEvent::DeviceType deviceType=QTouchEvent::TouchScreen)
Creates and returns a QTouchEventSequence for the device deviceType to simulate events for widget...
Definition: qtesttouch.h:141
QGraphicsItem * lastFocusItem
QList< QGraphicsItem * > items() const
Returns a list of all the items in the associated scene, in descending stacking order (i...
virtual void drawItems(QPainter *painter, int numItems, QGraphicsItem *items[], const QStyleOptionGraphicsItem options[], QWidget *widget=0)
Paints the given items using the provided painter, after the background has been drawn, and before the foreground has been drawn.
void setModifiers(Qt::KeyboardModifiers amodifiers)
Sets the keyboard modifiers flags for this event.
Definition: qevent.h:80
bool isEmpty() const
Returns true if either of the width and height is less than or equal to 0; otherwise returns false...
Definition: qsize.h:120
QGraphicsSimpleTextItem * addSimpleText(const QString &text, const QFont &font=QFont())
Creates and adds a QGraphicsSimpleTextItem to the scene, and returns the item pointer.
virtual void dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
This event handler, for event event, can be reimplemented in a subclass to receive drag leave events ...
QList< QGraphicsItem * > children
void setSceneRect(const QRectF &rect)
bool isNull() const
Returns true if this is a null pixmap; otherwise returns false.
Definition: qpixmap.cpp:615
QRectF translated(qreal dx, qreal dy) const
Returns a copy of the rectangle that is translated dx along the x axis and dy along the y axis...
Definition: qrect.h:740
bool isEmpty() const
Returns true if the rectangle is empty, otherwise returns false.
Definition: qrect.h:658
QRectF exposedRect
the exposed rectangle, in item coordinates
Definition: qstyleoption.h:873
Qt::KeyboardModifiers modifiers() const
Returns the keyboard modifier flags that existed immediately before the event occurred.
Definition: qevent.h:79
void sendDragDropEvent(QGraphicsItem *item, QGraphicsSceneDragDropEvent *dragDropEvent)
PanelModality
This enum specifies the behavior of a modal panel.
void setTouchPoints(const QList< QTouchEvent::TouchPoint > &atouchPoints)
Sets the list of touch points for this event.
Definition: qevent.h:826
void translate(int dx, int dy)
Moves the rectangle dx along the x axis and dy along the y axis, relative to the current position...
Definition: qrect.h:312
static const KeyPair *const end
void setButtonDownScreenPos(Qt::MouseButton button, const QPoint &pos)
bool invoke(QObject *object, Qt::ConnectionType connectionType, QGenericReturnArgument returnValue, QGenericArgument val0=QGenericArgument(0), 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()) const
Invokes this method on the object object.
iterator erase(iterator i)
Definition: qset.h:172
The QGraphicsObject class provides a base class for all graphics items that require signals...
void markParentDirty(bool updateBoundingRect=false)
void ungrabKeyboard(QGraphicsItem *item, bool itemIsDying=false)
QGraphicsPathItem * addPath(const QPainterPath &path, const QPen &pen=QPen(), const QBrush &brush=QBrush())
Creates and adds a path item to the scene, and returns the item pointer.
Qt::FocusPolicy focusPolicy
the way the widget accepts keyboard focus
QList< QGraphicsItem * > collidingItems(const QGraphicsItem *item, Qt::ItemSelectionMode mode=Qt::IntersectsItemShape) const
Returns a list of all items that collide with item.
QGestureManager * gestureManager
bool sendEvent(QGraphicsItem *item, QEvent *event)
This is the final dispatch point for any events from the scene to the item.
void draw(QGraphicsItem *, QPainter *, const QTransform *const, const QTransform *const, QRegion *, QWidget *, qreal, const QTransform *const, bool, bool)
void setButton(Qt::MouseButton button)
QGraphicsPixmapItem * addPixmap(const QPixmap &pixmap)
Creates and adds a pixmap item to the scene, and returns the item pointer.
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event)
Filters events for the item watched.
Type type() const
Returns the event type.
Definition: qcoreevent.h:303
QGraphicsEffectSource * source() const
Returns a pointer to the source, which provides extra context information that can be useful for the ...
The QGraphicsPixmapItem class provides a pixmap item that you can add to a QGraphicsScene.
bool filterEvent(QGraphicsItem *item, QEvent *event)
The QStyleOptionGraphicsItem class is used to describe the parameters needed to draw a QGraphicsItem...
Definition: qstyleoption.h:867
virtual void deleteItem(QGraphicsItem *item)
This method is called when an item has been deleted.
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
void render(QPainter *painter, const QRectF &target=QRectF(), const QRectF &source=QRectF(), Qt::AspectRatioMode aspectRatioMode=Qt::KeepAspectRatio)
Renders the source rect from scene into target, using painter.
void setScreenPos(const QPoint &pos)
Sets the mouse position relative to the screen to pos.
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
const QBrush & window() const
Returns the window (general background) brush of the current color group.
Definition: qpalette.h:135
void resetDirtyItem(QGraphicsItem *item, bool recursive=false)
QGraphicsItem * activePanel
qreal width() const
This convenience function is equivalent to calling sceneRect().
bool hasHotSpot
whether the gesture has a hot-spot
Definition: qgesture.h:73
bool isNull() const
Returns true if the rectangle is a null rectangle, otherwise returns false.
Definition: qrect.h:655
QMultiMap< QGraphicsItem *, QGraphicsItem * > sceneEventFilters
QRectF sceneBoundingRect() const
Returns the bounding rect of this item in scene coordinates, by combining sceneTransform() with bound...
iterator erase(iterator it)
Removes the (key, value) pair associated with the iterator pos from the hash, and returns an iterator...
Definition: qhash.h:827
The QMetaMethod class provides meta-data about a member function.
Definition: qmetaobject.h:56
void setFocusItemHelper(QGraphicsItem *item, Qt::FocusReason focusReason)
QList< QGraphicsItem * > children() const
Use childItems() instead.
int bspTreeDepth() const
#define enabled
The QFocusEvent class contains event parameters for widget focus events.
Definition: qevent.h:275
void setBrush(const QBrush &brush)
Sets the item&#39;s brush to brush.
QPoint toPoint() const
Returns the variant as a QPoint if the variant has type() Point or PointF ; otherwise returns a null ...
Definition: qvariant.cpp:2400
QHash< QGraphicsObject *, QSet< QGesture * > > cachedAlreadyDeliveredGestures
bool childrenCombineOpacity() const
virtual const QMetaObject * metaObject() const
Returns a pointer to the meta-object of this object.
bool discardUpdateRequest(bool ignoreVisibleBit=false, bool ignoreDirtyBit=false, bool ignoreOpacity=false) const
Returns true if we can discard an update request; otherwise false.
bool end()
Ends painting.
Definition: qpainter.cpp:1929
QPointF lastPos() const
Returns the last recorded mouse cursor position in item coordinates.
virtual void draw(QPainter *painter)=0
This pure virtual function draws the effect and is called whenever the source needs to be drawn...
QWidget * widget() const
Returns a pointer to the embedded widget.
The QMap class is a template class that provides a skip-list-based dictionary.
Definition: qdatastream.h:67
qreal m11() const
Returns the horizontal scaling factor.
Definition: qtransform.h:237
void fillRect(const QRectF &, const QBrush &)
Fills the given rectangle with the brush specified.
Definition: qpainter.cpp:7420
void setLastPos(const QPointF &pos)
Qt::MouseButtons buttons() const
Returns the combination of mouse buttons that were pressed at the time the event was sent...
#define text
Definition: qobjectdefs.h:80
static QPoint pos()
Returns the position of the cursor (hot spot) in global screen coordinates.
Definition: qcursor_mac.mm:310
void setScenePos(const QPointF &pos)
Sets the position associated with the hover event to the given point in scene coordinates.
QRectF itemsBoundingRect() const
Calculates and returns the bounding rect of all items on the scene.
virtual void wheelEvent(QGraphicsSceneWheelEvent *event)
This event handler, for event wheelEvent, can be reimplemented in a subclass to receive mouse wheel e...
The QTransform class specifies 2D transformations of a coordinate system.
Definition: qtransform.h:65
QPointF pos() const
Returns the mouse position of the event relative to the view that sent the event. ...
The QGraphicsPathItem class provides a path item that you can add to a QGraphicsScene.
QList< QGraphicsWidget * > popupWidgets
The QGraphicsSceneHoverEvent class provides hover events in the graphics view framework.
QPalette resolve(const QPalette &) const
Returns a new QPalette that has attributes copied from other.
Definition: qpalette.cpp:1101
int signalIndex(const char *signalName) const
Returns the signal index used in the internal connectionLists vector.
Definition: qobject.cpp:3719
QPoint topLeft() const
Returns the position of the rectangle&#39;s top-left corner.
Definition: qrect.h:288
Qt::MouseButtons acceptedMouseButtons() const
Returns the mouse buttons that this item accepts mouse events for.
int removeAll(const T &t)
Removes all occurrences of value in the list and returns the number of entries removed.
Definition: qlist.h:770
static void showText(const QPoint &pos, const QString &text, QWidget *w=0)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qtooltip.cpp:497
MouseButton
Definition: qnamespace.h:150
The QGraphicsWidget class is the base class for all widget items in a QGraphicsScene.
AspectRatioMode
Definition: qnamespace.h:1317
void setFocus(Qt::FocusReason focusReason=Qt::OtherFocusReason)
Gives keyboard input focus to this item.
void translate(const QPointF &offset)
Translates the coordinate system by the given offset; i.e.
Definition: qpainter.cpp:3311
void setItemIndexMethod(ItemIndexMethod method)
The QGraphicsSceneContextMenuEvent class provides context menu events in the graphics view framework...
quint32 lastMouseGrabberItemHasImplicitMouseGrab
The QPalette class contains color groups for each widget state.
Definition: qpalette.h:61
void removeAt(int i)
Removes the item at index position i.
Definition: qlist.h:480
bool sendTouchBeginEvent(QGraphicsItem *item, QTouchEvent *touchEvent)