diff options
author | Jason Barron <jbarron@trolltech.com> | 2009-07-28 10:58:46 (GMT) |
---|---|---|
committer | Jason Barron <jbarron@trolltech.com> | 2009-07-28 11:45:59 (GMT) |
commit | 7eba68adc4a7862d9474179592e5c8393a7acdbb (patch) | |
tree | 73014cabc8b10f46203844aeb40de574d97032dc /src/gui/graphicsview | |
parent | a20f8dcbeafa34b50ef69d1c5db0f17b09731d2a (diff) | |
parent | 3bf3981c7026de9017887d08312391b54fe8afc6 (diff) | |
download | Qt-7eba68adc4a7862d9474179592e5c8393a7acdbb.zip Qt-7eba68adc4a7862d9474179592e5c8393a7acdbb.tar.gz Qt-7eba68adc4a7862d9474179592e5c8393a7acdbb.tar.bz2 |
Merge commit 'qt/master-stable'
Conflicts:
configure.exe
src/corelib/io/io.pri
src/corelib/io/qfilesystemwatcher.cpp
tests/auto/qfileinfo/tst_qfileinfo.cpp
tools/configure/configureapp.cpp
Diffstat (limited to 'src/gui/graphicsview')
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.cpp | 120 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.h | 5 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem_p.h | 9 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene.cpp | 36 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicssceneevent.cpp | 2 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsview.cpp | 20 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicswidget.cpp | 8 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicswidget_p.cpp | 34 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicswidget_p.h | 4 |
9 files changed, 151 insertions, 87 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 7e155e1..c4ff7c6 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -325,6 +325,10 @@ \value ItemAcceptsInputMethod The item supports input methods typically used for Asian languages. This flag was introduced in Qt 4.6. + + \value ItemAutoDetectsFocusProxy The item will assign any child that + gains input focus as its focus proxy. See also focusProxy(). + This flag was introduced in Qt 4.6. */ /*! @@ -908,12 +912,12 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParentVariant); } - if (QGraphicsWidget *w = isWidget ? static_cast<QGraphicsWidget *>(q) : q->parentWidget()) { - // Update the child focus chain; when reparenting a widget that has a + QGraphicsItem *lastSubFocusItem = subFocusItem; + if (subFocusItem) { + // Update the child focus chain; when reparenting an item that has a // focus child, ensure that that focus child clears its focus child // chain from our parents before it's reparented. - if (QGraphicsWidget *focusChild = w->focusWidget()) - focusChild->clearFocus(); + subFocusItem->clearFocus(); } // We anticipate geometry changes. If the item is deleted, it will be @@ -1001,6 +1005,21 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) resolveDepth(parent ? parent->d_ptr->depth : -1); dirtySceneTransform = 1; + // Restore the sub focus chain. + if (lastSubFocusItem) + lastSubFocusItem->d_ptr->setSubFocus(); + + // Auto-update focus proxy. The closest parent that detects + // focus proxies is updated as the proxy gains or loses focus. + QGraphicsItem *p = newParent; + while (p) { + if (p->d_ptr->flags & QGraphicsItem::ItemAutoDetectsFocusProxy) { + p->setFocusProxy(q); + break; + } + p = p->d_ptr->parent; + } + // Deliver post-change notification q->itemChange(QGraphicsItem::ItemParentHasChanged, newParentVariant); @@ -2463,33 +2482,45 @@ bool QGraphicsItem::hasFocus() const be passed into any focus event generated by this function; it is used to give an explanation of what caused the item to get focus. - Only items that set the ItemIsFocusable flag can accept keyboard focus. + Only enabled items that set the ItemIsFocusable flag can accept keyboard + focus. - If this item is not visible (i.e., isVisible() returns false), not - enabled, not associated with a scene, or if it already has input focus, - this function will do nothing. + If this item is not visible, or not associated with a scene, it will not + gain immediate input focus. However, it will be registered as the preferred + focus item for its subtree of items, should it later become visible. As a result of calling this function, this item will receive a focus in event with \a focusReason. If another item already has focus, that item will first receive a focus out event indicating that it has lost input focus. - \sa clearFocus(), hasFocus() + \sa clearFocus(), hasFocus(), focusItem() */ void QGraphicsItem::setFocus(Qt::FocusReason focusReason) { - if (!d_ptr->scene || !isEnabled() || hasFocus() || !(d_ptr->flags & ItemIsFocusable)) + // Disabled / unfocusable items cannot accept focus. + if (!isEnabled() || !(d_ptr->flags & QGraphicsItem::ItemIsFocusable)) + return; + + // Find focus proxy. + QGraphicsItem *f = this; + while (f->d_ptr->focusProxy) + f = f->d_ptr->focusProxy; + + // Return if it already has focus. + if (d_ptr->scene && d_ptr->scene->focusItem() == f) return; - QGraphicsItem *item = this; - QGraphicsItem *f; - while ((f = item->d_ptr->focusProxy)) - item = f; - if (item->isVisible()) { - // Visible items immediately gain focus from scene. - d_ptr->scene->d_func()->setFocusItemHelper(item, focusReason); - } else if (item->d_ptr->isWidget) { - // Just set up subfocus. - static_cast<QGraphicsWidget *>(item)->d_func()->setFocusWidget(); + + // Update the child focus chain. + d_ptr->setSubFocus(); + + // Update the scene's focus item. + if (d_ptr->scene) { + QGraphicsWidget *w = window(); + if (!w || w->isActiveWindow()) { + // Visible items immediately gain focus from scene. + d_ptr->scene->d_func()->setFocusItemHelper(f, focusReason); + } } } @@ -2508,10 +2539,8 @@ void QGraphicsItem::clearFocus() { if (!d_ptr->scene) return; - if (d_ptr->isWidget) { - // Invisible widget items with focus must explicitly clear subfocus. - static_cast<QGraphicsWidget *>(this)->d_func()->clearFocusWidget(); - } + // Invisible items with focus must explicitly clear subfocus. + d_ptr->clearSubFocus(); if (hasFocus()) { // If this item has the scene's input focus, clear it. d_ptr->scene->setFocusItem(0); @@ -2579,6 +2608,18 @@ void QGraphicsItem::setFocusProxy(QGraphicsItem *item) } /*! + If this item, a child or descendant of this item currently has input + focus, this function will return a pointer to that item. If + no descendant has input focus, 0 is returned. + + \sa QWidget::focusWidget() +*/ +QGraphicsItem *QGraphicsItem::focusItem() const +{ + return d_ptr->subFocusItem; +} + +/*! \since 4.4 Grabs the mouse input. @@ -4668,6 +4709,34 @@ void QGraphicsItemPrivate::ensureSceneTransform() /*! \internal +*/ +void QGraphicsItemPrivate::setSubFocus() +{ + // Update focus child chain. + QGraphicsItem *item = q_ptr; + QGraphicsItem *parent = item; + bool hidden = !visible; + do { + parent->d_func()->subFocusItem = item; + } while (!parent->isWindow() && (parent = parent->d_ptr->parent) && (!hidden || !parent->d_func()->visible)); +} + +/*! + \internal +*/ +void QGraphicsItemPrivate::clearSubFocus() +{ + // Reset focus child chain. + QGraphicsItem *parent = q_ptr; + do { + if (parent->d_ptr->subFocusItem != q_ptr) + break; + parent->d_ptr->subFocusItem = 0; + } while (!parent->isWindow() && (parent = parent->d_ptr->parent)); +} + +/*! + \internal Tells us if it is a proxy widget */ @@ -10164,6 +10233,9 @@ QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlag flag) case QGraphicsItem::ItemAcceptsInputMethod: str = "ItemAcceptsInputMethod"; break; + case QGraphicsItem::ItemAutoDetectsFocusProxy: + str = "ItemAutoDetectsFocusProxy"; + break; } debug << str; return debug; diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index fef09f0..f8e74f3 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -100,7 +100,8 @@ public: ItemUsesExtendedStyleOption = 0x200, ItemHasNoContents = 0x400, ItemSendsGeometryChanges = 0x800, - ItemAcceptsInputMethod = 0x1000 + ItemAcceptsInputMethod = 0x1000, + ItemAutoDetectsFocusProxy = 0x2000 // NB! Don't forget to increase the d_ptr->flags bit field by 1 when adding a new flag. }; Q_DECLARE_FLAGS(GraphicsItemFlags, GraphicsItemFlag) @@ -230,6 +231,8 @@ public: QGraphicsItem *focusProxy() const; void setFocusProxy(QGraphicsItem *item); + QGraphicsItem *focusItem() const; + void grabMouse(); void ungrabMouse(); void grabKeyboard(); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index c395cd6..8097519 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -123,6 +123,7 @@ public: siblingIndex(-1), depth(0), focusProxy(0), + subFocusItem(0), acceptedMouseButtons(0x1f), visible(1), explicitlyHidden(0), @@ -391,6 +392,9 @@ public: || (childrenCombineOpacity() && isFullyTransparent()); } + void setSubFocus(); + void clearSubFocus(); + inline QTransform transformToParent() const; inline void ensureSortedChildren(); @@ -411,6 +415,7 @@ public: int siblingIndex; int depth; QGraphicsItem *focusProxy; + QGraphicsItem *subFocusItem; // Packed 32 bytes quint32 acceptedMouseButtons : 5; @@ -440,7 +445,7 @@ public: // New 32 bits quint32 fullUpdatePending : 1; - quint32 flags : 13; + quint32 flags : 14; quint32 dirtyChildrenBoundingRect : 1; quint32 paintedViewBoundingRectsNeedRepaint : 1; quint32 dirtySceneTransform : 1; @@ -453,7 +458,7 @@ public: quint32 acceptedTouchBeginEvent : 1; quint32 filtersDescendantEvents : 1; quint32 sceneTransformTranslateOnly : 1; - quint32 unused : 6; // feel free to use + quint32 unused : 5; // feel free to use // Optional stacking order int globalStackingOrder; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index a1a2b60..7e2f7c8 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -484,6 +484,8 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) index->removeItem(item); } + item->d_ptr->clearSubFocus(); + if (!item->d_ptr->inDestructor && item == tabFocusFirst) { QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item); widget->d_func()->fixFocusChainBeforeReparenting(0, 0); @@ -572,17 +574,34 @@ void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item, Q_Q(QGraphicsScene); if (item == focusItem) return; + + // Clear focus if asked to set focus on something that can't + // accept input focus. if (item && (!(item->flags() & QGraphicsItem::ItemIsFocusable) || !item->isVisible() || !item->isEnabled())) { item = 0; } + // Set focus on the scene if an item requests focus. if (item) { q->setFocus(focusReason); if (item == focusItem) return; } + // Auto-update focus proxy. The closest parent that detects + // focus proxies is updated as the proxy gains or loses focus. + if (item) { + QGraphicsItem *p = item->d_ptr->parent; + while (p) { + if (p->d_ptr->flags & QGraphicsItem::ItemAutoDetectsFocusProxy) { + p->setFocusProxy(item); + break; + } + p = p->d_ptr->parent; + } + } + if (focusItem) { QFocusEvent event(QEvent::FocusOut, focusReason); lastFocusItem = focusItem; @@ -602,11 +621,6 @@ void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item, } if (item) { - if (item->isWidget()) { - // Update focus child chain. - static_cast<QGraphicsWidget *>(item)->d_func()->setFocusWidget(); - } - focusItem = item; QFocusEvent event(QEvent::FocusIn, focusReason); sendEvent(item, &event); @@ -2342,6 +2356,11 @@ void QGraphicsScene::addItem(QGraphicsItem *item) // Deliver post-change notification item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant); + // Ensure that newly added items that have subfocus set, gain + // focus automatically if there isn't a focus item already. + if (!d->focusItem && item->focusItem()) + item->focusItem()->setFocus(); + d->updateInputMethodSensitivityInViews(); } @@ -3457,7 +3476,7 @@ void QGraphicsScene::helpEvent(QGraphicsSceneHelpEvent *helpEvent) text = toolTipItem->toolTip(); point = helpEvent->screenPos(); } - QToolTip::showText(point, text); + QToolTip::showText(point, text, helpEvent->widget()); helpEvent->setAccepted(!text.isEmpty()); #endif } @@ -3556,8 +3575,7 @@ void QGraphicsScenePrivate::leaveScene() { Q_Q(QGraphicsScene); #ifndef QT_NO_TOOLTIP - // Remove any tooltips - QToolTip::showText(QPoint(), QString()); + QToolTip::hideText(); #endif // Send HoverLeave events to all existing hover items, topmost first. QGraphicsView *senderWidget = qobject_cast<QGraphicsView *>(q->sender()); @@ -4698,7 +4716,7 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool background has been drawn, and before the foreground has been drawn. All painting is done in \e scene coordinates. Before drawing each item, the painter must be transformed using - QGraphicsItem::sceneMatrix(). + QGraphicsItem::sceneTransform(). The \a options parameter is the list of style option objects for each item in \a items. The \a numItems parameter is the number of diff --git a/src/gui/graphicsview/qgraphicssceneevent.cpp b/src/gui/graphicsview/qgraphicssceneevent.cpp index 97e8e46..73cc787 100644 --- a/src/gui/graphicsview/qgraphicssceneevent.cpp +++ b/src/gui/graphicsview/qgraphicssceneevent.cpp @@ -1475,7 +1475,7 @@ void QGraphicsSceneDragDropEvent::acceptProposedAction() /*! Returns the action that was performed in this drag and drop. This should be set by the receiver of the drop and is - returned by QDrag::start(). + returned by QDrag::exec(). \sa setDropAction(), acceptProposedAction() */ diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index a3005ae..e1f9f62 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -97,8 +97,8 @@ static const int QGRAPHICSVIEW_PREALLOC_STYLE_OPTIONS = 503; // largest prime < setViewport(new QGLWidget). QGraphicsView takes ownership of the viewport widget. - QGraphicsView supports affine transformations, using QMatrix. You can - either pass a matrix to setMatrix(), or you can call one of the + QGraphicsView supports affine transformations, using QTransform. You can + either pass a matrix to setTransform(), or you can call one of the convenience functions rotate(), scale(), translate() or shear(). The most two common transformations are scaling, which is used to implement zooming, and rotation. QGraphicsView keeps the center of the view fixed @@ -1598,7 +1598,7 @@ void QGraphicsView::setSceneRect(const QRectF &rect) Returns the current transformation matrix for the view. If no current transformation is set, the identity matrix is returned. - \sa setMatrix(), rotate(), scale(), shear(), translate() + \sa setMatrix(), transform(), rotate(), scale(), shear(), translate() */ QMatrix QGraphicsView::matrix() const { @@ -1630,7 +1630,7 @@ QMatrix QGraphicsView::matrix() const a view coordinate to a floating point scene coordinate, or mapFromScene() to map from floating point scene coordinates to view coordinates. - \sa matrix(), rotate(), scale(), shear(), translate() + \sa matrix(), setTransform(), rotate(), scale(), shear(), translate() */ void QGraphicsView::setMatrix(const QMatrix &matrix, bool combine) { @@ -1639,6 +1639,8 @@ void QGraphicsView::setMatrix(const QMatrix &matrix, bool combine) /*! Resets the view transformation matrix to the identity matrix. + + \sa resetTransform() */ void QGraphicsView::resetMatrix() { @@ -1648,7 +1650,7 @@ void QGraphicsView::resetMatrix() /*! Rotates the current view transformation \a angle degrees clockwise. - \sa setMatrix(), matrix(), scale(), shear(), translate() + \sa setTransform(), transform(), scale(), shear(), translate() */ void QGraphicsView::rotate(qreal angle) { @@ -1661,7 +1663,7 @@ void QGraphicsView::rotate(qreal angle) /*! Scales the current view transformation by (\a sx, \a sy). - \sa setMatrix(), matrix(), rotate(), shear(), translate() + \sa setTransform(), transform(), rotate(), shear(), translate() */ void QGraphicsView::scale(qreal sx, qreal sy) { @@ -1674,7 +1676,7 @@ void QGraphicsView::scale(qreal sx, qreal sy) /*! Shears the current view transformation by (\a sh, \a sv). - \sa setMatrix(), matrix(), rotate(), scale(), translate() + \sa setTransform(), transform(), rotate(), scale(), translate() */ void QGraphicsView::shear(qreal sh, qreal sv) { @@ -1687,7 +1689,7 @@ void QGraphicsView::shear(qreal sh, qreal sv) /*! Translates the current view transformation by (\a dx, \a dy). - \sa setMatrix(), matrix(), rotate(), shear() + \sa setTransform(), transform(), rotate(), shear() */ void QGraphicsView::translate(qreal dx, qreal dy) { @@ -1845,7 +1847,7 @@ void QGraphicsView::ensureVisible(const QGraphicsItem *item, int xmargin, int ym If \a rect is empty, or if the viewport is too small, this function will do nothing. - \sa setMatrix(), ensureVisible(), centerOn() + \sa setTransform(), ensureVisible(), centerOn() */ void QGraphicsView::fitInView(const QRectF &rect, Qt::AspectRatioMode aspectRatioMode) { diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 922db04..5e5c826 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -1716,14 +1716,16 @@ void QGraphicsWidget::setFocusPolicy(Qt::FocusPolicy policy) /*! If this widget, a child or descendant of this widget currently has input focus, this function will return a pointer to that widget. If - no descendant has input focus, 0 is returned. + no descendant widget has input focus, 0 is returned. - \sa QWidget::focusWidget() + \sa QGraphicsItem::focusItem(), QWidget::focusWidget() */ QGraphicsWidget *QGraphicsWidget::focusWidget() const { Q_D(const QGraphicsWidget); - return d->focusChild; + if (d->subFocusItem && d->subFocusItem->d_ptr->isWidget) + return static_cast<QGraphicsWidget *>(d->subFocusItem); + return 0; } /*! \property QGraphicsWidget::horizontalShear diff --git a/src/gui/graphicsview/qgraphicswidget_p.cpp b/src/gui/graphicsview/qgraphicswidget_p.cpp index c9212f7..8eac063 100644 --- a/src/gui/graphicsview/qgraphicswidget_p.cpp +++ b/src/gui/graphicsview/qgraphicswidget_p.cpp @@ -626,34 +626,6 @@ bool QGraphicsWidgetPrivate::hasDecoration() const return (windowFlags & Qt::Window) && (windowFlags & Qt::WindowTitleHint); } -/*! - \internal -*/ -void QGraphicsWidgetPrivate::setFocusWidget() -{ - // Update focus child chain. - QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(q_ptr); - QGraphicsWidget *parent = widget; - bool hidden = !visible; - do { - parent->d_func()->focusChild = widget; - } while (!parent->isWindow() && (parent = parent->parentWidget()) && (!hidden || !parent->d_func()->visible)); -} - -/*! - \internal -*/ -void QGraphicsWidgetPrivate::clearFocusWidget() -{ - // Reset focus child chain. - QGraphicsWidget *parent = static_cast<QGraphicsWidget *>(q_ptr); - do { - if (parent->d_func()->focusChild != q_ptr) - break; - parent->d_func()->focusChild = 0; - } while (!parent->isWindow() && (parent = parent->parentWidget())); -} - /** * is called after a reparent has taken place to fix up the focus chain(s) */ @@ -670,12 +642,6 @@ void QGraphicsWidgetPrivate::fixFocusChainBeforeReparenting(QGraphicsWidget *new QGraphicsWidget *firstOld = 0; bool wasPreviousNew = true; - - if (focusChild) { - // Ensure that the current focus child doesn't leave pointers around - // before reparenting. - focusChild->clearFocus(); - } while (w != q) { bool isCurrentNew = q->isAncestorOf(w); diff --git a/src/gui/graphicsview/qgraphicswidget_p.h b/src/gui/graphicsview/qgraphicswidget_p.h index 0c34baa..92e520a 100644 --- a/src/gui/graphicsview/qgraphicswidget_p.h +++ b/src/gui/graphicsview/qgraphicswidget_p.h @@ -83,7 +83,6 @@ public: focusPolicy(Qt::NoFocus), focusNext(0), focusPrev(0), - focusChild(0), windowFlags(0), windowData(0), setWindowFrameMargins(false), @@ -178,9 +177,6 @@ public: Qt::FocusPolicy focusPolicy; QGraphicsWidget *focusNext; QGraphicsWidget *focusPrev; - QGraphicsWidget *focusChild; - void setFocusWidget(); - void clearFocusWidget(); // Windows Qt::WindowFlags windowFlags; |