diff options
author | Martin Jones <martin.jones@nokia.com> | 2009-07-23 07:13:59 (GMT) |
---|---|---|
committer | Martin Jones <martin.jones@nokia.com> | 2009-07-23 07:14:35 (GMT) |
commit | 64c807ed9d7e7eea95e35a26c31679dfaae820bb (patch) | |
tree | bf7639483a1d85e1e5c097097738f462b1d9a52b /src | |
parent | f9103011abc672059cda53078e84d9e73e687e12 (diff) | |
parent | 5234d083c9b00ed508dae7cc8c47d21da46325c6 (diff) | |
download | Qt-64c807ed9d7e7eea95e35a26c31679dfaae820bb.zip Qt-64c807ed9d7e7eea95e35a26c31679dfaae820bb.tar.gz Qt-64c807ed9d7e7eea95e35a26c31679dfaae820bb.tar.bz2 |
Merge branch 'master' of git@scm.dev.nokia.troll.no:qt/qt
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.cpp | 76 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.h | 3 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem_p.h | 6 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene.cpp | 106 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene_p.h | 2 | ||||
-rw-r--r-- | src/opengl/qgl_x11.cpp | 19 |
6 files changed, 162 insertions, 50 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index ae2a2c3..4e3677a 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -2455,6 +2455,8 @@ void QGraphicsItem::setHandlesChildEvents(bool enabled) */ bool QGraphicsItem::hasFocus() const { + if (d_ptr->focusProxy) + return d_ptr->focusProxy->hasFocus(); return (d_ptr->scene && d_ptr->scene->focusItem() == this); } @@ -2480,12 +2482,16 @@ void QGraphicsItem::setFocus(Qt::FocusReason focusReason) { if (!d_ptr->scene || !isEnabled() || hasFocus() || !(d_ptr->flags & ItemIsFocusable)) return; - if (isVisible()) { + 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->setFocusItem(this, focusReason); - } else if (d_ptr->isWidget) { + d_ptr->scene->d_func()->setFocusItemHelper(item, focusReason); + } else if (item->d_ptr->isWidget) { // Just set up subfocus. - static_cast<QGraphicsWidget *>(this)->d_func()->setFocusWidget(); + static_cast<QGraphicsWidget *>(item)->d_func()->setFocusWidget(); } } @@ -2508,13 +2514,73 @@ void QGraphicsItem::clearFocus() // Invisible widget items with focus must explicitly clear subfocus. static_cast<QGraphicsWidget *>(this)->d_func()->clearFocusWidget(); } - if (d_ptr->scene->focusItem() == this) { + if (hasFocus()) { // If this item has the scene's input focus, clear it. d_ptr->scene->setFocusItem(0); } } /*! + \since 4.6 + + Returns this item's focus proxy, or 0 if the item + does not have any focus proxy. + + \sa setFocusProxy() +*/ +QGraphicsItem *QGraphicsItem::focusProxy() const +{ + return d_ptr->focusProxy; +} + +/*! + \since 4.6 + + Sets the item's focus proxy to \a item. + + If an item has a focus proxy, the focus proxy will receive + input focus when the item gains input focus. The item itself + will still have focus (i.e., hasFocus() will return true), + but only the focus proxy will receive the keyboard input. + + A focus proxy can itself have a focus proxy, and so on. In + such case, keyboard input will be handled by the outermost + focus proxy. + + \sa focusProxy() +*/ +void QGraphicsItem::setFocusProxy(QGraphicsItem *item) +{ + if (item == d_ptr->focusProxy) + return; + if (item == this) { + qWarning("QGraphicsItem::setFocusProxy: cannot assign self as focus proxy"); + return; + } + if (item) { + if (item->d_ptr->scene != d_ptr->scene) { + qWarning("QGraphicsItem::setFocusProxy: focus proxy must be in same scene"); + return; + } + for (QGraphicsItem *f = item->focusProxy(); f != 0; f = f->focusProxy()) { + if (f == this) { + qWarning("QGraphicsItem::setFocusProxy: %p is already in the focus proxy chain", item); + return; + } + } + } + + QGraphicsItem *lastFocusProxy = d_ptr->focusProxy; + d_ptr->focusProxy = item; + if (d_ptr->scene) { + if (lastFocusProxy) + d_ptr->scene->d_func()->focusProxyReverseMap.remove(lastFocusProxy, this); + if (item) + d_ptr->scene->d_func()->focusProxyReverseMap.insert(item, this); + } +} + +/*! \since 4.4 Grabs the mouse input. diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index a307622..5c9297f 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -226,6 +226,9 @@ public: void setFocus(Qt::FocusReason focusReason = Qt::OtherFocusReason); void clearFocus(); + QGraphicsItem *focusProxy() const; + void setFocusProxy(QGraphicsItem *item); + void grabMouse(); void ungrabMouse(); void grabKeyboard(); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 4729634..1cf188e 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -122,6 +122,7 @@ public: index(-1), siblingIndex(-1), depth(0), + focusProxy(0), acceptedMouseButtons(0x1f), visible(1), explicitlyHidden(0), @@ -409,6 +410,7 @@ public: int index; int siblingIndex; int depth; + QGraphicsItem *focusProxy; // Packed 32 bytes quint32 acceptedMouseButtons : 5; @@ -438,7 +440,7 @@ public: // New 32 bits quint32 fullUpdatePending : 1; - quint32 flags : 12; + quint32 flags : 13; quint32 dirtyChildrenBoundingRect : 1; quint32 paintedViewBoundingRectsNeedRepaint : 1; quint32 dirtySceneTransform : 1; @@ -451,7 +453,7 @@ public: quint32 acceptedTouchBeginEvent : 1; quint32 filtersDescendantEvents : 1; quint32 sceneTransformTranslateOnly : 1; - quint32 unused : 7; // feel free to use + quint32 unused : 6; // feel free to use // Optional stacking order int globalStackingOrder; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index b017022..4796436 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -491,6 +491,13 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) item->d_func()->scene = 0; + // Unregister focus proxy. + QMultiHash<QGraphicsItem *, QGraphicsItem *>::iterator it = focusProxyReverseMap.find(item); + while (it != focusProxyReverseMap.end() && it.key() == item) { + it.value()->d_ptr->focusProxy = 0; + it = focusProxyReverseMap.erase(it); + } + // Remove from parent, or unregister from toplevels. if (QGraphicsItem *parentItem = item->parentItem()) { if (parentItem->scene()) { @@ -559,6 +566,58 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) /*! \internal */ +void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item, + Qt::FocusReason focusReason) +{ + Q_Q(QGraphicsScene); + if (item == focusItem) + return; + if (item && (!(item->flags() & QGraphicsItem::ItemIsFocusable) + || !item->isVisible() || !item->isEnabled())) { + item = 0; + } + + if (item) { + q->setFocus(focusReason); + if (item == focusItem) + return; + } + + if (focusItem) { + QFocusEvent event(QEvent::FocusOut, focusReason); + lastFocusItem = focusItem; + focusItem = 0; + sendEvent(lastFocusItem, &event); + + if (lastFocusItem + && (lastFocusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod)) { + // Reset any visible preedit text + QInputMethodEvent imEvent; + sendEvent(lastFocusItem, &imEvent); + + // Close any external input method panel + for (int i = 0; i < views.size(); ++i) + views.at(i)->inputContext()->reset(); + } + } + + 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); + } + + updateInputMethodSensitivityInViews(); +} + +/*! + \internal +*/ void QGraphicsScenePrivate::addPopup(QGraphicsWidget *widget) { Q_ASSERT(widget); @@ -2597,49 +2656,10 @@ QGraphicsItem *QGraphicsScene::focusItem() const void QGraphicsScene::setFocusItem(QGraphicsItem *item, Qt::FocusReason focusReason) { Q_D(QGraphicsScene); - if (item == d->focusItem) - return; - if (item && (!(item->flags() & QGraphicsItem::ItemIsFocusable) - || !item->isVisible() || !item->isEnabled())) { - item = 0; - } - - if (item) { - setFocus(focusReason); - if (item == d->focusItem) - return; - } - - if (d->focusItem) { - QFocusEvent event(QEvent::FocusOut, focusReason); - d->lastFocusItem = d->focusItem; - d->focusItem = 0; - d->sendEvent(d->lastFocusItem, &event); - - if (d->lastFocusItem - && (d->lastFocusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod)) { - // Reset any visible preedit text - QInputMethodEvent imEvent; - d->sendEvent(d->lastFocusItem, &imEvent); - - // Close any external input method panel - for (int i = 0; i < d->views.size(); ++i) - d->views.at(i)->inputContext()->reset(); - } - } - - if (item) { - if (item->isWidget()) { - // Update focus child chain. - static_cast<QGraphicsWidget *>(item)->d_func()->setFocusWidget(); - } - - d->focusItem = item; - QFocusEvent event(QEvent::FocusIn, focusReason); - d->sendEvent(item, &event); - } - - d->updateInputMethodSensitivityInViews(); + if (item) + item->setFocus(focusReason); + else + d->setFocusItemHelper(item, focusReason); } /*! diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 9a91acc..a4bbdd2 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -130,6 +130,8 @@ public: QGraphicsWidget *tabFocusFirst; QGraphicsWidget *activeWindow; int activationRefCount; + void setFocusItemHelper(QGraphicsItem *item, Qt::FocusReason focusReason); + QMultiHash<QGraphicsItem *, QGraphicsItem *> focusProxyReverseMap; QList<QGraphicsWidget *> popupWidgets; void addPopup(QGraphicsWidget *widget); diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp index d8af4d5..43bdec7 100644 --- a/src/opengl/qgl_x11.cpp +++ b/src/opengl/qgl_x11.cpp @@ -82,6 +82,25 @@ extern const QX11Info *qt_x11Info(const QPaintDevice *pd); #define GLX_SAMPLES_ARB 100001 #endif +#ifndef GLX_EXT_texture_from_pixmap +#define GLX_TEXTURE_2D_BIT_EXT 0x00000002 +#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004 +#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0 +#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1 +#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2 +#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3 +#define GLX_Y_INVERTED_EXT 0x20D4 +#define GLX_TEXTURE_FORMAT_EXT 0x20D5 +#define GLX_TEXTURE_TARGET_EXT 0x20D6 +#define GLX_MIPMAP_TEXTURE_EXT 0x20D7 +#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8 +#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9 +#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA +#define GLX_TEXTURE_2D_EXT 0x20DC +#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD +#define GLX_FRONT_LEFT_EXT 0x20DE +#endif + /* The qt_gl_choose_cmap function is internal and used by QGLWidget::setContext() and GLX (not Windows). If the application can't find any sharable |