summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2009-07-23 07:13:59 (GMT)
committerMartin Jones <martin.jones@nokia.com>2009-07-23 07:14:35 (GMT)
commit64c807ed9d7e7eea95e35a26c31679dfaae820bb (patch)
treebf7639483a1d85e1e5c097097738f462b1d9a52b /src
parentf9103011abc672059cda53078e84d9e73e687e12 (diff)
parent5234d083c9b00ed508dae7cc8c47d21da46325c6 (diff)
downloadQt-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.cpp76
-rw-r--r--src/gui/graphicsview/qgraphicsitem.h3
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h6
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp106
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h2
-rw-r--r--src/opengl/qgl_x11.cpp19
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