Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/graphicsview/qgraphicsview.cpp

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    5454    QGraphicsView visualizes the contents of a QGraphicsScene in a scrollable
    5555    viewport. To create a scene with geometrical items, see QGraphicsScene's
    56     documentation. QGraphicsView is part of \l{The Graphics View Framework}.
     56    documentation. QGraphicsView is part of the \l{Graphics View Framework}.
    5757
    5858    To visualize a scene, you start by constructing a QGraphicsView object,
     
    328328      sceneInteractionAllowed(true), hasSceneRect(false),
    329329      connectedToScene(false),
    330       mousePressButton(Qt::NoButton),
     330      useLastMouseEvent(false),
    331331      identityMatrix(true),
    332332      dirtyScroll(true),
    333333      accelerateScrolling(true),
     334      keepLastCenterPoint(true),
     335      transforming(false),
     336      handScrolling(false),
     337      mustAllocateStyleOptions(false),
     338      mustResizeBackgroundPixmap(true),
     339      fullUpdatePending(true),
     340      hasUpdateClip(false),
     341      mousePressButton(Qt::NoButton),
    334342      leftIndent(0), topIndent(0),
    335343      lastMouseEvent(QEvent::None, QPoint(), Qt::NoButton, 0, 0),
    336       useLastMouseEvent(false),
    337       keepLastCenterPoint(true),
    338344      alignment(Qt::AlignCenter),
    339       transforming(false),
    340345      transformationAnchor(QGraphicsView::AnchorViewCenter), resizeAnchor(QGraphicsView::NoAnchor),
    341346      viewportUpdateMode(QGraphicsView::MinimalViewportUpdate),
     
    346351      rubberBandSelectionMode(Qt::IntersectsItemShape),
    347352#endif
    348       handScrolling(false), handScrollMotions(0), cacheMode(0),
    349       mustAllocateStyleOptions(false),
    350       mustResizeBackgroundPixmap(true),
     353      handScrollMotions(0), cacheMode(0),
    351354#ifndef QT_NO_CURSOR
    352355      hasStoredOriginalCursor(false),
    353356#endif
    354357      lastDragDropEvent(0),
    355       fullUpdatePending(true),
    356358      updateSceneSlotReimplementedChecked(false)
    357359{
     
    734736
    735737    // Restore the original viewport cursor.
    736     hasStoredOriginalCursor = false;
    737     if (dragMode == QGraphicsView::ScrollHandDrag)
    738         viewport->setCursor(Qt::OpenHandCursor);
    739     else
    740         viewport->setCursor(originalCursor);
     738    if (hasStoredOriginalCursor) {
     739        hasStoredOriginalCursor = false;
     740        if (dragMode == QGraphicsView::ScrollHandDrag)
     741            viewport->setCursor(Qt::OpenHandCursor);
     742        else
     743            viewport->setCursor(originalCursor);
     744    }
    741745}
    742746#endif
     
    853857        viewport->update();
    854858    } else if (viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate) {
    855         if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
    856             viewport->update(dirtyBoundingRect.adjusted(-1, -1, 1, 1));
    857         else
    858             viewport->update(dirtyBoundingRect.adjusted(-2, -2, 2, 2));
     859        viewport->update(dirtyBoundingRect);
    859860    } else {
    860861        viewport->update(dirtyRegion); // Already adjusted in updateRect/Region.
     
    881882}
    882883
    883 bool QGraphicsViewPrivate::updateRegion(const QRegion &r)
    884 {
    885     if (fullUpdatePending || viewportUpdateMode == QGraphicsView::NoViewportUpdate || r.isEmpty())
     884/*
     885   Calling this function results in update rects being clipped to the item's
     886   bounding rect. Note that updates prior to this function call is not clipped.
     887   The clip is removed by passing 0.
     888*/
     889void QGraphicsViewPrivate::setUpdateClip(QGraphicsItem *item)
     890{
     891    Q_Q(QGraphicsView);
     892    // We simply ignore the request if the update mode is either FullViewportUpdate
     893    // or NoViewportUpdate; in that case there's no point in clipping anything.
     894    if (!item || viewportUpdateMode == QGraphicsView::NoViewportUpdate
     895        || viewportUpdateMode == QGraphicsView::FullViewportUpdate) {
     896        hasUpdateClip = false;
     897        return;
     898    }
     899
     900    // Calculate the clip (item's bounding rect in view coordinates).
     901    // Optimized version of:
     902    // QRect clip = item->deviceTransform(q->viewportTransform())
     903    //              .mapRect(item->boundingRect()).toAlignedRect();
     904    QRect clip;
     905    if (item->d_ptr->itemIsUntransformable()) {
     906        QTransform xform = item->deviceTransform(q->viewportTransform());
     907        clip = xform.mapRect(item->boundingRect()).toAlignedRect();
     908    } else if (item->d_ptr->sceneTransformTranslateOnly && identityMatrix) {
     909        QRectF r(item->boundingRect());
     910        r.translate(item->d_ptr->sceneTransform.dx() - horizontalScroll(),
     911                    item->d_ptr->sceneTransform.dy() - verticalScroll());
     912        clip = r.toAlignedRect();
     913    } else if (!q->isTransformed()) {
     914        clip = item->d_ptr->sceneTransform.mapRect(item->boundingRect()).toAlignedRect();
     915    } else {
     916        QTransform xform = item->d_ptr->sceneTransform;
     917        xform *= q->viewportTransform();
     918        clip = xform.mapRect(item->boundingRect()).toAlignedRect();
     919    }
     920
     921    if (hasUpdateClip) {
     922        // Intersect with old clip.
     923        updateClip &= clip;
     924    } else {
     925        updateClip = clip;
     926        hasUpdateClip = true;
     927    }
     928}
     929
     930bool QGraphicsViewPrivate::updateRegion(const QRectF &rect, const QTransform &xform)
     931{
     932    if (rect.isEmpty())
    886933        return false;
    887934
    888     const QRect boundingRect = r.boundingRect();
    889     if (!intersectsViewport(boundingRect, viewport->width(), viewport->height()))
    890         return false; // Update region outside viewport.
     935    if (viewportUpdateMode != QGraphicsView::MinimalViewportUpdate
     936        && viewportUpdateMode != QGraphicsView::SmartViewportUpdate) {
     937        // No point in updating with QRegion granularity; use the rect instead.
     938        return updateRectF(xform.mapRect(rect));
     939    }
     940
     941    // Update mode is either Minimal or Smart, so we have to do a potentially slow operation,
     942    // which is clearly documented here: QGraphicsItem::setBoundingRegionGranularity.
     943    const QRegion region = xform.map(QRegion(rect.toAlignedRect()));
     944    QRect viewRect = region.boundingRect();
     945    const bool dontAdjustForAntialiasing = optimizationFlags & QGraphicsView::DontAdjustForAntialiasing;
     946    if (dontAdjustForAntialiasing)
     947        viewRect.adjust(-1, -1, 1, 1);
     948    else
     949        viewRect.adjust(-2, -2, 2, 2);
     950    if (!intersectsViewport(viewRect, viewport->width(), viewport->height()))
     951        return false; // Update region for sure outside viewport.
     952
     953    const QVector<QRect> &rects = region.rects();
     954    for (int i = 0; i < rects.size(); ++i) {
     955        viewRect = rects.at(i);
     956        if (dontAdjustForAntialiasing)
     957            viewRect.adjust(-1, -1, 1, 1);
     958        else
     959            viewRect.adjust(-2, -2, 2, 2);
     960        if (hasUpdateClip)
     961            viewRect &= updateClip;
     962        dirtyRegion += viewRect;
     963    }
     964
     965    return true;
     966}
     967
     968// NB! Assumes the rect 'r' is already aligned and adjusted for antialiasing.
     969// For QRectF use updateRectF(const QRectF &) to ensure proper adjustments.
     970bool QGraphicsViewPrivate::updateRect(const QRect &r)
     971{
     972    if (fullUpdatePending || viewportUpdateMode == QGraphicsView::NoViewportUpdate
     973        || !intersectsViewport(r, viewport->width(), viewport->height())) {
     974        return false;
     975    }
    891976
    892977    switch (viewportUpdateMode) {
     
    896981        break;
    897982    case QGraphicsView::BoundingRectViewportUpdate:
    898         QRect_unite(&dirtyBoundingRect, boundingRect);
     983        if (hasUpdateClip)
     984            QRect_unite(&dirtyBoundingRect, r & updateClip);
     985        else
     986            QRect_unite(&dirtyBoundingRect, r);
    899987        if (containsViewport(dirtyBoundingRect, viewport->width(), viewport->height())) {
    900988            fullUpdatePending = true;
     
    904992    case QGraphicsView::SmartViewportUpdate: // ### DEPRECATE
    905993    case QGraphicsView::MinimalViewportUpdate:
    906     {
    907         const QVector<QRect> &rects = r.rects();
    908         for (int i = 0; i < rects.size(); ++i) {
    909             if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
    910                 dirtyRegion += rects.at(i).adjusted(-1, -1, 1, 1);
    911             else
    912                 dirtyRegion += rects.at(i).adjusted(-2, -2, 2, 2);
    913         }
    914         break;
    915     }
    916     default:
    917         break;
    918     }
    919 
    920     return true;
    921 }
    922 
    923 bool QGraphicsViewPrivate::updateRect(const QRect &r)
    924 {
    925     if (fullUpdatePending || viewportUpdateMode == QGraphicsView::NoViewportUpdate
    926         || !intersectsViewport(r, viewport->width(), viewport->height())) {
    927         return false;
    928     }
    929 
    930     switch (viewportUpdateMode) {
    931     case QGraphicsView::FullViewportUpdate:
    932         fullUpdatePending = true;
    933         viewport->update();
    934         break;
    935     case QGraphicsView::BoundingRectViewportUpdate:
    936         QRect_unite(&dirtyBoundingRect, r);
    937         if (containsViewport(dirtyBoundingRect, viewport->width(), viewport->height())) {
    938             fullUpdatePending = true;
    939             viewport->update();
    940         }
    941         break;
    942     case QGraphicsView::SmartViewportUpdate: // ### DEPRECATE
    943     case QGraphicsView::MinimalViewportUpdate:
    944         if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
    945             dirtyRegion += r.adjusted(-1, -1, 1, 1);
     994        if (hasUpdateClip)
     995            dirtyRegion += r & updateClip;
    946996        else
    947             dirtyRegion += r.adjusted(-2, -2, 2, 2);
     997            dirtyRegion += r;
    948998        break;
    949999    default:
     
    10361086{
    10371087    Q_Q(QGraphicsView);
    1038     bool enabled = scene && scene->focusItem()
    1039                    && (scene->focusItem()->flags() & QGraphicsItem::ItemAcceptsInputMethod);
     1088    QGraphicsItem *focusItem = 0;
     1089    bool enabled = scene && (focusItem = scene->focusItem())
     1090                   && (focusItem->d_ptr->flags & QGraphicsItem::ItemAcceptsInputMethod);
    10401091    q->setAttribute(Qt::WA_InputMethodEnabled, enabled);
    10411092    q->viewport()->setAttribute(Qt::WA_InputMethodEnabled, enabled);
     1093
     1094    if (!enabled) {
     1095        q->setInputMethodHints(0);
     1096        return;
     1097    }
     1098
     1099    QGraphicsProxyWidget *proxy = focusItem->d_ptr->isWidget && focusItem->d_ptr->isProxyWidget()
     1100                                    ? static_cast<QGraphicsProxyWidget *>(focusItem) : 0;
     1101    if (!proxy) {
     1102        q->setInputMethodHints(focusItem->inputMethodHints());
     1103    } else if (QWidget *widget = proxy->widget()) {
     1104    if (QWidget *fw = widget->focusWidget())
     1105        widget = fw;
     1106        q->setInputMethodHints(widget->inputMethodHints());
     1107    } else {
     1108        q->setInputMethodHints(0);
     1109    }
    10421110}
    10431111
     
    18081876{
    18091877    Q_D(QGraphicsView);
    1810     Q_UNUSED(xmargin);
    1811     Q_UNUSED(ymargin);
    18121878    qreal width = viewport()->width();
    18131879    qreal height = viewport()->height();
     
    24292495    QVariant value = d->scene->inputMethodQuery(query);
    24302496    if (value.type() == QVariant::RectF)
    2431         value = mapFromScene(value.toRectF()).boundingRect();
     2497        value = d->mapRectFromScene(value.toRectF());
    24322498    else if (value.type() == QVariant::PointF)
    24332499        value = mapFromScene(value.toPointF());
     
    25312597    // Convert scene rects to viewport rects.
    25322598    foreach (const QRectF &rect, rects) {
    2533         QRect xrect = transform.mapRect(rect).toRect();
     2599        QRect xrect = transform.mapRect(rect).toAlignedRect();
    25342600        if (!(d->optimizationFlags & DontAdjustForAntialiasing))
    25352601            xrect.adjust(-2, -2, 2, 2);
     2602        else
     2603            xrect.adjust(-1, -1, 1, 1);
    25362604        if (!viewportRect.intersects(xrect))
    25372605            continue;
     
    26222690    if (d->scene && !d->scene->d_func()->allItemsIgnoreTouchEvents)
    26232691        widget->setAttribute(Qt::WA_AcceptTouchEvents);
     2692
     2693#ifndef QT_NO_GESTURES
     2694    if (d->scene) {
     2695        foreach (Qt::GestureType gesture, d->scene->d_func()->grabbedGestures.keys())
     2696            widget->grabGesture(gesture);
     2697    }
     2698#endif
    26242699
    26252700    widget->setAcceptDrops(acceptDrops());
     
    27682843        return true;
    27692844    }
     2845#ifndef QT_NO_GESTURES
    27702846    case QEvent::Gesture:
    27712847    case QEvent::GestureOverride:
     
    27812857        return true;
    27822858    }
     2859#endif // QT_NO_GESTURES
    27832860    default:
    27842861        break;
     
    33843461    // Items
    33853462    if (!(d->optimizationFlags & IndirectPainting)) {
     3463        const quint32 oldRectAdjust = d->scene->d_func()->rectAdjust;
     3464        if (d->optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
     3465            d->scene->d_func()->rectAdjust = 1;
     3466        else
     3467            d->scene->d_func()->rectAdjust = 2;
    33863468        d->scene->d_func()->drawItems(&painter, viewTransformed ? &viewTransform : 0,
    33873469                                      &d->exposedRegion, viewport());
     3470        d->scene->d_func()->rectAdjust = oldRectAdjust;
    33883471        // Make sure the painter's world transform is restored correctly when
    33893472        // drawing without painter state protection (DontSavePainterState).
     
    33933476        // and restore() in QGraphicsScene::drawItems().
    33943477        if (!d->scene->d_func()->painterStateProtection)
    3395             painter.setWorldTransform(viewTransform);
     3478            painter.setOpacity(1.0);
     3479        painter.setWorldTransform(viewTransform);
    33963480    } else {
    33973481        // Make sure we don't have unpolished items before we draw
Note: See TracChangeset for help on using the changeset viewer.