src/gui/graphicsview/qgraphicsview.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
   279 #include <QtGui/qpainter.h>
   279 #include <QtGui/qpainter.h>
   280 #include <QtGui/qscrollbar.h>
   280 #include <QtGui/qscrollbar.h>
   281 #include <QtGui/qstyleoption.h>
   281 #include <QtGui/qstyleoption.h>
   282 #include <QtGui/qinputcontext.h>
   282 #include <QtGui/qinputcontext.h>
   283 #ifdef Q_WS_X11
   283 #ifdef Q_WS_X11
       
   284 #include <QtGui/qpaintengine.h>
   284 #include <private/qt_x11_p.h>
   285 #include <private/qt_x11_p.h>
   285 #endif
   286 #endif
   286 
   287 
   287 #include <private/qevent_p.h>
   288 #include <private/qevent_p.h>
   288 
   289 
   542     return scrollY;
   543     return scrollY;
   543 }
   544 }
   544 
   545 
   545 /*!
   546 /*!
   546     \internal
   547     \internal
       
   548 
       
   549     Maps the given rectangle to the scene using QTransform::mapRect()
       
   550 */
       
   551 QRectF QGraphicsViewPrivate::mapRectToScene(const QRect &rect) const
       
   552 {
       
   553     if (dirtyScroll)
       
   554         const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
       
   555     QRectF scrolled = QRectF(rect.translated(scrollX, scrollY));
       
   556     return identityMatrix ? scrolled : matrix.inverted().mapRect(scrolled);
       
   557 }
       
   558 
       
   559 
       
   560 /*!
       
   561     \internal
       
   562 
       
   563     Maps the given rectangle from the scene using QTransform::mapRect()
       
   564 */
       
   565 QRectF QGraphicsViewPrivate::mapRectFromScene(const QRectF &rect) const
       
   566 {
       
   567     if (dirtyScroll)
       
   568         const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
       
   569     return (identityMatrix ? rect : matrix.mapRect(rect)).translated(-scrollX, -scrollY);
       
   570 }
       
   571 
       
   572 /*!
       
   573     \internal
   547 */
   574 */
   548 void QGraphicsViewPrivate::updateScroll()
   575 void QGraphicsViewPrivate::updateScroll()
   549 {
   576 {
   550     Q_Q(QGraphicsView);
   577     Q_Q(QGraphicsView);
   551     scrollX = qint64(-leftIndent);
   578     scrollX = qint64(-leftIndent);
   975     }
  1002     }
   976 
  1003 
   977     // Step 2) If the expose region is a simple rect and the view is only
  1004     // Step 2) If the expose region is a simple rect and the view is only
   978     // translated or scaled, search for items using
  1005     // translated or scaled, search for items using
   979     // QGraphicsScene::items(QRectF).
  1006     // QGraphicsScene::items(QRectF).
   980     bool simpleRectLookup =  exposedRegion.numRects() == 1 && matrix.type() <= QTransform::TxScale;
  1007     bool simpleRectLookup =  exposedRegion.rectCount() == 1 && matrix.type() <= QTransform::TxScale;
   981     if (simpleRectLookup) {
  1008     if (simpleRectLookup) {
   982         return scene->items(exposedRegionSceneBounds,
  1009         return scene->items(exposedRegionSceneBounds,
   983                             Qt::IntersectsItemBoundingRect,
  1010                             Qt::IntersectsItemBoundingRect,
   984                             Qt::AscendingOrder, viewTransform);
  1011                             Qt::AscendingOrder, viewTransform);
   985     }
  1012     }
  1179 }
  1206 }
  1180 void QGraphicsView::setTransformationAnchor(ViewportAnchor anchor)
  1207 void QGraphicsView::setTransformationAnchor(ViewportAnchor anchor)
  1181 {
  1208 {
  1182     Q_D(QGraphicsView);
  1209     Q_D(QGraphicsView);
  1183     d->transformationAnchor = anchor;
  1210     d->transformationAnchor = anchor;
       
  1211 
       
  1212     // Ensure mouse tracking is enabled in the case we are using AnchorUnderMouse
       
  1213     // in order to have up-to-date information for centering the view.
       
  1214     if (d->transformationAnchor == AnchorUnderMouse)
       
  1215         d->viewport->setMouseTracking(true);
  1184 }
  1216 }
  1185 
  1217 
  1186 /*!
  1218 /*!
  1187     \property QGraphicsView::resizeAnchor
  1219     \property QGraphicsView::resizeAnchor
  1188     \brief how the view should position the scene when the view is resized.
  1220     \brief how the view should position the scene when the view is resized.
  1206 }
  1238 }
  1207 void QGraphicsView::setResizeAnchor(ViewportAnchor anchor)
  1239 void QGraphicsView::setResizeAnchor(ViewportAnchor anchor)
  1208 {
  1240 {
  1209     Q_D(QGraphicsView);
  1241     Q_D(QGraphicsView);
  1210     d->resizeAnchor = anchor;
  1242     d->resizeAnchor = anchor;
       
  1243 
       
  1244     // Ensure mouse tracking is enabled in the case we are using AnchorUnderMouse
       
  1245     // in order to have up-to-date information for centering the view.
       
  1246     if (d->resizeAnchor == AnchorUnderMouse)
       
  1247         d->viewport->setMouseTracking(true);
  1211 }
  1248 }
  1212 
  1249 
  1213 /*!
  1250 /*!
  1214     \property QGraphicsView::viewportUpdateMode
  1251     \property QGraphicsView::viewportUpdateMode
  1215     \brief how the viewport should update its contents.
  1252     \brief how the viewport should update its contents.
  1509                    this, SLOT(updateScene(QList<QRectF>)));
  1546                    this, SLOT(updateScene(QList<QRectF>)));
  1510         disconnect(d->scene, SIGNAL(sceneRectChanged(QRectF)),
  1547         disconnect(d->scene, SIGNAL(sceneRectChanged(QRectF)),
  1511                    this, SLOT(updateSceneRect(QRectF)));
  1548                    this, SLOT(updateSceneRect(QRectF)));
  1512         d->scene->d_func()->removeView(this);
  1549         d->scene->d_func()->removeView(this);
  1513         d->connectedToScene = false;
  1550         d->connectedToScene = false;
       
  1551 
       
  1552         if (isActiveWindow() && isVisible()) {
       
  1553             QEvent windowDeactivate(QEvent::WindowDeactivate);
       
  1554             QApplication::sendEvent(d->scene, &windowDeactivate);
       
  1555         }
       
  1556         if(hasFocus())
       
  1557             d->scene->clearFocus();
  1514     }
  1558     }
  1515 
  1559 
  1516     // Assign the new scene and update the contents (scrollbars, etc.)).
  1560     // Assign the new scene and update the contents (scrollbars, etc.)).
  1517     if ((d->scene = scene)) {
  1561     if ((d->scene = scene)) {
  1518         connect(d->scene, SIGNAL(sceneRectChanged(QRectF)),
  1562         connect(d->scene, SIGNAL(sceneRectChanged(QRectF)),
  1530         }
  1574         }
  1531 
  1575 
  1532         // enable touch events if any items is interested in them
  1576         // enable touch events if any items is interested in them
  1533         if (!d->scene->d_func()->allItemsIgnoreTouchEvents)
  1577         if (!d->scene->d_func()->allItemsIgnoreTouchEvents)
  1534             d->viewport->setAttribute(Qt::WA_AcceptTouchEvents);
  1578             d->viewport->setAttribute(Qt::WA_AcceptTouchEvents);
       
  1579 
       
  1580         if (isActiveWindow() && isVisible()) {
       
  1581             QEvent windowActivate(QEvent::WindowActivate);
       
  1582             QApplication::sendEvent(d->scene, &windowActivate);
       
  1583         }
  1535     } else {
  1584     } else {
  1536         d->recalculateContentSize();
  1585         d->recalculateContentSize();
  1537     }
  1586     }
  1538 
  1587 
  1539     d->updateInputMethodSensitivity();
  1588     d->updateInputMethodSensitivity();
  2556         // autoFillBackground enables scroll acceleration.
  2605         // autoFillBackground enables scroll acceleration.
  2557         widget->setAutoFillBackground(true);
  2606         widget->setAutoFillBackground(true);
  2558     }
  2607     }
  2559 
  2608 
  2560     // We are only interested in mouse tracking if items
  2609     // We are only interested in mouse tracking if items
  2561     // accept hover events or use non-default cursors.
  2610     // accept hover events or use non-default cursors or if
  2562     if (d->scene && (!d->scene->d_func()->allItemsIgnoreHoverEvents
  2611     // AnchorUnderMouse is used as transformation or resize anchor.
  2563                      || !d->scene->d_func()->allItemsUseDefaultCursor)) {
  2612     if ((d->scene && (!d->scene->d_func()->allItemsIgnoreHoverEvents
       
  2613                      || !d->scene->d_func()->allItemsUseDefaultCursor))
       
  2614         || d->transformationAnchor == AnchorUnderMouse
       
  2615         || d->resizeAnchor == AnchorUnderMouse) {
  2564         widget->setMouseTracking(true);
  2616         widget->setMouseTracking(true);
  2565     }
  2617     }
  2566 
  2618 
  2567     // enable touch events if any items is interested in them
  2619     // enable touch events if any items is interested in them
  2568     if (d->scene && !d->scene->d_func()->allItemsIgnoreTouchEvents)
  2620     if (d->scene && !d->scene->d_func()->allItemsIgnoreTouchEvents)
  2635         // Remove all popups when the scene loses focus.
  2687         // Remove all popups when the scene loses focus.
  2636         if (!d->scene->d_func()->popupWidgets.isEmpty())
  2688         if (!d->scene->d_func()->popupWidgets.isEmpty())
  2637             d->scene->d_func()->removePopup(d->scene->d_func()->popupWidgets.first());
  2689             d->scene->d_func()->removePopup(d->scene->d_func()->popupWidgets.first());
  2638         QApplication::sendEvent(d->scene, event);
  2690         QApplication::sendEvent(d->scene, event);
  2639         break;
  2691         break;
       
  2692     case QEvent::Show:
       
  2693         if (d->scene && isActiveWindow()) {
       
  2694             QEvent windowActivate(QEvent::WindowActivate);
       
  2695             QApplication::sendEvent(d->scene, &windowActivate);
       
  2696         }
       
  2697         break;
       
  2698     case QEvent::Hide:
       
  2699         // spontaneous event will generate a WindowDeactivate.
       
  2700         if (!event->spontaneous() && d->scene && isActiveWindow()) {
       
  2701             QEvent windowDeactivate(QEvent::WindowDeactivate);
       
  2702             QApplication::sendEvent(d->scene, &windowDeactivate);
       
  2703         }
       
  2704         break;
  2640     case QEvent::Leave:
  2705     case QEvent::Leave:
  2641         // ### This is a temporary fix for until we get proper mouse grab
  2706         // ### This is a temporary fix for until we get proper mouse grab
  2642         // events. activeMouseGrabberItem should be set to 0 if we lose the
  2707         // events. activeMouseGrabberItem should be set to 0 if we lose the
  2643         // mouse grab.
  2708         // mouse grab.
  2644         if ((QApplication::activePopupWidget() && QApplication::activePopupWidget() != window())
  2709         if ((QApplication::activePopupWidget() && QApplication::activePopupWidget() != window())
  3292         if (!d->backgroundPixmapExposed.isEmpty()) {
  3357         if (!d->backgroundPixmapExposed.isEmpty()) {
  3293             QPainter backgroundPainter(&d->backgroundPixmap);
  3358             QPainter backgroundPainter(&d->backgroundPixmap);
  3294             backgroundPainter.setClipRegion(d->backgroundPixmapExposed, Qt::ReplaceClip);
  3359             backgroundPainter.setClipRegion(d->backgroundPixmapExposed, Qt::ReplaceClip);
  3295             if (viewTransformed)
  3360             if (viewTransformed)
  3296                 backgroundPainter.setTransform(viewTransform);
  3361                 backgroundPainter.setTransform(viewTransform);
  3297             backgroundPainter.setCompositionMode(QPainter::CompositionMode_Source);
  3362 #ifdef Q_WS_X11
       
  3363 #undef X11
       
  3364             if (backgroundPainter.paintEngine()->type() != QPaintEngine::X11)
       
  3365 #define X11 qt_x11Data
       
  3366 #endif
       
  3367                 backgroundPainter.setCompositionMode(QPainter::CompositionMode_Source);
  3298             drawBackground(&backgroundPainter, exposedSceneRect);
  3368             drawBackground(&backgroundPainter, exposedSceneRect);
  3299             d->backgroundPixmapExposed = QRegion();
  3369             d->backgroundPixmapExposed = QRegion();
  3300         }
  3370         }
  3301 
  3371 
  3302         // Blit the background from the background pixmap
  3372         // Blit the background from the background pixmap
  3317 
  3387 
  3318     // Items
  3388     // Items
  3319     if (!(d->optimizationFlags & IndirectPainting)) {
  3389     if (!(d->optimizationFlags & IndirectPainting)) {
  3320         d->scene->d_func()->drawItems(&painter, viewTransformed ? &viewTransform : 0,
  3390         d->scene->d_func()->drawItems(&painter, viewTransformed ? &viewTransform : 0,
  3321                                       &d->exposedRegion, viewport());
  3391                                       &d->exposedRegion, viewport());
       
  3392         // Make sure the painter's world transform is restored correctly when
       
  3393         // drawing without painter state protection (DontSavePainterState).
       
  3394         // We only change the worldTransform() so there's no need to do a full-blown
       
  3395         // save() and restore(). Also note that we don't have to do this in case of
       
  3396         // IndirectPainting (the else branch), because in that case we always save()
       
  3397         // and restore() in QGraphicsScene::drawItems().
       
  3398         if (!d->scene->d_func()->painterStateProtection)
       
  3399             painter.setWorldTransform(viewTransform);
  3322     } else {
  3400     } else {
  3323         // Find all exposed items
  3401         // Find all exposed items
  3324         bool allItems = false;
  3402         bool allItems = false;
  3325         QList<QGraphicsItem *> itemList = d->findItems(d->exposedRegion, &allItems, viewTransform);
  3403         QList<QGraphicsItem *> itemList = d->findItems(d->exposedRegion, &allItems, viewTransform);
  3326         if (!itemList.isEmpty()) {
  3404         if (!itemList.isEmpty()) {