summaryrefslogtreecommitdiffstats
path: root/src/gui/graphicsview/qgraphicsscene.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/graphicsview/qgraphicsscene.cpp')
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp161
1 files changed, 77 insertions, 84 deletions
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 56cf83e..f6e0aaf 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -20,10 +21,9 @@
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
-** In addition, as a special exception, Nokia gives you certain
-** additional rights. These rights are described in the Nokia Qt LGPL
-** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this
-** package.
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
@@ -581,6 +581,9 @@ void QGraphicsScenePrivate::setActivePanelHelper(QGraphicsItem *item, bool durin
return;
}
+ // Ensure the scene has focus when we change panel activation.
+ q->setFocus(Qt::ActiveWindowFocusReason);
+
// Find the item's panel.
QGraphicsItem *panel = item ? item->panel() : 0;
lastActivePanel = panel ? activePanel : 0;
@@ -636,10 +639,6 @@ void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item,
Qt::FocusReason focusReason)
{
Q_Q(QGraphicsScene);
-
- while (item && item->d_ptr->focusScopeItem)
- item = item->d_ptr->focusScopeItem;
-
if (item == focusItem)
return;
@@ -657,18 +656,9 @@ void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item,
return;
}
- QGraphicsItem *itemRootLevelFocusItem =
- item?item->d_ptr->rootLevelFocusItem():0;
-
if (focusItem) {
QFocusEvent event(QEvent::FocusOut, focusReason);
lastFocusItem = focusItem;
-
- QGraphicsItem *oldRootLevelFocusItem =
- focusItem->d_ptr->rootLevelFocusItem();
- if (oldRootLevelFocusItem != itemRootLevelFocusItem)
- oldRootLevelFocusItem->d_ptr->setItemFocusedInScope(false);
-
focusItem = 0;
sendEvent(lastFocusItem, &event);
@@ -678,16 +668,19 @@ void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item,
QInputMethodEvent imEvent;
sendEvent(lastFocusItem, &imEvent);
- // Close any external input method panel
- for (int i = 0; i < views.size(); ++i)
- views.at(i)->inputContext()->reset();
+ // Close any external input method panel. This happens
+ // automatically by removing WA_InputMethodEnabled on
+ // the views, but if we are changing focus, we have to
+ // do it ourselves.
+ if (item) {
+ for (int i = 0; i < views.size(); ++i)
+ views.at(i)->inputContext()->reset();
+ }
}
}
if (item) {
focusItem = item;
- itemRootLevelFocusItem->d_ptr->setItemFocusedInScope(true);
- item->d_ptr->setItemFocusedInScope(true);
QFocusEvent event(QEvent::FocusIn, focusReason);
sendEvent(item, &event);
}
@@ -1400,6 +1393,7 @@ QGraphicsScene::QGraphicsScene(qreal x, qreal y, qreal width, qreal height, QObj
QGraphicsScene::~QGraphicsScene()
{
Q_D(QGraphicsScene);
+
// Remove this scene from qApp's global scene list.
qApp->d_func()->scene_list.removeAll(this);
@@ -2298,19 +2292,11 @@ void QGraphicsScene::destroyItemGroup(QGraphicsItemGroup *group)
void QGraphicsScene::addItem(QGraphicsItem *item)
{
Q_D(QGraphicsScene);
- d->addItem(item);
-}
-
-void QGraphicsScenePrivate::addItem(QGraphicsItem *item,
- QGraphicsItem *focusScope)
-{
- Q_Q(QGraphicsScene);
-
if (!item) {
qWarning("QGraphicsScene::addItem: cannot add null item");
return;
}
- if (item->scene() == q) {
+ if (item->scene() == this) {
qWarning("QGraphicsScene::addItem: item has already been added to this scene");
return;
}
@@ -2321,9 +2307,9 @@ void QGraphicsScenePrivate::addItem(QGraphicsItem *item,
// Notify the item that its scene is changing, and allow the item to
// react.
const QVariant newSceneVariant(item->itemChange(QGraphicsItem::ItemSceneChange,
- qVariantFromValue<QGraphicsScene *>(q)));
+ qVariantFromValue<QGraphicsScene *>(this)));
QGraphicsScene *targetScene = qVariantValue<QGraphicsScene *>(newSceneVariant);
- if (targetScene != q) {
+ if (targetScene != this) {
if (targetScene && item->scene() != targetScene)
targetScene->addItem(item);
return;
@@ -2332,7 +2318,7 @@ void QGraphicsScenePrivate::addItem(QGraphicsItem *item,
// Detach this item from its parent if the parent's scene is different
// from this scene.
if (QGraphicsItem *itemParent = item->parentItem()) {
- if (itemParent->scene() != q)
+ if (itemParent->scene() != this)
item->setParentItem(0);
}
@@ -2340,121 +2326,127 @@ void QGraphicsScenePrivate::addItem(QGraphicsItem *item,
item->d_func()->scene = targetScene;
// Add the item in the index
- index->addItem(item);
+ d->index->addItem(item);
// Add to list of toplevels if this item is a toplevel.
if (!item->d_ptr->parent)
- registerTopLevelItem(item);
+ d->registerTopLevelItem(item);
// Add to list of items that require an update. We cannot assume that the
// item is fully constructed, so calling item->update() can lead to a pure
// virtual function call to boundingRect().
- markDirty(item);
- dirtyGrowingItemsBoundingRect = true;
+ d->markDirty(item);
+ d->dirtyGrowingItemsBoundingRect = true;
// Disable selectionChanged() for individual items
- ++selectionChanging;
- int oldSelectedItemSize = selectedItems.size();
+ ++d->selectionChanging;
+ int oldSelectedItemSize = d->selectedItems.size();
// Enable mouse tracking if the item accepts hover events or has a cursor set.
- if (allItemsIgnoreHoverEvents && itemAcceptsHoverEvents_helper(item)) {
- allItemsIgnoreHoverEvents = false;
- enableMouseTrackingOnViews();
+ if (d->allItemsIgnoreHoverEvents && d->itemAcceptsHoverEvents_helper(item)) {
+ d->allItemsIgnoreHoverEvents = false;
+ d->enableMouseTrackingOnViews();
}
#ifndef QT_NO_CURSOR
- if (allItemsUseDefaultCursor && item->hasCursor()) {
- allItemsUseDefaultCursor = false;
- if (allItemsIgnoreHoverEvents) // already enabled otherwise
- enableMouseTrackingOnViews();
+ if (d->allItemsUseDefaultCursor && item->hasCursor()) {
+ d->allItemsUseDefaultCursor = false;
+ if (d->allItemsIgnoreHoverEvents) // already enabled otherwise
+ d->enableMouseTrackingOnViews();
}
#endif //QT_NO_CURSOR
// Enable touch events if the item accepts touch events.
- if (allItemsIgnoreTouchEvents && item->acceptTouchEvents()) {
- allItemsIgnoreTouchEvents = false;
- enableTouchEventsOnViews();
+ if (d->allItemsIgnoreTouchEvents && item->acceptTouchEvents()) {
+ d->allItemsIgnoreTouchEvents = false;
+ d->enableTouchEventsOnViews();
}
// Update selection lists
if (item->isSelected())
- selectedItems << item;
+ d->selectedItems << item;
if (item->isWidget() && item->isVisible() && static_cast<QGraphicsWidget *>(item)->windowType() == Qt::Popup)
- addPopup(static_cast<QGraphicsWidget *>(item));
+ d->addPopup(static_cast<QGraphicsWidget *>(item));
// Update creation order focus chain. Make sure to leave the widget's
// internal tab order intact.
if (item->isWidget()) {
QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
- if (!tabFocusFirst) {
+ if (!d->tabFocusFirst) {
// No first tab focus widget - make this the first tab focus
// widget.
- tabFocusFirst = widget;
+ d->tabFocusFirst = widget;
} else if (!widget->parentWidget()) {
// Adding a widget that is not part of a tab focus chain.
- QGraphicsWidget *last = tabFocusFirst->d_func()->focusPrev;
+ QGraphicsWidget *last = d->tabFocusFirst->d_func()->focusPrev;
QGraphicsWidget *lastNew = widget->d_func()->focusPrev;
last->d_func()->focusNext = widget;
widget->d_func()->focusPrev = last;
- tabFocusFirst->d_func()->focusPrev = lastNew;
- lastNew->d_func()->focusNext = tabFocusFirst;
+ d->tabFocusFirst->d_func()->focusPrev = lastNew;
+ lastNew->d_func()->focusNext = d->tabFocusFirst;
}
}
// Add all children recursively
- QGraphicsItem *subFocusScope =
- (item->d_ptr->flags & QGraphicsItem::ItemIsFocusScope)?item:focusScope;
foreach (QGraphicsItem *child, item->children())
- addItem(child, subFocusScope);
+ addItem(child);
// Resolve font and palette.
- item->d_ptr->resolveFont(font.resolve());
- item->d_ptr->resolvePalette(palette.resolve());
+ item->d_ptr->resolveFont(d->font.resolve());
+ item->d_ptr->resolvePalette(d->palette.resolve());
if (!item->d_ptr->explicitlyHidden) {
- if (unpolishedItems.isEmpty())
- QMetaObject::invokeMethod(q, "_q_polishItems", Qt::QueuedConnection);
- unpolishedItems << item;
+ if (d->unpolishedItems.isEmpty())
+ QMetaObject::invokeMethod(this, "_q_polishItems", Qt::QueuedConnection);
+ d->unpolishedItems << item;
}
// Reenable selectionChanged() for individual items
- --selectionChanging;
- if (!selectionChanging && selectedItems.size() != oldSelectedItemSize)
- emit q->selectionChanged();
+ --d->selectionChanging;
+ if (!d->selectionChanging && d->selectedItems.size() != oldSelectedItemSize)
+ emit selectionChanged();
// Deliver post-change notification
item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant);
// Update explicit activation
bool autoActivate = true;
- if (!childExplicitActivation && item->d_ptr->explicitActivate)
- childExplicitActivation = item->d_ptr->wantsActive ? 1 : 2;
- if (childExplicitActivation && item->isPanel()) {
- if (childExplicitActivation == 1)
- q->setActivePanel(item);
+ if (!d->childExplicitActivation && item->d_ptr->explicitActivate)
+ d->childExplicitActivation = item->d_ptr->wantsActive ? 1 : 2;
+ if (d->childExplicitActivation && item->isPanel()) {
+ if (d->childExplicitActivation == 1)
+ setActivePanel(item);
else
autoActivate = false;
- childExplicitActivation = 0;
+ d->childExplicitActivation = 0;
} else if (!item->d_ptr->parent) {
- childExplicitActivation = 0;
+ d->childExplicitActivation = 0;
}
// Auto-activate this item's panel if nothing else has been activated
if (autoActivate) {
- if (!lastActivePanel && !activePanel && item->isPanel()) {
- if (q->isActive())
- q->setActivePanel(item);
+ if (!d->lastActivePanel && !d->activePanel && item->isPanel()) {
+ if (isActive())
+ setActivePanel(item);
else
- lastActivePanel = item;
+ d->lastActivePanel = item;
}
}
// Ensure that newly added items that have subfocus set, gain
// focus automatically if there isn't a focus item already.
- if (!focusItem && item->focusItem() ||
- focusScope && !focusScope->d_ptr->focusScopeItem && item->focusItem())
- item->focusItem()->setFocus();
+ if (!d->focusItem) {
+ if (item->focusItem() == item && item != d->lastFocusItem) {
+ QGraphicsItem *fi = item->focusItem() ? item->focusItem() : item->focusScopeItem();
+ if (fi) {
+ QGraphicsItem *fsi;
+ while ((fsi = fi->focusScopeItem()) && fsi->isVisible())
+ fi = fsi;
+ fi->setFocus();
+ }
+ }
+ }
- updateInputMethodSensitivityInViews();
+ d->updateInputMethodSensitivityInViews();
}
/*!
@@ -2800,7 +2792,7 @@ bool QGraphicsScene::hasFocus() const
void QGraphicsScene::setFocus(Qt::FocusReason focusReason)
{
Q_D(QGraphicsScene);
- if (d->hasFocus)
+ if (d->hasFocus || !isActive())
return;
QFocusEvent event(QEvent::FocusIn, focusReason);
QCoreApplication::sendEvent(this, &event);
@@ -4480,6 +4472,7 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
painter->setWorldTransform(*transformPtr * *effectTransform);
else
painter->setWorldTransform(*transformPtr);
+ painter->setOpacity(opacity);
item->d_ptr->graphicsEffect->draw(painter, source);
painter->setWorldTransform(restoreTransform);
sourced->info = 0;