summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorBjørn Erik Nilsen <bjorn.nilsen@nokia.com>2010-01-27 10:47:01 (GMT)
committerBjørn Erik Nilsen <bjorn.nilsen@nokia.com>2010-01-27 10:47:01 (GMT)
commitdd8a0d85b070c363c8e4575ec967ae0ad8dfebec (patch)
tree5901a878931bbd3c4bffed0b0dba332af5e04181 /src/gui
parentc0160230c4fd6f226d0c5ddabe3762f5fa855768 (diff)
parentec90f6ed28ec735ce963c4257ea1095ecbc6c6ba (diff)
downloadQt-dd8a0d85b070c363c8e4575ec967ae0ad8dfebec.zip
Qt-dd8a0d85b070c363c8e4575ec967ae0ad8dfebec.tar.gz
Qt-dd8a0d85b070c363c8e4575ec967ae0ad8dfebec.tar.bz2
Merge commit 'qt/4.6' into kinetic-declarativeui
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/dialogs/qdialog.cpp16
-rw-r--r--src/gui/dialogs/qprintpreviewdialog.cpp10
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp226
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h56
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp97
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h3
-rw-r--r--src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp10
-rw-r--r--src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h2
-rw-r--r--src/gui/graphicsview/qgraphicssceneindex.cpp2
-rw-r--r--src/gui/graphicsview/qgraphicssceneindex_p.h2
-rw-r--r--src/gui/image/qbmphandler.cpp2
-rw-r--r--src/gui/image/qpixmap.cpp21
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_p.h7
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_s60.cpp50
-rw-r--r--src/gui/itemviews/qtableview.cpp4
-rw-r--r--src/gui/kernel/qapplication.cpp4
-rw-r--r--src/gui/kernel/qapplication_mac.mm42
-rw-r--r--src/gui/kernel/qapplication_p.h6
-rw-r--r--src/gui/kernel/qapplication_s60.cpp66
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm2
-rw-r--r--src/gui/kernel/qformlayout.cpp6
-rw-r--r--src/gui/kernel/qt_s60_p.h1
-rw-r--r--src/gui/kernel/qwidget.cpp8
-rw-r--r--src/gui/kernel/qwidget_mac.mm32
-rw-r--r--src/gui/painting/qcolor.cpp11
-rw-r--r--src/gui/painting/qpaintengine_raster_p.h4
-rw-r--r--src/gui/painting/qpainter.cpp41
-rw-r--r--src/gui/styles/qgtkstyle.cpp20
-rw-r--r--src/gui/styles/qs60style.cpp521
-rw-r--r--src/gui/styles/qs60style.h3
-rw-r--r--src/gui/styles/qs60style_p.h106
-rw-r--r--src/gui/styles/qs60style_s60.cpp243
-rw-r--r--src/gui/styles/qs60style_simulated.cpp10
-rw-r--r--src/gui/styles/qstyle_s60.qrc137
-rw-r--r--src/gui/styles/styles.pri10
-rw-r--r--src/gui/widgets/qlinecontrol.cpp5
-rw-r--r--src/gui/widgets/qlinecontrol_p.h5
37 files changed, 1406 insertions, 385 deletions
diff --git a/src/gui/dialogs/qdialog.cpp b/src/gui/dialogs/qdialog.cpp
index 3650051..9ff2ad8 100644
--- a/src/gui/dialogs/qdialog.cpp
+++ b/src/gui/dialogs/qdialog.cpp
@@ -265,6 +265,14 @@ QDialog::QDialog(QWidget *parent, Qt::WindowFlags f)
if (!qt_wince_is_smartphone())
setWindowFlags(windowFlags() | Qt::WindowOkButtonHint | QFlag(qt_wince_is_mobile() ? 0 : Qt::WindowCancelButtonHint));
#endif
+
+#ifdef Q_WS_S60
+ if (S60->avkonComponentsSupportTransparency) {
+ bool noSystemBackground = testAttribute(Qt::WA_NoSystemBackground);
+ setAttribute(Qt::WA_TranslucentBackground); // also sets WA_NoSystemBackground
+ setAttribute(Qt::WA_NoSystemBackground, noSystemBackground); // restore system background attribute
+ }
+#endif
}
#ifdef QT3_SUPPORT
@@ -294,6 +302,14 @@ QDialog::QDialog(QDialogPrivate &dd, QWidget *parent, Qt::WindowFlags f)
if (!qt_wince_is_smartphone())
setWindowFlags(windowFlags() | Qt::WindowOkButtonHint | QFlag(qt_wince_is_mobile() ? 0 : Qt::WindowCancelButtonHint));
#endif
+
+#ifdef Q_WS_S60
+ if (S60->avkonComponentsSupportTransparency) {
+ bool noSystemBackground = testAttribute(Qt::WA_NoSystemBackground);
+ setAttribute(Qt::WA_TranslucentBackground); // also sets WA_NoSystemBackground
+ setAttribute(Qt::WA_NoSystemBackground, noSystemBackground); // restore system background attribute
+ }
+#endif
}
/*!
diff --git a/src/gui/dialogs/qprintpreviewdialog.cpp b/src/gui/dialogs/qprintpreviewdialog.cpp
index 42be780..6723b53 100644
--- a/src/gui/dialogs/qprintpreviewdialog.cpp
+++ b/src/gui/dialogs/qprintpreviewdialog.cpp
@@ -207,6 +207,9 @@ public:
QActionGroup *printerGroup;
QAction *printAction;
QAction *pageSetupAction;
+#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
+ QAction *closeAction;
+#endif
QPointer<QObject> receiverToDisconnectOnClose;
QByteArray memberToDisconnectOnClose;
@@ -287,6 +290,9 @@ void QPrintPreviewDialogPrivate::init(QPrinter *_printer)
toolbar->addSeparator();
toolbar->addAction(pageSetupAction);
toolbar->addAction(printAction);
+#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
+ toolbar->addAction(closeAction);
+#endif
// Cannot use the actions' triggered signal here, since it doesn't autorepeat
QToolButton *zoomInButton = static_cast<QToolButton *>(toolbar->widgetForAction(zoomInAction));
@@ -406,6 +412,10 @@ void QPrintPreviewDialogPrivate::setupActions()
qt_setupActionIcon(pageSetupAction, QLatin1String("page-setup"));
QObject::connect(printAction, SIGNAL(triggered(bool)), q, SLOT(_q_print()));
QObject::connect(pageSetupAction, SIGNAL(triggered(bool)), q, SLOT(_q_pageSetup()));
+#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
+ closeAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Close"));
+ QObject::connect(closeAction, SIGNAL(triggered(bool)), q, SLOT(reject()));
+#endif
// Initial state:
fitPageAction->setChecked(true);
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 616daaa..c53a893 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -798,8 +798,36 @@ void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag ch
return;
}
- foreach (QGraphicsItem *child, children)
- child->d_ptr->updateAncestorFlag(childFlag, flag, enabled, false);
+ for (int i = 0; i < children.size(); ++i)
+ children.at(i)->d_ptr->updateAncestorFlag(childFlag, flag, enabled, false);
+}
+
+void QGraphicsItemPrivate::updateAncestorFlags()
+{
+ int flags = 0;
+ if (parent) {
+ // Inherit the parent's ancestor flags.
+ QGraphicsItemPrivate *pd = parent->d_ptr.data();
+ flags = pd->ancestorFlags;
+
+ // Add in flags from the parent.
+ if (pd->filtersDescendantEvents)
+ flags |= AncestorFiltersChildEvents;
+ if (pd->handlesChildEvents)
+ flags |= AncestorHandlesChildEvents;
+ if (pd->flags & QGraphicsItem::ItemClipsChildrenToShape)
+ flags |= AncestorClipsChildren;
+ if (pd->flags & QGraphicsItem::ItemIgnoresTransformations)
+ flags |= AncestorIgnoresTransformations;
+ }
+
+ if (ancestorFlags == flags)
+ return; // No change; stop propagation.
+ ancestorFlags = flags;
+
+ // Propagate to children recursively.
+ for (int i = 0; i < children.size(); ++i)
+ children.at(i)->d_ptr->updateAncestorFlags();
}
/*!
@@ -984,25 +1012,17 @@ QVariant QGraphicsItemPrivate::inputMethodQueryHelper(Qt::InputMethodQuery query
prepareGeometryChange) if the item is in its destructor, i.e.
inDestructor is 1.
*/
-void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
+void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const QVariant *newParentVariant,
+ const QVariant *thisPointerVariant)
{
Q_Q(QGraphicsItem);
- if (newParent == q) {
- qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this);
- return;
- }
- if (newParent == parent)
- return;
-
- const QVariant newParentVariant(q->itemChange(QGraphicsItem::ItemParentChange,
- qVariantFromValue<QGraphicsItem *>(newParent)));
- newParent = qVariantValue<QGraphicsItem *>(newParentVariant);
if (newParent == parent)
return;
if (scene) {
// Deliver the change to the index
- scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParentVariant);
+ if (scene->d_func()->indexMethod != QGraphicsScene::NoIndex)
+ scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParent);
// Disable scene pos notifications for old ancestors
if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges))
@@ -1020,11 +1040,11 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
if (!inDestructor)
q_ptr->prepareGeometryChange();
- const QVariant thisPointerVariant(qVariantFromValue<QGraphicsItem *>(q));
if (parent) {
// Remove from current parent
parent->d_ptr->removeChild(q);
- parent->itemChange(QGraphicsItem::ItemChildRemovedChange, thisPointerVariant);
+ if (thisPointerVariant)
+ parent->itemChange(QGraphicsItem::ItemChildRemovedChange, *thisPointerVariant);
}
// Update toplevelitem list. If this item is being deleted, its parent
@@ -1042,7 +1062,7 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
QGraphicsItem *p = parent;
QGraphicsItem *parentFocusScopeItem = 0;
while (p) {
- if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
+ if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) {
// If this item's focus scope's focus scope item points
// to this item or a descendent, then clear it.
QGraphicsItem *fsi = p->d_ptr->focusScopeItem;
@@ -1055,6 +1075,10 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
p = p->d_ptr->parent;
}
+ // Update graphics effect optimization flag
+ if (newParent && (graphicsEffect || mayHaveChildWithGraphicsEffect))
+ newParent->d_ptr->updateChildWithGraphicsEffectFlagRecursively();
+
// Update focus scope item ptr in new scope.
QGraphicsItem *newFocusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem;
if (newFocusScopeItem && newParent) {
@@ -1063,11 +1087,11 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
QGraphicsItem *ancestorScope = 0;
QGraphicsItem *p = subFocusItem->d_ptr->parent;
while (p) {
- if (p->flags() & QGraphicsItem::ItemIsFocusScope)
+ if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope)
ancestorScope = p;
- if (p->isPanel())
+ if (p->d_ptr->flags & QGraphicsItem::ItemIsPanel)
break;
- p = p->parentItem();
+ p = p->d_ptr->parent;
}
if (ancestorScope)
newFocusScopeItem = ancestorScope;
@@ -1075,7 +1099,7 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
QGraphicsItem *p = newParent;
while (p) {
- if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
+ if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) {
p->d_ptr->focusScopeItem = newFocusScopeItem;
// Ensure the new item is no longer the subFocusItem. The
// only way to set focus on a child of a focus scope is
@@ -1089,52 +1113,45 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
}
if ((parent = newParent)) {
- bool implicitUpdate = false;
if (parent->d_func()->scene && parent->d_func()->scene != scene) {
// Move this item to its new parent's scene
parent->d_func()->scene->addItem(q);
- implicitUpdate = true;
} else if (!parent->d_func()->scene && scene) {
// Remove this item from its former scene
scene->removeItem(q);
}
parent->d_ptr->addChild(q);
- parent->itemChange(QGraphicsItem::ItemChildAddedChange, thisPointerVariant);
+ if (thisPointerVariant)
+ parent->itemChange(QGraphicsItem::ItemChildAddedChange, *thisPointerVariant);
if (scene) {
- if (!implicitUpdate)
- scene->d_func()->markDirty(q_ptr);
-
// Re-enable scene pos notifications for new ancestors
if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges))
scene->d_func()->setScenePosItemEnabled(q, true);
}
+ // Propagate dirty flags to the new parent
+ markParentDirty(/*updateBoundingRect=*/true);
+
// Inherit ancestor flags from the new parent.
- updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2));
- updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1));
- updateAncestorFlag(QGraphicsItem::ItemClipsChildrenToShape);
- updateAncestorFlag(QGraphicsItem::ItemIgnoresTransformations);
+ updateAncestorFlags();
// Update item visible / enabled.
- if (parent->isVisible() != visible) {
- if (!parent->isVisible() || !explicitlyHidden)
- setVisibleHelper(parent->isVisible(), /* explicit = */ false, /* update = */ !implicitUpdate);
+ if (parent->d_ptr->visible != visible) {
+ if (!parent->d_ptr->visible || !explicitlyHidden)
+ setVisibleHelper(parent->d_ptr->visible, /* explicit = */ false, /* update = */ false);
}
if (parent->isEnabled() != enabled) {
- if (!parent->isEnabled() || !explicitlyDisabled)
- setEnabledHelper(parent->isEnabled(), /* explicit = */ false, /* update = */ !implicitUpdate);
+ if (!parent->d_ptr->enabled || !explicitlyDisabled)
+ setEnabledHelper(parent->d_ptr->enabled, /* explicit = */ false, /* update = */ false);
}
// Auto-activate if visible and the parent is active.
- if (q->isVisible() && parent->isActive())
+ if (visible && parent->isActive())
q->setActive(true);
} else {
// Inherit ancestor flags from the new parent.
- updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2));
- updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1));
- updateAncestorFlag(QGraphicsItem::ItemClipsChildrenToShape);
- updateAncestorFlag(QGraphicsItem::ItemIgnoresTransformations);
+ updateAncestorFlags();
if (!inDestructor) {
// Update item visible / enabled.
@@ -1142,10 +1159,6 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
setVisibleHelper(true, /* explicit = */ false);
if (!enabled && !explicitlyDisabled)
setEnabledHelper(true, /* explicit = */ false);
-
- // If the item is being deleted, the whole scene will be updated.
- if (scene)
- scene->d_func()->markDirty(q_ptr);
}
}
@@ -1161,7 +1174,8 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
}
// Deliver post-change notification
- q->itemChange(QGraphicsItem::ItemParentHasChanged, newParentVariant);
+ if (newParentVariant)
+ q->itemChange(QGraphicsItem::ItemParentHasChanged, *newParentVariant);
if (isObject)
emit static_cast<QGraphicsObject *>(q)->parentChanged();
@@ -1351,7 +1365,7 @@ QGraphicsItem::~QGraphicsItem()
d_ptr->scene->d_func()->removeItemHelper(this);
} else {
d_ptr->resetFocusProxy();
- d_ptr->setParentItemHelper(0);
+ setParentItem(0);
}
#ifndef QT_NO_GRAPHICSEFFECT
@@ -1556,9 +1570,23 @@ const QGraphicsObject *QGraphicsItem::toGraphicsObject() const
\sa parentItem(), childItems()
*/
-void QGraphicsItem::setParentItem(QGraphicsItem *parent)
+void QGraphicsItem::setParentItem(QGraphicsItem *newParent)
{
- d_ptr->setParentItemHelper(parent);
+ if (newParent == this) {
+ qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this);
+ return;
+ }
+ if (newParent == d_ptr->parent)
+ return;
+
+ const QVariant newParentVariant(itemChange(QGraphicsItem::ItemParentChange,
+ qVariantFromValue<QGraphicsItem *>(newParent)));
+ newParent = qVariantValue<QGraphicsItem *>(newParentVariant);
+ if (newParent == d_ptr->parent)
+ return;
+
+ const QVariant thisPointerVariant(qVariantFromValue<QGraphicsItem *>(this));
+ d_ptr->setParentItemHelper(newParent, &newParentVariant, &thisPointerVariant);
}
/*!
@@ -1608,7 +1636,7 @@ bool QGraphicsItem::isWidget() const
*/
bool QGraphicsItem::isWindow() const
{
- return isWidget() && (static_cast<const QGraphicsWidget *>(this)->windowType() & Qt::Window);
+ return d_ptr->isWidget && (static_cast<const QGraphicsWidget *>(this)->windowType() & Qt::Window);
}
/*!
@@ -1645,9 +1673,9 @@ QGraphicsItem::GraphicsItemFlags QGraphicsItem::flags() const
void QGraphicsItem::setFlag(GraphicsItemFlag flag, bool enabled)
{
if (enabled)
- setFlags(flags() | flag);
+ setFlags(GraphicsItemFlags(d_ptr->flags) | flag);
else
- setFlags(flags() & ~flag);
+ setFlags(GraphicsItemFlags(d_ptr->flags) & ~flag);
}
/*!
@@ -1694,8 +1722,8 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
flags = GraphicsItemFlags(itemChange(ItemFlagsChange, quint32(flags)).toUInt());
if (quint32(d_ptr->flags) == quint32(flags))
return;
- if (d_ptr->scene)
- d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, quint32(flags));
+ if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex)
+ d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, &flags);
// Flags that alter the geometry of the item (or its children).
const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations | ItemIsSelectable);
@@ -1704,7 +1732,7 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
// Keep the old flags to compare the diff.
- GraphicsItemFlags oldFlags = this->flags();
+ GraphicsItemFlags oldFlags = GraphicsItemFlags(d_ptr->flags);
// Update flags.
d_ptr->flags = flags;
@@ -1733,7 +1761,23 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
d_ptr->updateAncestorFlag(ItemIgnoresTransformations);
}
+ if ((flags & ItemNegativeZStacksBehindParent) != (oldFlags & ItemNegativeZStacksBehindParent)) {
+ // NB! We change the flags directly here, so we must also update d_ptr->flags.
+ // Note that this has do be done before the ItemStacksBehindParent check
+ // below; otherwise we will loose the change.
+
+ // Update stack-behind.
+ if (d_ptr->z < qreal(0.0))
+ flags |= ItemStacksBehindParent;
+ else
+ flags &= ~ItemStacksBehindParent;
+ d_ptr->flags = flags;
+ }
+
if ((flags & ItemStacksBehindParent) != (oldFlags & ItemStacksBehindParent)) {
+ // NB! This check has to come after the ItemNegativeZStacksBehindParent
+ // check above. Be careful.
+
// Ensure child item sorting is up to date when toggling this flag.
if (d_ptr->parent)
d_ptr->parent->d_ptr->needSortChildren = 1;
@@ -1747,10 +1791,6 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
d_ptr->scene->d_func()->updateInputMethodSensitivityInViews();
}
- if ((flags & ItemNegativeZStacksBehindParent) != (oldFlags & ItemNegativeZStacksBehindParent)) {
- // Update stack-behind.
- setFlag(ItemStacksBehindParent, d_ptr->z < qreal(0.0));
- }
if ((d_ptr->panelModality != NonModal)
&& d_ptr->scene
@@ -2524,7 +2564,9 @@ void QGraphicsItem::setOpacity(qreal opacity)
// Update.
if (d_ptr->scene) {
#ifndef QT_NO_GRAPHICSEFFECT
- d_ptr->invalidateGraphicsEffectsRecursively();
+ d_ptr->invalidateParentGraphicsEffectsRecursively();
+ if (!(d_ptr->flags & ItemDoesntPropagateOpacityToChildren))
+ d_ptr->invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::OpacityChanged);
#endif //QT_NO_GRAPHICSEFFECT
d_ptr->scene->d_func()->markDirty(this, QRectF(),
/*invalidateChildren=*/true,
@@ -2569,6 +2611,8 @@ void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect)
if (d_ptr->graphicsEffect) {
delete d_ptr->graphicsEffect;
d_ptr->graphicsEffect = 0;
+ } else if (d_ptr->parent) {
+ d_ptr->parent->d_ptr->updateChildWithGraphicsEffectFlagRecursively();
}
if (effect) {
@@ -2582,6 +2626,19 @@ void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect)
}
#endif //QT_NO_GRAPHICSEFFECT
+void QGraphicsItemPrivate::updateChildWithGraphicsEffectFlagRecursively()
+{
+#ifndef QT_NO_GRAPHICSEFFECT
+ QGraphicsItemPrivate *itemPrivate = this;
+ do {
+ // parent chain already notified?
+ if (itemPrivate->mayHaveChildWithGraphicsEffect)
+ return;
+ itemPrivate->mayHaveChildWithGraphicsEffect = 1;
+ } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0));
+#endif
+}
+
/*!
\internal
\since 4.6
@@ -2998,9 +3055,16 @@ void QGraphicsItem::setActive(bool active)
*/
bool QGraphicsItem::hasFocus() const
{
+ if (!d_ptr->scene || !d_ptr->scene->isActive())
+ return false;
+
if (d_ptr->focusProxy)
return d_ptr->focusProxy->hasFocus();
- return isActive() && (d_ptr->scene && d_ptr->scene->focusItem() == this);
+
+ if (d_ptr->scene->d_func()->focusItem != this)
+ return false;
+
+ return panel() == d_ptr->scene->d_func()->activePanel;
}
/*!
@@ -4258,9 +4322,9 @@ void QGraphicsItem::setZValue(qreal z)
if (newZ == d_ptr->z)
return;
- if (d_ptr->scene) {
+ if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex) {
// Z Value has changed, we have to notify the index.
- d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, newZVariant);
+ d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, &newZ);
}
d_ptr->z = newZ;
@@ -5027,7 +5091,7 @@ int QGraphicsItemPrivate::depth() const
\internal
*/
#ifndef QT_NO_GRAPHICSEFFECT
-void QGraphicsItemPrivate::invalidateGraphicsEffectsRecursively()
+void QGraphicsItemPrivate::invalidateParentGraphicsEffectsRecursively()
{
QGraphicsItemPrivate *itemPrivate = this;
do {
@@ -5039,6 +5103,24 @@ void QGraphicsItemPrivate::invalidateGraphicsEffectsRecursively()
}
} while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0));
}
+
+void QGraphicsItemPrivate::invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::InvalidateReason reason)
+{
+ if (!mayHaveChildWithGraphicsEffect)
+ return;
+
+ for (int i = 0; i < children.size(); ++i) {
+ QGraphicsItemPrivate *childPrivate = children.at(i)->d_ptr.data();
+ if (reason == OpacityChanged && (childPrivate->flags & QGraphicsItem::ItemIgnoresParentOpacity))
+ continue;
+ if (childPrivate->graphicsEffect) {
+ childPrivate->notifyInvalidated = 1;
+ static_cast<QGraphicsItemEffectSourcePrivate *>(childPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache();
+ }
+
+ childPrivate->invalidateChildGraphicsEffectsRecursively(reason);
+ }
+}
#endif //QT_NO_GRAPHICSEFFECT
/*!
@@ -5283,7 +5365,7 @@ void QGraphicsItem::update(const QRectF &rect)
// Make sure we notify effects about invalidated source.
#ifndef QT_NO_GRAPHICSEFFECT
- d_ptr->invalidateGraphicsEffectsRecursively();
+ d_ptr->invalidateParentGraphicsEffectsRecursively();
#endif //QT_NO_GRAPHICSEFFECT
if (CacheMode(d_ptr->cacheMode) != NoCache) {
@@ -7176,19 +7258,7 @@ void QGraphicsItem::prepareGeometryChange()
}
}
- QGraphicsItem *parent = this;
- while ((parent = parent->d_ptr->parent)) {
- QGraphicsItemPrivate *parentp = parent->d_ptr.data();
- parentp->dirtyChildrenBoundingRect = 1;
- // ### Only do this if the parent's effect applies to the entire subtree.
- parentp->notifyBoundingRectChanged = 1;
-#ifndef QT_NO_GRAPHICSEFFECT
- if (parentp->scene && parentp->graphicsEffect) {
- parentp->notifyInvalidated = 1;
- static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func()->source->d_func())->invalidateCache();
- }
-#endif
- }
+ d_ptr->markParentDirty(/*updateBoundingRect=*/true);
}
/*!
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index 2d34b80..5ad6cd5 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -153,7 +153,7 @@ public:
dirtyChildren(0),
localCollisionHack(0),
inSetPosHelper(0),
- needSortChildren(1), // ### can be 0 by default?
+ needSortChildren(0),
allChildrenDirty(0),
fullUpdatePending(0),
flags(0),
@@ -178,6 +178,8 @@ public:
sequentialOrdering(1),
updateDueToGraphicsEffect(0),
scenePosDescendants(0),
+ pendingPolish(0),
+ mayHaveChildWithGraphicsEffect(0),
globalStackingOrder(-1),
q_ptr(0)
{
@@ -195,8 +197,10 @@ public:
return item->d_ptr.data();
}
+ void updateChildWithGraphicsEffectFlagRecursively();
void updateAncestorFlag(QGraphicsItem::GraphicsItemFlag childFlag,
AncestorFlag flag = NoFlag, bool enabled = false, bool root = true);
+ void updateAncestorFlags();
void setIsMemberOfGroup(bool enabled);
void remapItemPos(QEvent *event, QGraphicsItem *item);
QPointF genericMapFromScene(const QPointF &pos, const QWidget *viewport) const;
@@ -223,13 +227,18 @@ public:
bool ignoreDirtyBit = false, bool ignoreOpacity = false) const;
int depth() const;
#ifndef QT_NO_GRAPHICSEFFECT
- void invalidateGraphicsEffectsRecursively();
+ enum InvalidateReason {
+ OpacityChanged
+ };
+ void invalidateParentGraphicsEffectsRecursively();
+ void invalidateChildGraphicsEffectsRecursively(InvalidateReason reason);
#endif //QT_NO_GRAPHICSEFFECT
void invalidateDepthRecursively();
void resolveDepth();
void addChild(QGraphicsItem *child);
void removeChild(QGraphicsItem *child);
- void setParentItemHelper(QGraphicsItem *parent);
+ void setParentItemHelper(QGraphicsItem *parent, const QVariant *newParentVariant,
+ const QVariant *thisPointerVariant);
void childrenBoundingRectHelper(QTransform *x, QRectF *rect);
void initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform,
const QRegion &exposedRegion, bool allItems = false) const;
@@ -397,6 +406,8 @@ public:
return !visible || (childrenCombineOpacity() && isFullyTransparent());
}
+ inline void markParentDirty(bool updateBoundingRect = false);
+
void setFocusHelper(Qt::FocusReason focusReason, bool climb);
void setSubFocus(QGraphicsItem *rootItem = 0);
void clearSubFocus(QGraphicsItem *rootItem = 0);
@@ -484,6 +495,8 @@ public:
quint32 sequentialOrdering : 1;
quint32 updateDueToGraphicsEffect : 1;
quint32 scenePosDescendants : 1;
+ quint32 pendingPolish : 1;
+ quint32 mayHaveChildWithGraphicsEffect : 1;
// Optional stacking order
int globalStackingOrder;
@@ -721,11 +734,13 @@ inline QTransform QGraphicsItemPrivate::transformToParent() const
inline void QGraphicsItemPrivate::ensureSortedChildren()
{
if (needSortChildren) {
- qSort(children.begin(), children.end(), qt_notclosestLeaf);
needSortChildren = 0;
sequentialOrdering = 1;
+ if (children.isEmpty())
+ return;
+ qSort(children.begin(), children.end(), qt_notclosestLeaf);
for (int i = 0; i < children.size(); ++i) {
- if (children[i]->d_ptr->siblingIndex != i) {
+ if (children.at(i)->d_ptr->siblingIndex != i) {
sequentialOrdering = 0;
break;
}
@@ -741,6 +756,37 @@ inline bool QGraphicsItemPrivate::insertionOrder(QGraphicsItem *a, QGraphicsItem
return a->d_ptr->siblingIndex < b->d_ptr->siblingIndex;
}
+/*!
+ \internal
+*/
+inline void QGraphicsItemPrivate::markParentDirty(bool updateBoundingRect)
+{
+ QGraphicsItemPrivate *parentp = this;
+ while (parentp->parent) {
+ parentp = parentp->parent->d_ptr.data();
+ parentp->dirtyChildren = 1;
+
+ if (updateBoundingRect) {
+ parentp->dirtyChildrenBoundingRect = 1;
+ // ### Only do this if the parent's effect applies to the entire subtree.
+ parentp->notifyBoundingRectChanged = 1;
+ }
+#ifndef QT_NO_GRAPHICSEFFECT
+ if (parentp->graphicsEffect) {
+ if (updateBoundingRect) {
+ parentp->notifyInvalidated = 1;
+ static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func()
+ ->source->d_func())->invalidateCache();
+ }
+ if (parentp->graphicsEffect->isEnabled()) {
+ parentp->dirty = 1;
+ parentp->fullUpdatePending = 1;
+ }
+ }
+#endif
+ }
+}
+
QT_END_NAMESPACE
#endif // QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index cea723c..9219773 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -292,7 +292,6 @@ QGraphicsScenePrivate::QGraphicsScenePrivate()
processDirtyItemsEmitted(false),
selectionChanging(0),
needSortTopLevelItems(true),
- unpolishedItemsModified(true),
holesInTopLevelSiblingIndex(false),
topLevelSequentialOrdering(true),
scenePosDescendantsUpdatePending(false),
@@ -429,22 +428,38 @@ void QGraphicsScenePrivate::unregisterTopLevelItem(QGraphicsItem *item)
*/
void QGraphicsScenePrivate::_q_polishItems()
{
- QSet<QGraphicsItem *>::Iterator it = unpolishedItems.begin();
+ if (unpolishedItems.isEmpty())
+ return;
+
const QVariant booleanTrueVariant(true);
- while (!unpolishedItems.isEmpty()) {
- QGraphicsItem *item = *it;
- it = unpolishedItems.erase(it);
- unpolishedItemsModified = false;
- if (!item->d_ptr->explicitlyHidden) {
+ QGraphicsItem *item = 0;
+ QGraphicsItemPrivate *itemd = 0;
+ const int oldUnpolishedCount = unpolishedItems.count();
+
+ for (int i = 0; i < oldUnpolishedCount; ++i) {
+ item = unpolishedItems.at(i);
+ if (!item)
+ continue;
+ itemd = item->d_ptr.data();
+ itemd->pendingPolish = false;
+ if (!itemd->explicitlyHidden) {
item->itemChange(QGraphicsItem::ItemVisibleChange, booleanTrueVariant);
item->itemChange(QGraphicsItem::ItemVisibleHasChanged, booleanTrueVariant);
}
- if (item->isWidget()) {
+ if (itemd->isWidget) {
QEvent event(QEvent::Polish);
QApplication::sendEvent((QGraphicsWidget *)item, &event);
}
- if (unpolishedItemsModified)
- it = unpolishedItems.begin();
+ }
+
+ if (unpolishedItems.count() == oldUnpolishedCount) {
+ // No new items were added to the vector.
+ unpolishedItems.clear();
+ } else {
+ // New items were appended; keep them and remove the old ones.
+ unpolishedItems.remove(0, oldUnpolishedCount);
+ unpolishedItems.squeeze();
+ QMetaObject::invokeMethod(q_ptr, "_q_polishItems", Qt::QueuedConnection);
}
}
@@ -599,7 +614,7 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
if (parentItem->scene()) {
Q_ASSERT_X(parentItem->scene() == q, "QGraphicsScene::removeItem",
"Parent item's scene is different from this item's scene");
- item->d_ptr->setParentItemHelper(0);
+ item->setParentItem(0);
}
} else {
unregisterTopLevelItem(item);
@@ -638,8 +653,12 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
selectedItems.remove(item);
hoverItems.removeAll(item);
cachedItemsUnderMouse.removeAll(item);
- unpolishedItems.remove(item);
- unpolishedItemsModified = true;
+ if (item->d_ptr->pendingPolish) {
+ const int unpolishedIndex = unpolishedItems.indexOf(item);
+ if (unpolishedIndex != -1)
+ unpolishedItems[unpolishedIndex] = 0;
+ item->d_ptr->pendingPolish = false;
+ }
resetDirtyItem(item);
//We remove all references of item from the sceneEventFilter arrays
@@ -1936,7 +1955,7 @@ QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rectangle, Qt::ItemSe
\since 4.3
This convenience function is equivalent to calling items(QRectF(\a x, \a y, \a w, \a h), \a mode).
-
+
This function is deprecated and returns incorrect results if the scene
contains items that ignore transformations. Use the overload that takes
a QTransform instead.
@@ -2482,12 +2501,12 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
qWarning("QGraphicsScene::addItem: cannot add null item");
return;
}
- if (item->scene() == this) {
+ if (item->d_ptr->scene == this) {
qWarning("QGraphicsScene::addItem: item has already been added to this scene");
return;
}
// Remove this item from its existing scene
- if (QGraphicsScene *oldScene = item->scene())
+ if (QGraphicsScene *oldScene = item->d_ptr->scene)
oldScene->removeItem(item);
// Notify the item that its scene is changing, and allow the item to
@@ -2496,15 +2515,20 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
qVariantFromValue<QGraphicsScene *>(this)));
QGraphicsScene *targetScene = qVariantValue<QGraphicsScene *>(newSceneVariant);
if (targetScene != this) {
- if (targetScene && item->scene() != targetScene)
+ if (targetScene && item->d_ptr->scene != targetScene)
targetScene->addItem(item);
return;
}
+ if (d->unpolishedItems.isEmpty())
+ QMetaObject::invokeMethod(this, "_q_polishItems", Qt::QueuedConnection);
+ d->unpolishedItems.append(item);
+ item->d_ptr->pendingPolish = true;
+
// Detach this item from its parent if the parent's scene is different
// from this scene.
- if (QGraphicsItem *itemParent = item->parentItem()) {
- if (itemParent->scene() != this)
+ if (QGraphicsItem *itemParent = item->d_ptr->parent) {
+ if (itemParent->d_ptr->scene != this)
item->setParentItem(0);
}
@@ -2534,7 +2558,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
d->enableMouseTrackingOnViews();
}
#ifndef QT_NO_CURSOR
- if (d->allItemsUseDefaultCursor && item->hasCursor()) {
+ if (d->allItemsUseDefaultCursor && item->d_ptr->hasCursor) {
d->allItemsUseDefaultCursor = false;
if (d->allItemsIgnoreHoverEvents) // already enabled otherwise
d->enableMouseTrackingOnViews();
@@ -2542,7 +2566,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
#endif //QT_NO_CURSOR
// Enable touch events if the item accepts touch events.
- if (d->allItemsIgnoreTouchEvents && item->acceptTouchEvents()) {
+ if (d->allItemsIgnoreTouchEvents && item->d_ptr->acceptTouchEvents) {
d->allItemsIgnoreTouchEvents = false;
d->enableTouchEventsOnViews();
}
@@ -2575,17 +2599,14 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
}
// Add all children recursively
- foreach (QGraphicsItem *child, item->children())
- addItem(child);
+ item->d_ptr->ensureSortedChildren();
+ for (int i = 0; i < item->d_ptr->children.size(); ++i)
+ addItem(item->d_ptr->children.at(i));
// Resolve font and palette.
item->d_ptr->resolveFont(d->font.resolve());
item->d_ptr->resolvePalette(d->palette.resolve());
- if (d->unpolishedItems.isEmpty())
- QMetaObject::invokeMethod(this, "_q_polishItems", Qt::QueuedConnection);
- d->unpolishedItems.insert(item);
- d->unpolishedItemsModified = true;
// Reenable selectionChanged() for individual items
--d->selectionChanging;
@@ -2619,7 +2640,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
}
}
- if (item->flags() & QGraphicsItem::ItemSendsScenePositionChanges)
+ if (item->d_ptr->flags & QGraphicsItem::ItemSendsScenePositionChanges)
d->registerScenePosItem(item);
// Ensure that newly added items that have subfocus set, gain
@@ -3766,10 +3787,10 @@ void QGraphicsScene::helpEvent(QGraphicsSceneHelpEvent *helpEvent)
bool QGraphicsScenePrivate::itemAcceptsHoverEvents_helper(const QGraphicsItem *item) const
{
- return (!item->isBlockedByModalPanel() &&
- (item->acceptHoverEvents()
- || (item->isWidget()
- && static_cast<const QGraphicsWidget *>(item)->d_func()->hasDecoration())));
+ return (item->d_ptr->acceptsHover
+ || (item->d_ptr->isWidget
+ && static_cast<const QGraphicsWidget *>(item)->d_func()->hasDecoration()))
+ && !item->isBlockedByModalPanel();
}
/*!
@@ -4882,17 +4903,7 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b
if (ignoreOpacity)
item->d_ptr->ignoreOpacity = 1;
- QGraphicsItem *p = item->d_ptr->parent;
- while (p) {
- p->d_ptr->dirtyChildren = 1;
-#ifndef QT_NO_GRAPHICSEFFECT
- if (p->d_ptr->graphicsEffect && p->d_ptr->graphicsEffect->isEnabled()) {
- p->d_ptr->dirty = 1;
- p->d_ptr->fullUpdatePending = 1;
- }
-#endif //QT_NO_GRAPHICSEFFECT
- p = p->d_ptr->parent;
- }
+ item->d_ptr->markParentDirty();
}
static inline bool updateHelper(QGraphicsViewPrivate *view, QGraphicsItemPrivate *item,
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
index d10811c..54d8130 100644
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_p.h
@@ -108,10 +108,9 @@ public:
QPainterPath selectionArea;
int selectionChanging;
QSet<QGraphicsItem *> selectedItems;
- QSet<QGraphicsItem *> unpolishedItems;
+ QVector<QGraphicsItem *> unpolishedItems;
QList<QGraphicsItem *> topLevelItems;
bool needSortTopLevelItems;
- bool unpolishedItemsModified;
bool holesInTopLevelSiblingIndex;
bool topLevelSequentialOrdering;
diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp
index 2e92b87..2a91348 100644
--- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp
+++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp
@@ -635,16 +635,17 @@ void QGraphicsSceneBspTreeIndex::updateSceneRect(const QRectF &rect)
This method react to the \a change of the \a item and use the \a value to
update the BSP tree if necessary.
*/
-void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value)
+void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const void *const value)
{
Q_D(QGraphicsSceneBspTreeIndex);
switch (change) {
case QGraphicsItem::ItemFlagsChange: {
// Handle ItemIgnoresTransformations
+ QGraphicsItem::GraphicsItemFlags newFlags = *static_cast<const QGraphicsItem::GraphicsItemFlags *>(value);
bool ignoredTransform = item->d_ptr->flags & QGraphicsItem::ItemIgnoresTransformations;
- bool willIgnoreTransform = value.toUInt() & QGraphicsItem::ItemIgnoresTransformations;
+ bool willIgnoreTransform = newFlags & QGraphicsItem::ItemIgnoresTransformations;
bool clipsChildren = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape;
- bool willClipChildren = value.toUInt() & QGraphicsItem::ItemClipsChildrenToShape;
+ bool willClipChildren = newFlags & QGraphicsItem::ItemClipsChildrenToShape;
if ((ignoredTransform != willIgnoreTransform) || (clipsChildren != willClipChildren)) {
QGraphicsItem *thatItem = const_cast<QGraphicsItem *>(item);
// Remove item and its descendants from the index and append
@@ -661,7 +662,7 @@ void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphics
case QGraphicsItem::ItemParentChange: {
d->invalidateSortCache();
// Handle ItemIgnoresTransformations
- QGraphicsItem *newParent = qVariantValue<QGraphicsItem *>(value);
+ const QGraphicsItem *newParent = static_cast<const QGraphicsItem *>(value);
bool ignoredTransform = item->d_ptr->itemIsUntransformable();
bool willIgnoreTransform = (item->d_ptr->flags & QGraphicsItem::ItemIgnoresTransformations)
|| (newParent && newParent->d_ptr->itemIsUntransformable());
@@ -682,7 +683,6 @@ void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphics
default:
break;
}
- return QGraphicsSceneIndex::itemChange(item, change, value);
}
/*!
\reimp
diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h
index 119571b..f671fd9 100644
--- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h
+++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h
@@ -97,7 +97,7 @@ protected:
void removeItem(QGraphicsItem *item);
void prepareBoundingRectChange(const QGraphicsItem *item);
- void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value);
+ void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const void *const value);
private :
Q_DECLARE_PRIVATE(QGraphicsSceneBspTreeIndex)
diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp
index bc8a7dc..043c4eb 100644
--- a/src/gui/graphicsview/qgraphicssceneindex.cpp
+++ b/src/gui/graphicsview/qgraphicssceneindex.cpp
@@ -624,7 +624,7 @@ void QGraphicsSceneIndex::deleteItem(QGraphicsItem *item)
\sa QGraphicsItem::GraphicsItemChange
*/
-void QGraphicsSceneIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value)
+void QGraphicsSceneIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const void *const value)
{
Q_UNUSED(item);
Q_UNUSED(change);
diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h
index def58f0..597a229 100644
--- a/src/gui/graphicsview/qgraphicssceneindex_p.h
+++ b/src/gui/graphicsview/qgraphicssceneindex_p.h
@@ -110,7 +110,7 @@ protected:
virtual void removeItem(QGraphicsItem *item) = 0;
virtual void deleteItem(QGraphicsItem *item);
- virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value);
+ virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const void *const value);
virtual void prepareBoundingRectChange(const QGraphicsItem *item);
QGraphicsSceneIndex(QGraphicsSceneIndexPrivate &dd, QGraphicsScene *scene);
diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp
index 854be2e..42e19b8 100644
--- a/src/gui/image/qbmphandler.cpp
+++ b/src/gui/image/qbmphandler.cpp
@@ -144,7 +144,7 @@ static QDataStream &operator<<(QDataStream &s, const BMP_INFOHDR &bi)
static int calc_shift(int mask)
{
int result = 0;
- while (!(mask & 1)) {
+ while (mask && !(mask & 1)) {
result++;
mask >>= 1;
}
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index 674d5da..f823fdc 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -833,14 +833,21 @@ bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConvers
if (QPixmapCache::find(key, *this))
return true;
- QPixmapData *tmp = QPixmapData::create(0, 0, QPixmapData::PixmapType);
- if (tmp->fromFile(fileName, format, flags)) {
- data = tmp;
- QPixmapCache::insert(key, *this);
- return true;
+ bool ok;
+
+ if (data) {
+ ok = data->fromFile(fileName, format, flags);
+ } else {
+ QScopedPointer<QPixmapData> tmp(QPixmapData::create(0, 0, QPixmapData::PixmapType));
+ ok = tmp->fromFile(fileName, format, flags);
+ if (ok)
+ data = tmp.take();
}
- delete tmp;
- return false;
+
+ if (ok)
+ QPixmapCache::insert(key, *this);
+
+ return ok;
}
/*!
diff --git a/src/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h
index 0b84e2f..f5034fc 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_p.h
+++ b/src/gui/inputmethod/qcoefepinputcontext_p.h
@@ -57,6 +57,7 @@
#include "qinputcontext.h"
#include <qhash.h>
+#include <qtimer.h>
#include <private/qcore_symbian_p.h>
#include <private/qt_s60_p.h>
@@ -91,6 +92,9 @@ public:
TCoeInputCapabilities inputCapabilities();
+protected:
+ void timerEvent(QTimerEvent *timerEvent);
+
private:
void commitCurrentString(bool triggeredBySymbian);
void updateHints(bool mustUpdateInputCapabilities);
@@ -98,6 +102,7 @@ private:
void applyFormat(QList<QInputMethodEvent::Attribute> *attributes);
void queueInputCapabilitiesChanged();
bool needsInputPanel();
+ void commitTemporaryPreeditString();
private Q_SLOTS:
void ensureInputCapabilitiesChanged();
@@ -148,6 +153,8 @@ private:
MFepPointerEventHandlerDuringInlineEdit *m_pointerHandler;
int m_longPress;
int m_cursorPos;
+ QBasicTimer m_tempPreeditStringTimeout;
+ bool m_hasTempPreeditString;
};
QT_END_NAMESPACE
diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
index d2f207a..793bcde 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
+++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
@@ -72,7 +72,8 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
m_formatRetriever(0),
m_pointerHandler(0),
m_longPress(0),
- m_cursorPos(0)
+ m_cursorPos(0),
+ m_hasTempPreeditString(false)
{
m_fepState->SetObjectProvider(this);
m_fepState->SetFlags(EAknEditorFlagDefault);
@@ -100,6 +101,8 @@ QCoeFepInputContext::~QCoeFepInputContext()
void QCoeFepInputContext::reset()
{
+ commitTemporaryPreeditString();
+
CCoeFep* fep = CCoeEnv::Static()->Fep();
if (fep)
fep->CancelTransaction();
@@ -200,7 +203,11 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event)
if (!focusWidget())
return false;
- if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) {
+ switch (event->type()) {
+ case QEvent::KeyPress:
+ commitTemporaryPreeditString();
+ // fall through intended
+ case QEvent::KeyRelease:
const QKeyEvent *keyEvent = static_cast<const QKeyEvent *>(event);
switch (keyEvent->key()) {
case Qt::Key_F20:
@@ -223,6 +230,21 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event)
default:
break;
}
+
+ if (keyEvent->type() == QEvent::KeyPress
+ && focusWidget()->inputMethodHints() & Qt::ImhHiddenText
+ && !keyEvent->text().isEmpty()) {
+ // Send some temporary preedit text in order to make text visible for a moment.
+ m_preeditString = keyEvent->text();
+ QList<QInputMethodEvent::Attribute> attributes;
+ QInputMethodEvent imEvent(m_preeditString, attributes);
+ QApplication::sendEvent(focusWidget(), &imEvent);
+ m_tempPreeditStringTimeout.start(1000, this);
+ m_hasTempPreeditString = true;
+ update();
+ return true;
+ }
+ break;
}
if (!needsInputPanel())
@@ -253,6 +275,24 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event)
return false;
}
+void QCoeFepInputContext::timerEvent(QTimerEvent *timerEvent)
+{
+ if (timerEvent->timerId() == m_tempPreeditStringTimeout.timerId())
+ commitTemporaryPreeditString();
+}
+
+void QCoeFepInputContext::commitTemporaryPreeditString()
+{
+ if (m_tempPreeditStringTimeout.isActive())
+ m_tempPreeditStringTimeout.stop();
+
+ if (!m_hasTempPreeditString)
+ return;
+
+ commitCurrentString(false);
+ m_hasTempPreeditString = false;
+}
+
void QCoeFepInputContext::mouseHandler( int x, QMouseEvent *event)
{
Q_ASSERT(focusWidget());
@@ -310,6 +350,8 @@ void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints)
{
using namespace Qt;
+ commitTemporaryPreeditString();
+
bool numbersOnly = hints & ImhDigitsOnly || hints & ImhFormattedNumbersOnly
|| hints & ImhDialableCharactersOnly;
bool noOnlys = !(numbersOnly || hints & ImhUppercaseOnly
@@ -501,6 +543,8 @@ void QCoeFepInputContext::StartFepInlineEditL(const TDesC& aInitialInlineText,
if (!w)
return;
+ commitTemporaryPreeditString();
+
m_cursorPos = w->inputMethodQuery(Qt::ImCursorPosition).toInt();
QList<QInputMethodEvent::Attribute> attributes;
@@ -600,6 +644,8 @@ void QCoeFepInputContext::SetCursorSelectionForFepL(const TCursorSelection& aCur
if (!w)
return;
+ commitTemporaryPreeditString();
+
int pos = aCursorSelection.iAnchorPos;
int length = aCursorSelection.iCursorPos - pos;
diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp
index 7eefb0b..3111896 100644
--- a/src/gui/itemviews/qtableview.cpp
+++ b/src/gui/itemviews/qtableview.cpp
@@ -114,7 +114,9 @@ void QSpanCollection::updateSpan(QSpanCollection::Span *span, int old_height)
}
} else if (old_height > span->height()) {
//remove the span from all the subspans lists that intersect the columns not covered anymore
- Index::iterator it_y = index.lowerBound(qMin(-span->bottom(), 0));
+ Index::iterator it_y = index.lowerBound(-span->bottom());
+ if (it_y == index.end())
+ it_y = index.find(-span->top()); // This is the only span remaining and we are deleting it.
Q_ASSERT(it_y != index.end()); //it_y must exist since the span is in the list
while (-it_y.key() <= span->top() + old_height -1) {
if (-it_y.key() > span->bottom()) {
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index 12fe797..4fe3900 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -121,8 +121,10 @@ extern bool qt_wince_is_pocket_pc(); //qguifunctions_wince.cpp
static void initResources()
{
-#ifdef Q_WS_WINCE
+#if defined(Q_WS_WINCE)
Q_INIT_RESOURCE(qstyle_wince);
+#elif defined(Q_OS_SYMBIAN)
+ Q_INIT_RESOURCE(qstyle_s60);
#else
Q_INIT_RESOURCE(qstyle);
#endif
diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm
index 6aebef5..e8b821af 100644
--- a/src/gui/kernel/qapplication_mac.mm
+++ b/src/gui/kernel/qapplication_mac.mm
@@ -227,8 +227,29 @@ void onApplicationChangedActivation( bool activated );
static void qt_mac_read_fontsmoothing_settings()
{
- NSInteger appleFontSmoothing = [[NSUserDefaults standardUserDefaults] integerForKey:@"AppleFontSmoothing"];
- qt_applefontsmoothing_enabled = (appleFontSmoothing > 0);
+ qt_applefontsmoothing_enabled = true;
+ int w = 10, h = 10;
+ QImage image(w, h, QImage::Format_RGB32);
+ image.fill(0xffffffff);
+ QPainter p(&image);
+ p.drawText(0, h, "X\\");
+ p.end();
+
+ const int *bits = (const int *) ((const QImage &) image).bits();
+ int bpl = image.bytesPerLine() / 4;
+ for (int y=0; y<w; ++y) {
+ for (int x=0; x<h; ++x) {
+ int r = qRed(bits[x]);
+ int g = qGreen(bits[x]);
+ int b = qBlue(bits[x]);
+ if (r != g || r != b) {
+ qt_applefontsmoothing_enabled = true;
+ return;
+ }
+ }
+ bits += bpl;
+ }
+ qt_applefontsmoothing_enabled = false;
}
Q_GUI_EXPORT bool qt_mac_execute_apple_script(const char *script, long script_len, AEDesc *ret) {
@@ -772,11 +793,11 @@ static void qt_mac_update_intersected_gl_widgets(QWidget *widget)
qt_post_window_change_event(glWidget);
it->lastUpdateWidget = widget;
} else if (it->lastUpdateWidget == widget) {
- // Update the gl wigets that the widget intersected the last time around,
- // and that we are not intersecting now. This prevents paint errors when the
+ // Update the gl wigets that the widget intersected the last time around,
+ // and that we are not intersecting now. This prevents paint errors when the
// intersecting widget leaves a gl widget.
qt_post_window_change_event(glWidget);
- it->lastUpdateWidget = 0;
+ it->lastUpdateWidget = 0;
}
}
#else
@@ -808,8 +829,8 @@ Q_GUI_EXPORT void qt_event_request_window_change(QWidget *widget)
// Post a kEventQtRequestWindowChange event. This event is semi-public,
// don't remove this line!
qt_event_request_window_change();
-
- // Post update request on gl widgets unconditionally.
+
+ // Post update request on gl widgets unconditionally.
if (qt_widget_private(widget)->isGLWidget == true) {
qt_post_window_change_event(widget);
return;
@@ -1214,8 +1235,6 @@ void qt_init(QApplicationPrivate *priv, int)
if (QApplication::desktopSettingsAware())
QApplicationPrivate::qt_mac_apply_settings();
- qt_mac_read_fontsmoothing_settings();
-
// Cocoa application delegate
#ifdef QT_MAC_USE_COCOA
NSApplication *cocoaApp = [NSApplication sharedApplication];
@@ -1253,6 +1272,7 @@ void qt_init(QApplicationPrivate *priv, int)
}
priv->native_modal_dialog_active = false;
+ qt_mac_read_fontsmoothing_settings();
}
void qt_release_apple_event_handler()
@@ -1705,7 +1725,7 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event
// kEventMouseWheelMoved events if we dont eat this event
// (actually two events; one for horizontal and one for vertical).
// As a results of this, and to make sure we dont't receive duplicate events,
- // we try to detect when this happend by checking the 'compatibilityEvent'.
+ // we try to detect when this happend by checking the 'compatibilityEvent'.
SInt32 mdelt = 0;
GetEventParameter(event, kEventParamMouseWheelSmoothHorizontalDelta, typeSInt32, 0,
sizeof(mdelt), 0, &mdelt);
@@ -2576,7 +2596,7 @@ void QApplicationPrivate::closePopup(QWidget *popup)
if (QApplicationPrivate::popupWidgets->isEmpty()) { // this was the last popup
delete QApplicationPrivate::popupWidgets;
QApplicationPrivate::popupWidgets = 0;
-
+
// Special case for Tool windows: since they are activated and deactived together
// with a normal window they never become the QApplicationPrivate::active_window.
QWidget *appFocusWidget = QApplication::focusWidget();
diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h
index f8943a8..9c001ab 100644
--- a/src/gui/kernel/qapplication_p.h
+++ b/src/gui/kernel/qapplication_p.h
@@ -501,9 +501,9 @@ public:
static TUint resolveS60ScanCode(TInt scanCode, TUint keysym);
QSet<WId> nativeWindows;
- int symbianProcessWsEvent(const TWsEvent *event);
- int symbianHandleCommand(int command);
- int symbianResourceChange(int type);
+ int symbianProcessWsEvent(const QSymbianEvent *symbianEvent);
+ int symbianHandleCommand(const QSymbianEvent *symbianEvent);
+ int symbianResourceChange(const QSymbianEvent *symbianEvent);
#endif
#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS)
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 8c77728..6caac9f 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -71,6 +71,7 @@
# include <private/qcoefepinputcontext_p.h>
# endif
# include <private/qs60mainapplication_p.h>
+# include <centralrepository.h>
#endif
#include "private/qstylesheetstyle_p.h"
@@ -1204,6 +1205,24 @@ void qt_init(QApplicationPrivate * /* priv */, int)
S60->virtualMouseRequired = false;
}
+ S60->avkonComponentsSupportTransparency = false;
+
+#ifdef Q_WS_S60
+ TUid KCRUidAvkon = { 0x101F876E };
+ TUint32 KAknAvkonTransparencyEnabled = 0x0000000D;
+
+ CRepository* repository = 0;
+ TRAP(err, repository = CRepository::NewL(KCRUidAvkon));
+
+ if(err == KErrNone) {
+ TInt value = 0;
+ err = repository->Get(KAknAvkonTransparencyEnabled, value);
+ if(err == KErrNone) {
+ S60->avkonComponentsSupportTransparency = (value==1) ? true : false;
+ }
+ }
+#endif
+
if (touch) {
QApplicationPrivate::navigationMode = Qt::NavigationModeNone;
} else {
@@ -1528,6 +1547,12 @@ void QApplication::beep()
qt_S60Beep->Play();
}
+static inline bool callSymbianEventFilters(const QSymbianEvent *event)
+{
+ long unused;
+ return qApp->filterEvent(const_cast<QSymbianEvent *>(event), &unused);
+}
+
/*!
\warning This function is only available on Symbian.
\since 4.6
@@ -1544,6 +1569,9 @@ int QApplication::symbianProcessEvent(const QSymbianEvent *event)
QScopedLoopLevelCounter counter(d->threadData);
+ if (d->eventDispatcher->filterEvent(const_cast<QSymbianEvent *>(event)))
+ return 1;
+
QWidget *w = qApp ? qApp->focusWidget() : 0;
if (w) {
QInputContext *ic = w->inputContext();
@@ -1556,29 +1584,34 @@ int QApplication::symbianProcessEvent(const QSymbianEvent *event)
switch (event->type()) {
case QSymbianEvent::WindowServerEvent:
- return d->symbianProcessWsEvent(event->windowServerEvent());
+ return d->symbianProcessWsEvent(event);
case QSymbianEvent::CommandEvent:
- return d->symbianHandleCommand(event->command());
+ return d->symbianHandleCommand(event);
case QSymbianEvent::ResourceChangeEvent:
- return d->symbianResourceChange(event->resourceChangeType());
+ return d->symbianResourceChange(event);
default:
return -1;
}
}
-int QApplicationPrivate::symbianProcessWsEvent(const TWsEvent *event)
+int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent)
{
// Qt event handling. Handle some events regardless of if the handle is in our
// widget map or not.
+ const TWsEvent *event = symbianEvent->windowServerEvent();
CCoeControl* control = reinterpret_cast<CCoeControl*>(event->Handle());
const bool controlInMap = QWidgetPrivate::mapper && QWidgetPrivate::mapper->contains(control);
switch (event->Type()) {
case EEventPointerEnter:
- if (controlInMap)
+ if (controlInMap) {
+ callSymbianEventFilters(symbianEvent);
return 1; // Qt::Enter will be generated in HandlePointerL
+ }
break;
case EEventPointerExit:
if (controlInMap) {
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
if (S60) {
// mouseEvent outside our window, send leave event to last focused widget
QMouseEvent mEvent(QEvent::Leave, S60->lastPointerEventPos, S60->lastCursorPos,
@@ -1591,6 +1624,8 @@ int QApplicationPrivate::symbianProcessWsEvent(const TWsEvent *event)
}
break;
case EEventScreenDeviceChanged:
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
if (S60)
S60->updateScreenSize();
if (qt_desktopWidget) {
@@ -1603,6 +1638,8 @@ int QApplicationPrivate::symbianProcessWsEvent(const TWsEvent *event)
return 0; // Propagate to CONE
case EEventWindowVisibilityChanged:
if (controlInMap) {
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
const TWsVisibilityChangedEvent *visChangedEvent = event->VisibilityChanged();
QWidget *w = QWidgetPrivate::mapper->value(control);
if (!w->d_func()->maybeTopData())
@@ -1620,6 +1657,8 @@ int QApplicationPrivate::symbianProcessWsEvent(const TWsEvent *event)
}
break;
case EEventFocusGained:
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
#ifndef QT_NO_CURSOR
//re-enable mouse interaction
if (S60->mouseInteractionEnabled) {
@@ -1633,6 +1672,8 @@ int QApplicationPrivate::symbianProcessWsEvent(const TWsEvent *event)
#endif
break;
case EEventFocusLost:
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
#ifndef QT_NO_CURSOR
//disable mouse as may be moving to application that does not support it
if (S60->mouseInteractionEnabled) {
@@ -1684,11 +1725,16 @@ bool QApplication::symbianEventFilter(const QSymbianEvent *event)
\sa s60EventFilter(), s60ProcessEvent()
*/
-int QApplicationPrivate::symbianHandleCommand(int command)
+int QApplicationPrivate::symbianHandleCommand(const QSymbianEvent *symbianEvent)
{
Q_Q(QApplication);
int ret = 0;
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
+
+ int command = symbianEvent->command();
+
switch (command) {
#ifdef Q_WS_S60
case EAknSoftkeyExit: {
@@ -1728,14 +1774,18 @@ int QApplicationPrivate::symbianHandleCommand(int command)
Currently, KEikDynamicLayoutVariantSwitch and
KAknsMessageSkinChange are handled.
*/
-int QApplicationPrivate::symbianResourceChange(int type)
+int QApplicationPrivate::symbianResourceChange(const QSymbianEvent *symbianEvent)
{
int ret = 0;
+ int type = symbianEvent->resourceChangeType();
+
switch (type) {
#ifdef Q_WS_S60
case KEikDynamicLayoutVariantSwitch:
{
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
if (S60)
S60->updateScreenSize();
@@ -1760,6 +1810,8 @@ int QApplicationPrivate::symbianResourceChange(int type)
#ifndef QT_NO_STYLE_S60
case KAknsMessageSkinChange:
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
if (QS60Style *s60Style = qobject_cast<QS60Style*>(QApplication::style())) {
s60Style->d_func()->handleSkinChange();
ret = 1;
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index c14798a..f61d2fe 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -510,7 +510,7 @@ extern "C" {
}
// Make sure the opengl context is updated on resize.
- if (0 && qwidgetprivate->isGLWidget) {
+ if (qwidgetprivate->isGLWidget) {
qwidgetprivate->needWindowChange = true;
QEvent event(QEvent::MacGLWindowChange);
qApp->sendEvent(qwidget, &event);
diff --git a/src/gui/kernel/qformlayout.cpp b/src/gui/kernel/qformlayout.cpp
index b44cd50..aebc3a5 100644
--- a/src/gui/kernel/qformlayout.cpp
+++ b/src/gui/kernel/qformlayout.cpp
@@ -1925,11 +1925,11 @@ void QFormLayoutPrivate::arrangeWidgets(const QVector<QLayoutStruct>& layouts, Q
/*
If the field on the right-hand side is tall,
we want the label to be top-aligned, but not too
- much. So we introduce a 5 / 4 factor so that it
- gets a few extra pixels at the top.
+ much. So we introduce a 7 / 4 factor so that it
+ gets some extra pixels at the top.
*/
height = qMin(height,
- qMin(label->sizeHint.height() * 5 / 4,
+ qMin(label->sizeHint.height() * 7 / 4,
label->maxSize.height()));
}
diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
index b417065..1163055 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/gui/kernel/qt_s60_p.h
@@ -121,6 +121,7 @@ public:
int virtualMouseRequired : 1;
int qtOwnsS60Environment : 1;
int supportsPremultipliedAlpha : 1;
+ int avkonComponentsSupportTransparency : 1;
QApplication::QS60MainApplicationFactory s60ApplicationFactory; // typedef'ed pointer type
static inline void updateScreenSize();
static inline RWsSession& wsSession();
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 81a9a80..ede87de 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -2026,6 +2026,14 @@ void QWidgetPrivate::updateIsOpaque()
}
#endif
+#ifdef Q_WS_S60
+ if (q->windowType() == Qt::Dialog && q->testAttribute(Qt::WA_TranslucentBackground)
+ && S60->avkonComponentsSupportTransparency) {
+ setOpaque(false);
+ return;
+ }
+#endif
+
if (q->testAttribute(Qt::WA_OpaquePaintEvent) || q->testAttribute(Qt::WA_PaintOnScreen)) {
setOpaque(true);
return;
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index b18830f..3dbc843 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -3414,6 +3414,38 @@ void QWidgetPrivate::hide_sys()
ShowHide(window, false);
#else
[window orderOut:window];
+ // Unfortunately it is not as easy as just hiding the window, we need
+ // to find out if we were in full screen mode. If we were and this is
+ // the last window in full screen mode then we need to unset the full screen
+ // mode. If this is not the last visible window in full screen mode then we
+ // don't change the full screen mode.
+ if(q->isFullScreen())
+ {
+ bool keepFullScreen = false;
+ QWidgetList windowList = qApp->topLevelWidgets();
+ int windowCount = windowList.count();
+ for(int i = 0; i < windowCount; i++)
+ {
+ QWidget *w = windowList[i];
+ // If it is the same window, we don't need to check :-)
+ if(q == w)
+ continue;
+ // If they are not visible or if they are minimized then
+ // we just ignore them.
+ if(!w->isVisible() || w->isMinimized())
+ continue;
+ // Is it full screen?
+ // Notice that if there is one window in full screen mode then we
+ // cannot switch the full screen mode off, therefore we just abort.
+ if(w->isFullScreen()) {
+ keepFullScreen = true;
+ break;
+ }
+ }
+ // No windows in full screen mode, so let just unset that flag.
+ if(!keepFullScreen)
+ qt_mac_set_fullscreen_mode(false);
+ }
#endif
toggleDrawers(false);
#ifndef QT_MAC_USE_COCOA
diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index f51dc36..d6d288e 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -934,8 +934,7 @@ void QColor::setRgb(int r, int g, int b, int a)
/*!
\fn QRgb QColor::rgba() const
- Returns the RGB value of the color. Unlike rgb(), the alpha is not
- stripped.
+ Returns the RGB value of the color, including its alpha.
For an invalid color, the alpha value of the returned color is unspecified.
@@ -950,8 +949,7 @@ QRgb QColor::rgba() const
}
/*!
- Sets the RGBA value to \a rgba. Unlike setRgb(QRgb rgb), this function does
- not ignore the alpha.
+ Sets the RGB value to \a rgba, including its alpha.
\sa rgba(), rgb()
*/
@@ -968,8 +966,7 @@ void QColor::setRgba(QRgb rgba)
/*!
\fn QRgb QColor::rgb() const
- Returns the RGB value of the color. The alpha is stripped for
- compatibility.
+ Returns the RGB value of the color. The alpha value is opaque.
\sa getRgb(), rgba()
*/
@@ -983,7 +980,7 @@ QRgb QColor::rgb() const
/*!
\overload
- Sets the RGB value to \a rgb, ignoring the alpha.
+ Sets the RGB value to \a rgb. The alpha value is set to opaque.
*/
void QColor::setRgb(QRgb rgb)
{
diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h
index b937f66..a1c73cc 100644
--- a/src/gui/painting/qpaintengine_raster_p.h
+++ b/src/gui/painting/qpaintengine_raster_p.h
@@ -264,13 +264,13 @@ private:
#endif // Q_OS_SYMBIAN && QT_NO_FREETYPE
inline void ensureBrush(const QBrush &brush) {
- if (!qbrush_fast_equals(state()->lastBrush, brush) || state()->fillFlags)
+ if (!qbrush_fast_equals(state()->lastBrush, brush) || (brush.style() != Qt::NoBrush && state()->fillFlags))
updateBrush(brush);
}
inline void ensureBrush() { ensureBrush(state()->brush); }
inline void ensurePen(const QPen &pen) {
- if (!qpen_fast_equals(state()->lastPen, pen) || state()->strokeFlags)
+ if (!qpen_fast_equals(state()->lastPen, pen) || (pen.style() != Qt::NoPen && state()->strokeFlags))
updatePen(pen);
}
inline void ensurePen() { ensurePen(state()->pen); }
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index a9dcea0..cde6a2d 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -1374,9 +1374,6 @@ void QPainterPrivate::updateState(QPainterState *newState)
opacity with non-smooth transformation mode
(\c QPainter::SmoothPixmapTransform not enabled as a render hint).
- \o Text drawing with regular font sizes with simple
- transformations with solid colors using no or 8-bit antialiasing.
-
\o Rectangle fills with solid color, two-color linear gradients
and simple transforms.
@@ -7385,10 +7382,15 @@ struct QPaintDeviceRedirection
typedef QList<QPaintDeviceRedirection> QPaintDeviceRedirectionList;
Q_GLOBAL_STATIC(QPaintDeviceRedirectionList, globalRedirections)
Q_GLOBAL_STATIC(QMutex, globalRedirectionsMutex)
+Q_GLOBAL_STATIC(QAtomicInt, globalRedirectionAtomic)
/*!
\threadsafe
+ \obsolete
+
+ Please use QWidget::render() instead.
+
Redirects all paint commands for the given paint \a device, to the
\a replacement device. The optional point \a offset defines an
offset within the source device.
@@ -7398,9 +7400,10 @@ Q_GLOBAL_STATIC(QMutex, globalRedirectionsMutex)
device's painter (if any) before redirecting. Call
restoreRedirected() to restore the previous redirection.
- In general, you'll probably find that calling
- QPixmap::grabWidget() or QPixmap::grabWindow() is an easier
- solution.
+ \warning Making use of redirections in the QPainter API implies
+ that QPainter::begin() and QPaintDevice destructors need to hold
+ a mutex for a short period. This can impact performance. Use of
+ QWidget::render is strongly encouraged.
\sa redirected(), restoreRedirected()
*/
@@ -7432,14 +7435,24 @@ void QPainter::setRedirected(const QPaintDevice *device,
Q_ASSERT(redirections != 0);
*redirections += QPaintDeviceRedirection(device, rdev ? rdev : replacement, offset + roffset,
hadInternalWidgetRedirection ? redirections->size() - 1 : -1);
+ globalRedirectionAtomic()->ref();
}
/*!
\threadsafe
+ \obsolete
+
+ Using QWidget::render() obsoletes the use of this function.
+
Restores the previous redirection for the given \a device after a
call to setRedirected().
+ \warning Making use of redirections in the QPainter API implies
+ that QPainter::begin() and QPaintDevice destructors need to hold
+ a mutex for a short period. This can impact performance. Use of
+ QWidget::render is strongly encouraged.
+
\sa redirected()
*/
void QPainter::restoreRedirected(const QPaintDevice *device)
@@ -7450,6 +7463,7 @@ void QPainter::restoreRedirected(const QPaintDevice *device)
Q_ASSERT(redirections != 0);
for (int i = redirections->size()-1; i >= 0; --i) {
if (redirections->at(i) == device) {
+ globalRedirectionAtomic()->deref();
const int internalWidgetRedirectionIndex = redirections->at(i).internalWidgetRedirectionIndex;
redirections->removeAt(i);
// Restore the internal widget redirection, i.e. remove it from the global
@@ -7471,9 +7485,18 @@ void QPainter::restoreRedirected(const QPaintDevice *device)
/*!
\threadsafe
+ \obsolete
+
+ Using QWidget::render() obsoletes the use of this function.
+
Returns the replacement for given \a device. The optional out
parameter \a offset returns the offset within the replaced device.
+ \warning Making use of redirections in the QPainter API implies
+ that QPainter::begin() and QPaintDevice destructors need to hold
+ a mutex for a short period. This can impact performance. Use of
+ QWidget::render is strongly encouraged.
+
\sa setRedirected(), restoreRedirected()
*/
QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset)
@@ -7486,6 +7509,9 @@ QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset)
return widgetPrivate->redirected(offset);
}
+ if (*globalRedirectionAtomic() == 0)
+ return 0;
+
QMutexLocker locker(globalRedirectionsMutex());
QPaintDeviceRedirectionList *redirections = globalRedirections();
Q_ASSERT(redirections != 0);
@@ -7503,6 +7529,9 @@ QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset)
void qt_painter_removePaintDevice(QPaintDevice *dev)
{
+ if (*globalRedirectionAtomic() == 0)
+ return;
+
QMutex *mutex = 0;
QT_TRY {
mutex = globalRedirectionsMutex();
diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp
index 211f4ce..b5f052b 100644
--- a/src/gui/styles/qgtkstyle.cpp
+++ b/src/gui/styles/qgtkstyle.cpp
@@ -1106,8 +1106,14 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element,
// ### Note: Ubuntulooks breaks when the proper widget is passed
// Murrine engine requires a widget not to get RGBA check - warnings
GtkWidget *gtkCheckButton = d->gtkWidget(QLS("GtkCheckButton"));
- gtkPainter.paintOption(gtkCheckButton , buttonRect, state, shadow, gtkRadioButton->style, QLS("radiobutton"));
-
+ QString key(QLS("radiobutton"));
+ if (option->state & State_HasFocus) { // Themes such as Nodoka check this flag
+ key += QLatin1Char('f');
+ GTK_WIDGET_SET_FLAGS(gtkCheckButton, GTK_HAS_FOCUS);
+ }
+ gtkPainter.paintOption(gtkCheckButton , buttonRect, state, shadow, gtkRadioButton->style, key);
+ if (option->state & State_HasFocus)
+ GTK_WIDGET_UNSET_FLAGS(gtkCheckButton, GTK_HAS_FOCUS);
}
break;
@@ -1128,6 +1134,11 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element,
int spacing;
GtkWidget *gtkCheckButton = d->gtkWidget(QLS("GtkCheckButton"));
+ QString key(QLS("checkbutton"));
+ if (option->state & State_HasFocus) { // Themes such as Nodoka checks this flag
+ key += QLatin1Char('f');
+ GTK_WIDGET_SET_FLAGS(gtkCheckButton, GTK_HAS_FOCUS);
+ }
// Some styles such as aero-clone assume they can paint in the spacing area
gtkPainter.setClipRect(option->rect);
@@ -1137,7 +1148,10 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element,
QRect checkRect = option->rect.adjusted(spacing, spacing, -spacing, -spacing);
gtkPainter.paintCheckbox(gtkCheckButton, checkRect, state, shadow, gtkCheckButton->style,
- QLS("checkbutton"));
+ key);
+ if (option->state & State_HasFocus)
+ GTK_WIDGET_UNSET_FLAGS(gtkCheckButton, GTK_HAS_FOCUS);
+
}
break;
diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp
index ca0b8c7..ecb3242 100644
--- a/src/gui/styles/qs60style.cpp
+++ b/src/gui/styles/qs60style.cpp
@@ -68,6 +68,10 @@
#include "qtoolbutton.h"
#include "qfocusframe.h"
#include "qformlayout.h"
+#include "qradiobutton.h"
+#include "qcheckbox.h"
+#include "qdesktopwidget.h"
+#include "qprogressbar.h"
#include "private/qtoolbarextension_p.h"
#include "private/qcombobox_p.h"
@@ -564,9 +568,11 @@ QPixmap QS60StylePrivate::cachedPart(QS60StyleEnums::SkinParts part,
const QSize &size, QPainter *painter, SkinElementFlags flags)
{
QPixmap result;
+ const int animationFrame = (flags & SF_Animation) ? currentAnimationFrame(part) : 0;
+
const QString cacheKey =
- QString::fromLatin1("S60Style: SkinParts=%1 QSize=%2|%3 SkinPartFlags=%4")
- .arg((int)part).arg(size.width()).arg(size.height()).arg((int)flags);
+ QString::fromLatin1("S60Style: SkinParts=%1 QSize=%2|%3 SkinPartFlags=%4 AnimationFrame=%5")
+ .arg((int)part).arg(size.width()).arg(size.height()).arg((int)flags).arg(animationFrame);
if (!QPixmapCache::find(cacheKey, result)) {
result = QS60StylePrivate::part(part, size, painter, flags);
QPixmapCache::insert(cacheKey, result);
@@ -672,8 +678,7 @@ void QS60StylePrivate::setThemePalette(QPalette *palette) const
s60Color(QS60StyleEnums::CL_QsnHighlightColors, 2, 0));
// set background image as a texture brush
palette->setBrush(QPalette::Window, backgroundTexture());
- // set these as transparent so that styled full screen theme background is visible
- palette->setColor(QPalette::AlternateBase, Qt::transparent);
+ // set as transparent so that styled full screen theme background is visible
palette->setBrush(QPalette::Base, Qt::transparent);
// set button and tooltipbase based on pixel colors
const QColor buttonColor = colorFromFrameGraphics(SF_ButtonNormal);
@@ -685,6 +690,9 @@ void QS60StylePrivate::setThemePalette(QPalette *palette) const
palette->setColor(QPalette::Midlight, palette->color(QPalette::Button).lighter(125));
palette->setColor(QPalette::Mid, palette->color(QPalette::Button).darker(150));
palette->setColor(QPalette::Shadow, Qt::black);
+ QColor alternateBase = palette->light().color();
+ alternateBase.setAlphaF(0.8);
+ palette->setColor(QPalette::AlternateBase, alternateBase);
QApplication::setPalette(*palette); //calling QApplication::setPalette clears palette hash
setThemePaletteHash(palette);
@@ -775,6 +783,11 @@ void QS60StylePrivate::setThemePaletteHash(QPalette *palette) const
QApplication::setPalette(widgetPalette, "QComboBox");
widgetPalette = *palette;
+ widgetPalette.setColor(QPalette::WindowText, s60Color(QS60StyleEnums::CL_QsnTextColors, 7, 0));
+ QApplication::setPalette(widgetPalette, "QRadioButton");
+ QApplication::setPalette(widgetPalette, "QCheckBox");
+ widgetPalette = *palette;
+
widgetPalette.setColor(QPalette::WindowText, mainAreaTextColor);
widgetPalette.setColor(QPalette::Button, QApplication::palette().color(QPalette::Button));
widgetPalette.setColor(QPalette::Dark, mainAreaTextColor.darker());
@@ -813,13 +826,13 @@ QSize QS60StylePrivate::partSize(QS60StyleEnums::SkinParts part, SkinElementFlag
//ratio of 1:2 for horizontal tab bars (and 2:1 for vertical ones).
result.setWidth(result.height() >> 1);
break;
-
+
case QS60StyleEnums::SP_QgnGrafNsliderEndLeft:
case QS60StyleEnums::SP_QgnGrafNsliderEndRight:
case QS60StyleEnums::SP_QgnGrafNsliderMiddle:
result.setWidth(result.height() >> 1);
break;
-
+
case QS60StyleEnums::SP_QgnGrafNsliderMarker:
case QS60StyleEnums::SP_QgnGrafNsliderMarkerSelected:
result.scale(pixelMetric(QStyle::PM_SliderLength),
@@ -922,10 +935,10 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom
horizontal ? QS60StylePrivate::SE_ScrollBarGrooveHorizontal : QS60StylePrivate::SE_ScrollBarGrooveVertical;
QS60StylePrivate::drawSkinElement(grooveElement, painter, grooveRect, flags);
- const QStyle::SubControls subControls = optionSlider->subControls;
+ const SubControls subControls = optionSlider->subControls;
// select correct slider (horizontal/vertical/pressed)
- const bool sliderPressed = ((optionSlider->state & QStyle::State_Sunken) && (subControls & SC_ScrollBarSlider));
+ const bool sliderPressed = ((optionSlider->state & State_Sunken) && (subControls & SC_ScrollBarSlider));
const QS60StylePrivate::SkinElements handleElement =
horizontal ?
( sliderPressed ?
@@ -946,13 +959,13 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom
const bool horizontal = optionSlider->orientation == Qt::Horizontal;
//Highlight
-/* if (optionSlider->state & QStyle::State_HasFocus)
+/* if (optionSlider->state & State_HasFocus)
drawPrimitive(PE_FrameFocusRect, optionSlider, painter, widget);*/
-
+
//Groove graphics
if (QS60StylePrivate::hasSliderGrooveGraphic()) {
- const QS60StylePrivate::SkinElements grooveElement = horizontal ?
- QS60StylePrivate::SE_SliderGrooveHorizontal :
+ const QS60StylePrivate::SkinElements grooveElement = horizontal ?
+ QS60StylePrivate::SE_SliderGrooveHorizontal :
QS60StylePrivate::SE_SliderGrooveVertical;
QS60StylePrivate::drawSkinElement(grooveElement, painter, sliderGroove, flags);
} else {
@@ -975,7 +988,7 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom
if (optionSlider->state & QStyle::State_Sunken)
handleElement =
horizontal ? QS60StylePrivate::SE_SliderHandleSelectedHorizontal : QS60StylePrivate::SE_SliderHandleSelectedVertical;
- else
+ else
handleElement =
horizontal ? QS60StylePrivate::SE_SliderHandleHorizontal : QS60StylePrivate::SE_SliderHandleVertical;
QS60StylePrivate::drawSkinElement(handleElement, painter, sliderHandle, flags);
@@ -994,7 +1007,7 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom
buttonOption.QStyleOption::operator=(*cmb);
const int maxHeight = cmbxFrame.height();
const int maxWidth = cmbxFrame.width() - cmbxEditField.width();
- const int topLeftPoint = direction ?
+ const int topLeftPoint = direction ?
(cmbxEditField.right() + 1) : (cmbxEditField.left() + 1 - maxWidth);
const QRect buttonRect(topLeftPoint, cmbxEditField.top(), maxWidth, maxHeight);
buttonOption.rect = buttonRect;
@@ -1020,102 +1033,62 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom
#ifndef QT_NO_TOOLBUTTON
case CC_ToolButton:
if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
- const State bflags = toolBtn->state;
+ State bflags = toolBtn->state & ~State_Sunken;
+
+ if (bflags & State_AutoRaise) {
+ if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) {
+ bflags &= ~State_Raised;
+ }
+ }
+ State mflags = bflags;
+ if (toolBtn->state & State_Sunken) {
+ if (toolBtn->activeSubControls & SC_ToolButton)
+ bflags |= State_Sunken;
+ mflags |= State_Sunken;
+ }
+
const QRect button(subControlRect(control, toolBtn, SC_ToolButton, widget));
QRect menuRect = QRect();
if (toolBtn->subControls & SC_ToolButtonMenu)
menuRect = subControlRect(control, toolBtn, SC_ToolButtonMenu, widget);
- QStyleOptionToolButton toolButton = *toolBtn;
-
- if (sub&SC_ToolButton) {
+ if (toolBtn->subControls & SC_ToolButton) {
QStyleOption tool(0);
tool.palette = toolBtn->palette;
- // Check if toolbutton is in toolbar.
- QToolBar *toolBar = 0;
- if (widget)
- toolBar = qobject_cast<QToolBar *>(widget->parentWidget());
-
- if (bflags & (State_Sunken | State_On | State_Raised)) {
+ if (bflags & (State_Sunken | State_On | State_Raised | State_Enabled)) {
tool.rect = button.unite(menuRect);
tool.state = bflags;
-
- // todo: I'd like to move extension button next to where last button is
- // however, the painter seems to want to clip the button rect even if I turn of the clipping.
- if (toolBar && (qobject_cast<const QToolBarExtension *>(widget))){
- /*QList<QAction *> actionList = toolBar->actions();
- const int actionCount = actionList.count();
- const int toolbarWidth = toolBar->width();
- const int extButtonWidth = pixelMetric(PM_ToolBarExtensionExtent, option, widget);
- const int toolBarButtonWidth = pixelMetric(PM_ToolBarIconSize, option, widget);
- const int frame = pixelMetric(PM_ToolBarFrameWidth, option, widget);
- const int margin = pixelMetric(PM_ToolBarItemMargin, option, widget);
- const int border = frame + margin;
- const int spacing = pixelMetric(PM_ToolBarItemSpacing, option, widget);
- const int toolBarButtonArea = toolbarWidth - extButtonWidth - spacing - 2*border;
- const int numberOfVisibleButtons = toolBarButtonArea / toolBarButtonWidth;
- // new extension button place is after border and all the other visible buttons (with spacings)
- const int newXForExtensionButton = numberOfVisibleButtons * toolBarButtonWidth + (numberOfVisibleButtons-1)*spacing + border;
- painter->save();
- painter->setClipping(false);
- tool.rect.translate(-newXForExtensionButton,0);
- painter->restore();*/
- }
-
- if (toolBar){
- /*if (toolBar->orientation() == Qt::Vertical){
- // todo: I'd like to make all vertical buttons the same size, but again the painter
- // prefers to use clipping for button rects, even though clipping has been set off.
- painter->save();
- painter->setClipping(false);
-
- const int origWidth = tool.rect.width();
- const int newWidth = toolBar->width()-2*pixelMetric(PM_ToolBarFrameWidth, option, widget);
- painter->translate(origWidth-newWidth,0);
- tool.rect.translate(origWidth-tool.rect.width(),0);
- tool.rect.setWidth(newWidth);
-
- if (option->state & QStyle::State_Sunken)
- QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButtonPressed, painter, tool.rect, flags);
- else
- QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButton, painter, tool.rect, flags);
-
- }*/
- if (option->state & QStyle::State_Sunken)
- QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButtonPressed, painter, tool.rect, flags);
- else
- QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButton, painter, tool.rect, flags);
- /*
- if (toolBar->orientation() == Qt::Vertical)
- painter->restore();
- */
- } else {
- drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
- }
-
- if (toolButton.subControls & SC_ToolButtonMenu) {
- tool.rect = menuRect;
- tool.state = bflags;
- drawPrimitive(PE_IndicatorArrowDown, &tool, painter, widget);
- }
+ const QToolButton *toolButtonWidget = qobject_cast<const QToolButton *>(widget);
+ QS60StylePrivate::SkinElements element;
+ if (toolButtonWidget)
+ element = (toolButtonWidget->isDown()) ? QS60StylePrivate::SE_ToolBarButtonPressed : QS60StylePrivate::SE_ToolBarButton;
+ else
+ element = (option->state & State_Sunken) ? QS60StylePrivate::SE_ToolBarButtonPressed : QS60StylePrivate::SE_ToolBarButton;
+ QS60StylePrivate::drawSkinElement(element, painter, tool.rect, flags);
+ drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
+ }
+ if (toolBtn->subControls & SC_ToolButtonMenu) {
+ tool.rect = menuRect;
+ tool.state = mflags;
+ drawPrimitive(PE_IndicatorArrowDown, &tool, painter, widget);
}
}
-
+ QStyleOptionToolButton toolButton = *toolBtn;
if (toolBtn->features & QStyleOptionToolButton::Arrow) {
- QStyle::PrimitiveElement pe;
+ PrimitiveElement pe;
switch (toolBtn->arrowType) {
case Qt::LeftArrow:
- pe = QStyle::PE_IndicatorArrowLeft;
+ pe = PE_IndicatorArrowLeft;
break;
case Qt::RightArrow:
- pe = QStyle::PE_IndicatorArrowRight;
+ pe = PE_IndicatorArrowRight;
break;
case Qt::UpArrow:
- pe = QStyle::PE_IndicatorArrowUp;
+ pe = PE_IndicatorArrowUp;
break;
case Qt::DownArrow:
- pe = QStyle::PE_IndicatorArrowDown;
+ pe = PE_IndicatorArrowDown;
break;
default:
break; }
@@ -1199,7 +1172,7 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom
// Draw frame
const QRect textRect = subControlRect(CC_GroupBox, option, SC_GroupBoxLabel, widget);
const QRect checkBoxRect = subControlRect(CC_GroupBox, option, SC_GroupBoxCheckBox, widget);
- if (groupBox->subControls & QStyle::SC_GroupBoxFrame) {
+ if (groupBox->subControls & SC_GroupBoxFrame) {
QStyleOptionFrameV2 frame;
frame.QStyleOption::operator=(*groupBox);
frame.features = groupBox->features;
@@ -1210,14 +1183,14 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom
}
// Draw title
- if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
+ if ((groupBox->subControls & SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
const QColor textColor = groupBox->textColor;
painter->save();
if (textColor.isValid())
painter->setPen(textColor);
int alignment = int(groupBox->textAlignment);
- if (!styleHint(QStyle::SH_UnderlineShortcut, option, widget))
+ if (!styleHint(SH_UnderlineShortcut, option, widget))
alignment |= Qt::TextHideMnemonic;
drawItemText(painter, textRect, Qt::TextShowMnemonic | Qt::AlignHCenter | Qt::AlignVCenter | alignment,
@@ -1249,6 +1222,31 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
Q_D(const QS60Style);
const QS60StylePrivate::SkinElementFlags flags = (option->state & State_Enabled) ? QS60StylePrivate::SF_StateEnabled : QS60StylePrivate::SF_StateDisabled;
switch (element) {
+ case CE_CheckBox:
+ case CE_RadioButton:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ bool isRadio = (element == CE_RadioButton);
+ // Highlight needs to be drawn first, as it goes "underneath" the text and indicator.
+ if (btn->state & State_HasFocus) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*btn);
+ fropt.rect = subElementRect(isRadio ? SE_RadioButtonFocusRect
+ : SE_CheckBoxFocusRect, btn, widget);
+ drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
+ }
+ QStyleOptionButton subopt = *btn;
+
+ subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator
+ : SE_CheckBoxIndicator, btn, widget);
+ drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox,
+ &subopt, painter, widget);
+ subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents
+ : SE_CheckBoxContents, btn, widget);
+
+ drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, painter, widget);
+ }
+ break;
+
case CE_PushButton:
if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
@@ -1261,13 +1259,13 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
break;
case CE_PushButtonBevel:
if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
- const bool isDisabled = !(option->state & QStyle::State_Enabled);
+ const bool isDisabled = !(option->state & State_Enabled);
const bool isFlat = button->features & QStyleOptionButton::Flat;
QS60StyleEnums::SkinParts skinPart;
QS60StylePrivate::SkinElements skinElement;
if (!isDisabled) {
- const bool isPressed = (option->state & QStyle::State_Sunken) ||
- (option->state & QStyle::State_On);
+ const bool isPressed = (option->state & State_Sunken) ||
+ (option->state & State_On);
if (isFlat) {
skinPart =
isPressed ? QS60StyleEnums::SP_QsnFrButtonTbCenterPressed : QS60StyleEnums::SP_QsnFrButtonTbCenter;
@@ -1292,7 +1290,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
QStyleOptionToolButton optionToolButton = *toolBtn;
- if (!optionToolButton.icon.isNull() && (optionToolButton.state & QStyle::State_Sunken)
+ if (!optionToolButton.icon.isNull() && (optionToolButton.state & State_Sunken)
&& (optionToolButton.state & State_Enabled)) {
const QIcon::State state = optionToolButton.state & State_On ? QIcon::On : QIcon::Off;
@@ -1351,8 +1349,8 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
painter->save();
painter->setClipRect(voptAdj.rect);
- const bool isSelected = (vopt->state & QStyle::State_Selected);
- const bool hasFocus = (vopt->state & QStyle::State_HasFocus);
+ const bool isSelected = (vopt->state & State_Selected);
+ const bool hasFocus = (vopt->state & State_HasFocus);
bool isScrollBarVisible = false;
int scrollBarWidth = 0;
@@ -1426,8 +1424,8 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
}
// draw the icon
- const QIcon::Mode mode = (voptAdj.state & QStyle::State_Enabled) ? QIcon::Normal : QIcon::Disabled;
- const QIcon::State state = voptAdj.state & QStyle::State_Open ? QIcon::On : QIcon::Off;
+ const QIcon::Mode mode = (voptAdj.state & State_Enabled) ? QIcon::Normal : QIcon::Disabled;
+ const QIcon::State state = voptAdj.state & State_Open ? QIcon::On : QIcon::Off;
voptAdj.icon.paint(painter, iconRect, voptAdj.decorationAlignment, mode, state);
// Draw selection check mark. Show check mark only in multi selection modes.
@@ -1439,29 +1437,29 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
QStyleOptionViewItemV4 checkMarkOption(voptAdj);
// Draw selection mark.
- if (voptAdj.state & QStyle::State_Selected && !singleSelection) {
+ if (voptAdj.state & State_Selected && !singleSelection) {
checkMarkOption.rect = selectionRect;
- drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget);
+ drawPrimitive(PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget);
if ( textRect.right() > selectionRect.left() )
textRect.setRight(selectionRect.left());
} else if (singleSelection &&
voptAdj.features & QStyleOptionViewItemV2::HasCheckIndicator &&
selectionRect.isValid()) {
checkMarkOption.rect = selectionRect;
- checkMarkOption.state = checkMarkOption.state & ~QStyle::State_HasFocus;
+ checkMarkOption.state = checkMarkOption.state & ~State_HasFocus;
switch (vopt->checkState) {
case Qt::Unchecked:
- checkMarkOption.state |= QStyle::State_Off;
+ checkMarkOption.state |= State_Off;
break;
case Qt::PartiallyChecked:
- checkMarkOption.state |= QStyle::State_NoChange;
+ checkMarkOption.state |= State_NoChange;
break;
case Qt::Checked:
- checkMarkOption.state |= QStyle::State_On;
+ checkMarkOption.state |= State_On;
break;
}
- drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget);
+ drawPrimitive(PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget);
}
}
@@ -1486,7 +1484,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
case CE_TabBarTabShape:
if (const QStyleOptionTabV3 *optionTab = qstyleoption_cast<const QStyleOptionTabV3 *>(option)) {
QStyleOptionTabV3 optionTabAdj = *optionTab;
- const bool isSelected = optionTab->state & QStyle::State_Selected;
+ const bool isSelected = optionTab->state & State_Selected;
const bool directionMirrored = (optionTab->direction == Qt::RightToLeft);
QS60StylePrivate::SkinElements skinElement;
switch (optionTab->shape) {
@@ -1521,9 +1519,9 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
skinElement==QS60StylePrivate::SE_TabBarTabSouthActive||
skinElement==QS60StylePrivate::SE_TabBarTabWestActive) {
const int borderThickness =
- QS60StylePrivate::pixelMetric(QStyle::PM_DefaultFrameWidth);
+ QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
const int tabOverlap =
- QS60StylePrivate::pixelMetric(QStyle::PM_TabBarTabOverlap) - borderThickness;
+ QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap) - borderThickness;
//todo: draw navi wipe behind tabbar - must be drawn with first draw
if (skinElement==QS60StylePrivate::SE_TabBarTabEastInactive||
@@ -1546,9 +1544,9 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
QStyleOptionTabV3 optionTab = *tab;
QRect tr = optionTab.rect;
const bool directionMirrored = (optionTab.direction == Qt::RightToLeft);
- const int borderThickness = QS60StylePrivate::pixelMetric(QStyle::PM_DefaultFrameWidth);
+ const int borderThickness = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
const int tabOverlap =
- QS60StylePrivate::pixelMetric(QStyle::PM_TabBarTabOverlap) - borderThickness;
+ QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap) - borderThickness;
const QRect windowRect = painter->window();
switch (tab->shape) {
@@ -1602,12 +1600,12 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
m.rotate(newRotation);
painter->setTransform(m, true);
}
- tr.adjust(0, 0, pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget),
- pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget));
+ tr.adjust(0, 0, pixelMetric(PM_TabBarTabShiftHorizontal, tab, widget),
+ pixelMetric(PM_TabBarTabShiftVertical, tab, widget));
if (selected) {
- tr.setBottom(tr.bottom() - pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget));
- tr.setRight(tr.right() - pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget));
+ tr.setBottom(tr.bottom() - pixelMetric(PM_TabBarTabShiftVertical, tab, widget));
+ tr.setRight(tr.right() - pixelMetric(PM_TabBarTabShiftHorizontal, tab, widget));
}
int alignment = Qt::AlignCenter | Qt::TextShowMnemonic;
@@ -1648,17 +1646,20 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
// busy indicator
const QS60StylePrivate::SkinElementFlag orientationFlag = optionProgressBar->orientation == Qt::Horizontal ?
QS60StylePrivate::SF_PointNorth : QS60StylePrivate::SF_PointWest;
- QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnGrafBarWait, painter, progressRect, flags | orientationFlag);
+
+ QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnGrafBarWaitAnim,
+ painter, progressRect, flags | orientationFlag | QS60StylePrivate::SF_Animation );
} else {
const qreal progressFactor = (optionProgressBar->minimum == optionProgressBar->maximum) ? 1.0
: (qreal)optionProgressBar->progress / optionProgressBar->maximum;
+ const int frameWidth = pixelMetric(PM_DefaultFrameWidth, option, widget);
if (optionProgressBar->orientation == Qt::Horizontal) {
progressRect.setWidth(int(progressRect.width() * progressFactor));
if(optionProgressBar->direction == Qt::RightToLeft)
- progressRect.translate(optionProgressBar->rect.width()-progressRect.width(), 0);
- progressRect.adjust(1, 0, -1, 0);
+ progressRect.translate(optionProgressBar->rect.width() - progressRect.width(), 0);
+ progressRect.adjust(frameWidth, 0, -frameWidth, 0);
} else {
- progressRect.adjust(0, 1, 0, -1);
+ progressRect.adjust(0, frameWidth, 0, -frameWidth);
progressRect.setTop(progressRect.bottom() - int(progressRect.height() * progressFactor));
}
@@ -1714,9 +1715,9 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
QRect textRect = subElementRect(SE_ItemViewItemText, &optionMenuItem, widget);
//todo: move the vertical spacing stuff into subElementRect
- const int vSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutVerticalSpacing);
+ const int vSpacing = QS60StylePrivate::pixelMetric(PM_LayoutVerticalSpacing);
if (checkable){
- const int hSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
+ const int hSpacing = QS60StylePrivate::pixelMetric(PM_LayoutHorizontalSpacing);
QStyleOptionMenuItem optionCheckBox;
optionCheckBox.QStyleOptionMenuItem::operator=(*menuItem);
optionCheckBox.rect.setWidth(pixelMetric(PM_IndicatorWidth));
@@ -1754,7 +1755,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
QStyleOptionMenuItem arrowOptions;
arrowOptions.QStyleOption::operator=(*menuItem);
const int indicatorWidth = (pixelMetric(PM_ListViewIconSize, option, widget) >> 1) +
- pixelMetric(QStyle::PM_LayoutVerticalSpacing, option, widget);
+ pixelMetric(PM_LayoutVerticalSpacing, option, widget);
if (optionMenuItem.direction == Qt::LeftToRight)
arrowOptions.rect.setLeft(textRect.right());
arrowOptions.rect.setWidth(indicatorWidth);
@@ -1925,8 +1926,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
break;
case CE_MenuScroller:
break;
- case CE_FocusFrame:
- {
+ case CE_FocusFrame: {
// The pen width should nearly fill the layoutspacings around the widget
const int penWidth =
qMin(pixelMetric(QS60Style::PM_LayoutVerticalSpacing), pixelMetric(QS60Style::PM_LayoutHorizontalSpacing))
@@ -1985,11 +1985,21 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
*/
void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
{
- Q_D(const QS60Style);
const QS60StylePrivate::SkinElementFlags flags = (option->state & State_Enabled) ? QS60StylePrivate::SF_StateEnabled : QS60StylePrivate::SF_StateDisabled;
bool commonStyleDraws = false;
switch (element) {
+ case PE_FrameFocusRect: {
+ //Draw themed highlight to radiobuttons and checkboxes.
+ //For other widgets skip, unless palette has been modified. In that case, draw with commonstyle.
+ if (option->palette.highlight().color() == QS60StylePrivate::themePalette()->highlight().color())
+ if ((qstyleoption_cast<const QStyleOptionFocusRect *>(option) &&
+ (qobject_cast<const QRadioButton *>(widget) || qobject_cast<const QCheckBox *>(widget))))
+ QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, option->rect, flags);
+ else
+ commonStyleDraws = true;
+ }
+ break;
#ifndef QT_NO_LINEEDIT
case PE_PanelLineEdit:
if (const QStyleOptionFrame *lineEdit = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
@@ -2004,15 +2014,14 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
}
break;
#endif // QT_NO_LINEEDIT
- case PE_IndicatorCheckBox:
- {
+ case PE_IndicatorCheckBox: {
// Draw checkbox indicator as color skinned graphics.
- const QS60StyleEnums::SkinParts skinPart = (option->state & QStyle::State_On) ?
+ const QS60StyleEnums::SkinParts skinPart = (option->state & State_On) ?
QS60StyleEnums::SP_QgnIndiCheckboxOn : QS60StyleEnums::SP_QgnIndiCheckboxOff;
painter->save();
- QColor themeColor = QS60StylePrivate::themePalette()->windowText().color();
- QColor windowTextColor = option->palette.windowText().color();
+ const QColor themeColor = QS60StylePrivate::themePalette()->windowText().color();
+ const QColor windowTextColor = option->palette.windowText().color();
if (themeColor != windowTextColor)
painter->setPen(windowTextColor);
@@ -2032,7 +2041,7 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
if (checkBoxVisible && singleSelection) {
drawPrimitive(PE_IndicatorCheckBox, option, painter, widget);
// ... or normal "tick" selection at the end.
- } else if (option->state & QStyle::State_Selected) {
+ } else if (option->state & State_Selected) {
QRect tickRect = option->rect;
const int frameBorderWidth = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth);
// adjust tickmark rect to exclude frame border
@@ -2059,15 +2068,15 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
buttonRect.adjust(0, -newY, -1, -newY);
painter->save();
- QColor themeColor = d->s60Color(QS60StyleEnums::CL_QsnTextColors, 6, option);
- QColor buttonTextColor = option->palette.buttonText().color();
+ const QColor themeColor = QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 6, option);
+ const QColor buttonTextColor = option->palette.buttonText().color();
if (themeColor != buttonTextColor)
painter->setPen(buttonTextColor);
else
painter->setPen(themeColor);
// Draw radiobutton indicator as color skinned graphics.
- QS60StyleEnums::SkinParts skinPart = (option->state & QStyle::State_On) ?
+ QS60StyleEnums::SkinParts skinPart = (option->state & State_On) ?
QS60StyleEnums::SP_QgnIndiRadiobuttOn : QS60StyleEnums::SP_QgnIndiRadiobuttOff;
QS60StylePrivate::drawSkinPart(skinPart, painter, buttonRect,
(flags | QS60StylePrivate::SF_ColorSkinned));
@@ -2077,15 +2086,14 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
case PE_PanelButtonCommand:
case PE_PanelButtonTool:
case PE_PanelButtonBevel:
- case PE_FrameButtonBevel: {
+ case PE_FrameButtonBevel:
if (QS60StylePrivate::canDrawThemeBackground(option->palette.base())) {
- const bool isPressed = option->state & QStyle::State_Sunken;
+ const bool isPressed = option->state & State_Sunken;
const QS60StylePrivate::SkinElements skinElement =
isPressed ? QS60StylePrivate::SE_ButtonPressed : QS60StylePrivate::SE_ButtonNormal;
QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags);
} else {
commonStyleDraws = true;
- }
}
break;
#ifndef QT_NO_TOOLBUTTON
@@ -2207,7 +2215,6 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
break;
#ifndef QT_NO_ITEMVIEWS
case PE_PanelItemViewItem:
- case PE_PanelItemViewRow: // ### Qt 5: remove
break;
#endif //QT_NO_ITEMVIEWS
@@ -2276,7 +2283,23 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
}
}
break;
-
+ case PE_PanelItemViewRow: // ### Qt 5: remove
+#ifndef QT_NO_ITEMVIEWS
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) {
+ if (vopt->palette.base().texture().cacheKey() != QS60StylePrivate::m_themePalette->base().texture().cacheKey()) {
+ //QPalette::Base has been changed, let commonstyle draw the item
+ commonStyleDraws = true;
+ } else {
+ QPalette::ColorGroup cg = vopt->state & State_Enabled ? QPalette::Normal : QPalette::Disabled;
+ if (cg == QPalette::Normal && !(vopt->state & State_Active))
+ cg = QPalette::Inactive;
+ if (vopt->features & QStyleOptionViewItemV2::Alternate)
+ painter->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::AlternateBase));
+ //apart from alternate base, no background for list item is drawn for S60Style
+ }
+ }
+#endif
+ break;
case PE_PanelScrollAreaCorner:
break;
@@ -2361,8 +2384,7 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt,
if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt))
sz += QSize(2 * f->lineWidth, 4 * f->lineWidth);
break;
- case CT_TabBarTab:
- {
+ case CT_TabBarTab: {
const QSize naviPaneSize = QS60StylePrivate::naviPaneSize();
sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
if (naviPaneSize.height() > sz.height())
@@ -2374,8 +2396,26 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt,
if (QS60StylePrivate::isTouchSupported())
//Make itemview easier to use in touch devices
//QCommonStyle does not adjust height with horizontal margin, it only adjusts width
- sz.setHeight(sz.height() + 2 * pixelMetric(QStyle::PM_FocusFrameVMargin));
+ sz.setHeight(sz.height() + 2 * pixelMetric(PM_FocusFrameVMargin));
break;
+#ifndef QT_NO_COMBOBOX
+ case CT_ComboBox:
+ if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ const int frameWidth = cmb->frame ? pixelMetric(PM_ComboBoxFrameWidth, opt, widget) * 2 : 0;
+ const int textMargins = 2*(pixelMetric(PM_FocusFrameHMargin) + 1);
+ const int smallestExtraWidth = 23;
+ // QItemDelegate::sizeHint expands the textMargins two times, thus the 2*textMargins...
+ const int extra =
+ qMax(smallestExtraWidth, 2*textMargins + pixelMetric(PM_ScrollBarExtent, opt, widget));
+ sz = QSize(sz.width() + frameWidth + extra, sz.height() + frameWidth);
+ int maxScreenWidth = QApplication::desktop()->availableGeometry().size().width();
+ if (sz.width() > maxScreenWidth) {
+ maxScreenWidth = maxScreenWidth - (extra + frameWidth);
+ sz.setWidth(maxScreenWidth);
+ }
+ }
+ break;
+#endif
default:
sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
break;
@@ -2414,7 +2454,7 @@ int QS60Style::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w
retValue = QPalette::Base;
break;
case SH_ItemView_ActivateItemOnSingleClick:
- retValue = true;
+ retValue = QS60StylePrivate::isSingleClickUi();
break;
case SH_ProgressDialog_TextLabelAlignment:
retValue = (QApplication::layoutDirection() == Qt::LeftToRight) ?
@@ -2526,7 +2566,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple
if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
const int frameThickness = spinbox->frame ? pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0;
const int buttonMargin = spinbox->frame ? 2 : 0;
- const int buttonWidth = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize) + 2 * buttonMargin;
+ const int buttonWidth = QS60StylePrivate::pixelMetric(PM_ButtonIconSize) + 2 * buttonMargin;
QSize buttonSize;
buttonSize.setHeight(qMax(8, spinbox->rect.height() - frameThickness));
//width should at least be equal to height
@@ -2575,7 +2615,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple
ret = cmb->rect;
const int width = cmb->rect.width();
const int height = cmb->rect.height();
- const int buttonIconSize = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize);
+ const int buttonIconSize = QS60StylePrivate::pixelMetric(PM_ButtonIconSize);
const int buttonMargin = cmb->frame ? 2 : 0;
// lets use spinbox frame here as well, as no combobox specific value available.
const int frameThickness = cmb->frame ? pixelMetric(PM_SpinBoxFrameWidth, cmb, widget) : 0;
@@ -2613,7 +2653,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple
case SC_GroupBoxLabel: {
//slightly indent text and boxes, so that dialog border does not mess with them.
const int horizontalSpacing =
- QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
+ QS60StylePrivate::pixelMetric(PM_LayoutHorizontalSpacing);
ret.adjust(2, horizontalSpacing - 3, 0, 0);
}
break;
@@ -2668,6 +2708,9 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
{
QRect ret;
switch (element) {
+ case SE_RadioButtonFocusRect:
+ ret = opt->rect;
+ break;
case SE_LineEditContents: {
// in S60 the input text box doesn't start from line Edit's TL, but
// a bit indented.
@@ -2686,9 +2729,9 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
const int tabOverlapNoBorder =
- QS60StylePrivate::pixelMetric(QStyle::PM_TabBarTabOverlap);
+ QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap);
const int tabOverlap =
- tabOverlapNoBorder-QS60StylePrivate::pixelMetric(QStyle::PM_DefaultFrameWidth);
+ tabOverlapNoBorder-QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
const QTabWidget *tab = qobject_cast<const QTabWidget *>(widget);
int gain = (tab) ? tabOverlap * tab->count() : 0;
switch (twf->shape) {
@@ -2737,8 +2780,8 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
multiSelection &&
(vopt->features & QStyleOptionViewItemV2::HasCheckIndicator)) {
const int verticalSpacing =
- QS60StylePrivate::pixelMetric(QStyle::PM_LayoutVerticalSpacing);
- //const int horizontalSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
+ QS60StylePrivate::pixelMetric(PM_LayoutVerticalSpacing);
+ //const int horizontalSpacing = QS60StylePrivate::pixelMetric(PM_LayoutHorizontalSpacing);
const int checkBoxRectWidth = subElementRect(SE_ItemViewItemCheckIndicator, opt, widget).width();
ret.adjust(-checkBoxRectWidth - verticalSpacing, 0, -checkBoxRectWidth - verticalSpacing, 0);
}
@@ -2784,9 +2827,9 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
singleSelection;
// Selection check mark rect.
- const int indicatorWidth = QS60StylePrivate::pixelMetric(QStyle::PM_IndicatorWidth);
- const int indicatorHeight = QS60StylePrivate::pixelMetric(QStyle::PM_IndicatorHeight);
- const int spacing = QS60StylePrivate::pixelMetric(QStyle::PM_CheckBoxLabelSpacing);
+ const int indicatorWidth = QS60StylePrivate::pixelMetric(PM_IndicatorWidth);
+ const int indicatorHeight = QS60StylePrivate::pixelMetric(PM_IndicatorHeight);
+ const int spacing = QS60StylePrivate::pixelMetric(PM_CheckBoxLabelSpacing);
const int itemHeight = opt->rect.height();
int heightOffset = 0;
@@ -2818,6 +2861,25 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
}
ret = visualRect(opt->direction, opt->rect, ret);
break;
+ case SE_RadioButtonIndicator: {
+ const int height = pixelMetric(PM_ExclusiveIndicatorHeight, opt, widget);
+ ret.setRect(opt->rect.x(), opt->rect.y() + ((opt->rect.height() - height) >> 1),
+ pixelMetric(PM_ExclusiveIndicatorWidth, opt, widget), height);
+ ret.translate(2, 0); //move indicator slightly to avoid highlight crossing over it
+ ret = visualRect(opt->direction, opt->rect, ret);
+ }
+ break;
+ case SE_CheckBoxIndicator: {
+ const int height = pixelMetric(PM_IndicatorHeight, opt, widget);
+ ret.setRect(opt->rect.x(), opt->rect.y() + ((opt->rect.height() - height) >> 1),
+ pixelMetric(PM_IndicatorWidth, opt, widget), height);
+ ret.translate(2, 0); //move indicator slightly to avoid highlight crossing over it
+ ret = visualRect(opt->direction, opt->rect, ret);
+ }
+ break;
+ case SE_CheckBoxFocusRect:
+ ret = opt->rect;
+ break;
default:
ret = QCommonStyle::subElementRect(element, opt, widget);
}
@@ -2835,6 +2897,12 @@ void QS60Style::polish(QWidget *widget)
if (!widget)
return;
+ //Currently we only support animations in QProgressBar.
+#ifndef QT_NO_PROGRESSBAR
+ if (qobject_cast<QProgressBar *>(widget))
+ widget->installEventFilter(this);
+#endif
+
if (false
#ifndef QT_NO_SCROLLBAR
|| qobject_cast<QScrollBar *>(widget)
@@ -2867,6 +2935,8 @@ void QS60Style::polish(QWidget *widget)
*/
void QS60Style::unpolish(QWidget *widget)
{
+ Q_D(QS60Style);
+
if (false
#ifndef QT_NO_SCROLLBAR
|| qobject_cast<QScrollBar *>(widget)
@@ -2893,6 +2963,14 @@ void QS60Style::unpolish(QWidget *widget)
if (widget)
widget->setPalette(QPalette());
+#if defined(Q_WS_S60) && !defined(QT_NO_PROGRESSBAR)
+ if (QProgressBar *bar = qobject_cast<QProgressBar *>(widget)) {
+ widget->removeEventFilter(this);
+ d->m_bars.removeAll(bar);
+ }
+#else
+ Q_UNUSED(d)
+#endif
QCommonStyle::unpolish(widget);
}
@@ -2924,10 +3002,23 @@ void QS60Style::unpolish(QApplication *application)
bool QS60Style::event(QEvent *e)
{
#ifdef QT_KEYPAD_NAVIGATION
- if (QS60StylePrivate::isTouchSupported())
- return false;
Q_D(QS60Style);
+ const QEvent::Type eventType = e->type();
+ if ((eventType == QEvent::FocusIn ||
+ eventType == QEvent::FocusOut ||
+ eventType == QEvent::EnterEditFocus ||
+ eventType == QEvent::LeaveEditFocus) &&
+ QS60StylePrivate::isTouchSupported())
+ return false;
+#endif
+
switch (e->type()) {
+ case QEvent::Timer: {
+ QTimerEvent *te = static_cast<QTimerEvent*>(e);
+ timerEvent(te);
+ }
+ break;
+#ifdef QT_KEYPAD_NAVIGATION
case QEvent::FocusIn:
if (QWidget *focusWidget = QApplication::focusWidget()) {
if (!d->m_focusFrame)
@@ -2946,12 +3037,10 @@ bool QS60Style::event(QEvent *e)
if (d->m_focusFrame)
d->m_focusFrame->update();
break;
+#endif
default:
break;
}
-#else
- Q_UNUSED(e)
-#endif
return false;
}
@@ -2961,7 +3050,7 @@ bool QS60Style::event(QEvent *e)
QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon,
const QStyleOption *option, const QWidget *widget) const
{
- const int iconDimension = QS60StylePrivate::pixelMetric(QStyle::PM_ToolBarIconSize);
+ const int iconDimension = QS60StylePrivate::pixelMetric(PM_ToolBarIconSize);
const QRect iconSize = (!option) ? QRect(0, 0, iconDimension, iconDimension) : option->rect;
QS60StyleEnums::SkinParts part;
QS60StylePrivate::SkinElementFlags adjustedFlags;
@@ -2971,67 +3060,67 @@ QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon,
QS60StylePrivate::SF_StateDisabled;
switch(standardIcon) {
- case QStyle::SP_MessageBoxWarning:
+ case SP_MessageBoxWarning:
part = QS60StyleEnums::SP_QgnNoteWarning;
break;
- case QStyle::SP_MessageBoxInformation:
+ case SP_MessageBoxInformation:
part = QS60StyleEnums::SP_QgnNoteInfo;
break;
- case QStyle::SP_MessageBoxCritical:
+ case SP_MessageBoxCritical:
part = QS60StyleEnums::SP_QgnNoteError;
break;
- case QStyle::SP_MessageBoxQuestion:
+ case SP_MessageBoxQuestion:
part = QS60StyleEnums::SP_QgnNoteQuery;
break;
- case QStyle::SP_ArrowRight:
+ case SP_ArrowRight:
part = QS60StyleEnums::SP_QgnIndiNaviArrowRight;
break;
- case QStyle::SP_ArrowLeft:
+ case SP_ArrowLeft:
part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft;
break;
- case QStyle::SP_ArrowUp:
+ case SP_ArrowUp:
part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft;
adjustedFlags |= QS60StylePrivate::SF_PointEast;
break;
- case QStyle::SP_ArrowDown:
+ case SP_ArrowDown:
part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft;
adjustedFlags |= QS60StylePrivate::SF_PointWest;
break;
- case QStyle::SP_ArrowBack:
+ case SP_ArrowBack:
if (QApplication::layoutDirection() == Qt::RightToLeft)
return QS60Style::standardIcon(SP_ArrowRight, option, widget);
return QS60Style::standardIcon(SP_ArrowLeft, option, widget);
- case QStyle::SP_ArrowForward:
+ case SP_ArrowForward:
if (QApplication::layoutDirection() == Qt::RightToLeft)
return QS60Style::standardIcon(SP_ArrowLeft, option, widget);
return QS60Style::standardIcon(SP_ArrowRight, option, widget);
- case QStyle::SP_ComputerIcon:
+ case SP_ComputerIcon:
part = QS60StyleEnums::SP_QgnPropPhoneMemcLarge;
break;
- case QStyle::SP_DirClosedIcon:
+ case SP_DirClosedIcon:
part = QS60StyleEnums::SP_QgnPropFolderSmall;
break;
- case QStyle::SP_DirOpenIcon:
+ case SP_DirOpenIcon:
part = QS60StyleEnums::SP_QgnPropFolderCurrent;
break;
- case QStyle::SP_DirIcon:
+ case SP_DirIcon:
part = QS60StyleEnums::SP_QgnPropFolderSmall;
break;
- case QStyle::SP_FileDialogNewFolder:
+ case SP_FileDialogNewFolder:
part = QS60StyleEnums::SP_QgnPropFolderSmallNew;
break;
- case QStyle::SP_FileIcon:
+ case SP_FileIcon:
part = QS60StyleEnums::SP_QgnPropFileSmall;
break;
- case QStyle::SP_TrashIcon:
+ case SP_TrashIcon:
part = QS60StyleEnums::SP_QgnNoteErased;
break;
- case QStyle::SP_ToolBarHorizontalExtensionButton:
+ case SP_ToolBarHorizontalExtensionButton:
part = QS60StyleEnums::SP_QgnIndiSubMenu;
if (QApplication::layoutDirection() == Qt::RightToLeft)
adjustedFlags |= QS60StylePrivate::SF_PointSouth;
break;
- case QStyle::SP_ToolBarVerticalExtensionButton:
+ case SP_ToolBarVerticalExtensionButton:
adjustedFlags |= QS60StylePrivate::SF_PointEast;
part = QS60StyleEnums::SP_QgnIndiSubMenu;
break;
@@ -3045,6 +3134,68 @@ QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon,
QCommonStyle::standardIconImplementation(standardIcon, option, widget) : QIcon(cachedPixMap);
}
+/*!
+ \internal
+ Animate indeterminate progress bars only when visible
+*/
+bool QS60Style::eventFilter(QObject *object, QEvent *event)
+{
+#ifdef Q_WS_S60
+#ifndef QT_NO_PROGRESSBAR
+ Q_D(QS60Style);
+ switch(event->type()) {
+ case QEvent::StyleChange:
+ case QEvent::Show:
+ if (QProgressBar *bar = qobject_cast<QProgressBar *>(object)) {
+ if (!d->m_bars.contains(bar))
+ d->m_bars << bar;
+ if (d->m_bars.size() == 1) //only start with first animated progressbar
+ d->startAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim);
+ }
+ break;
+ case QEvent::Destroy:
+ case QEvent::Hide:
+ d->stopAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim);
+ d->m_bars.removeAll(reinterpret_cast<QProgressBar *>(object));
+ break;
+ default:
+ break;
+ }
+#endif // QT_NO_PROGRESSBAR
+#endif // Q_WS_S60
+ return QStyle::eventFilter(object, event);
+}
+
+void QS60Style::timerEvent(QTimerEvent *event)
+{
+#ifdef Q_WS_S60
+#ifndef QT_NO_PROGRESSBAR
+ Q_D(QS60Style);
+
+ QS60StyleAnimation *progressBarAnimation =
+ QS60StylePrivate::animationDefinition(QS60StyleEnums::SP_QgnGrafBarWaitAnim);
+
+ if (event->timerId() == progressBarAnimation->timerId()) {
+
+ Q_ASSERT(progressBarAnimation->interval() > 0);
+
+ if (progressBarAnimation->currentFrame() == progressBarAnimation->frameCount() )
+ if (progressBarAnimation->playMode() == QS60StyleEnums::AM_Looping)
+ progressBarAnimation->setCurrentFrame(0);
+ else
+ d->stopAnimation(progressBarAnimation->animationId());
+
+ foreach (QProgressBar *bar, d->m_bars) {
+ if ((bar->minimum() == 0 && bar->maximum() == 0))
+ bar->update();
+ }
+ progressBarAnimation->setCurrentFrame(progressBarAnimation->currentFrame() + 1);
+ }
+#endif // QT_NO_PROGRESSBAR
+#endif // Q_WS_S60
+ event->ignore();
+}
+
extern QPoint qt_s60_fill_background_offset(const QWidget *targetWidget);
bool qt_s60_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush)
@@ -3056,11 +3207,13 @@ bool qt_s60_fill_background(QPainter *painter, const QRegion &rgn, const QBrush
const QPaintDevice *target = painter->device();
if (target->devType() == QInternal::Widget) {
const QWidget *widget = static_cast<const QWidget *>(target);
- const QVector<QRect> &rects = rgn.rects();
- for (int i = 0; i < rects.size(); ++i) {
- const QRect rect(rects.at(i));
- painter->drawPixmap(rect.topLeft(), backgroundTexture,
- rect.translated(qt_s60_fill_background_offset(widget)));
+ if (!widget->testAttribute(Qt::WA_TranslucentBackground)) {
+ const QVector<QRect> &rects = rgn.rects();
+ for (int i = 0; i < rects.size(); ++i) {
+ const QRect rect(rects.at(i));
+ painter->drawPixmap(rect.topLeft(), backgroundTexture,
+ rect.translated(qt_s60_fill_background_offset(widget)));
+ }
}
}
return true;
diff --git a/src/gui/styles/qs60style.h b/src/gui/styles/qs60style.h
index adcb313..82cc21c 100644
--- a/src/gui/styles/qs60style.h
+++ b/src/gui/styles/qs60style.h
@@ -94,6 +94,9 @@ protected Q_SLOTS:
QIcon standardIconImplementation(
StandardPixmap standardIcon, const QStyleOption * option = 0, const QWidget * widget = 0 ) const;
+protected:
+ void timerEvent(QTimerEvent *event);
+ bool eventFilter(QObject *o, QEvent *e);
private:
Q_DISABLE_COPY(QS60Style)
friend class QStyleFactory;
diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h
index 1417552..2cd238f 100644
--- a/src/gui/styles/qs60style_p.h
+++ b/src/gui/styles/qs60style_p.h
@@ -93,6 +93,29 @@ class QS60StyleEnums
#endif // !Q_WS_S60
public:
+
+ // S60 definitions within theme
+ enum ThemeDefinitions {
+ TD_AnimationData,
+ };
+
+ //Defines which values are contained within animation data (retrieved using TD_AnimationData).
+ //Additionally defines the order in which the items are given out in QList<QVariant>.
+ enum AnimationData {
+ AD_Interval = 0,
+ AD_NumberOfFrames,
+ AD_AnimationPlayMode, //currently not used as themes seem to contain invalid data
+ };
+
+ // Animation modes
+ enum AnimationMode {
+ AM_PlayOnce = 0, //animation is played exactly once
+ AM_Looping, //animation is repeated until stopped
+ AM_Bounce //animation is played repeatedly until stopped,
+ //but frames are played in reverse order every second time
+ //(no support yet)
+ };
+
// S60 look-and-feel font categories
enum FontCategories {
FC_Undefined,
@@ -104,7 +127,7 @@ public:
};
enum SkinParts {
- SP_QgnGrafBarWait,
+ SP_QgnGrafBarWaitAnim,
SP_QgnGrafBarFrameCenter,
SP_QgnGrafBarFrameSideL,
SP_QgnGrafBarFrameSideR,
@@ -287,7 +310,70 @@ public:
};
};
+#ifdef Q_WS_S60
+class CAknBitmapAnimation;
+NONSHARABLE_CLASS (AnimationData) : public QObject
+{
+public:
+ AnimationData(const QS60StyleEnums::SkinParts part, int frames, int interval);
+
+ const QS60StyleEnums::SkinParts m_id;
+ int m_frames;
+ int m_interval;
+ QS60StyleEnums::AnimationMode m_mode;
+};
+
+
+NONSHARABLE_CLASS (AnimationDataV2) : public AnimationData
+{
+public:
+ AnimationDataV2(const AnimationData &data);
+ ~AnimationDataV2();
+
+ CAknBitmapAnimation *m_animation;
+ int m_currentFrame;
+ bool m_resourceBased;
+ int m_timerId;
+};
+
+
+class QS60StyleAnimation : public QObject
+{
+public:
+ QS60StyleAnimation(const QS60StyleEnums::SkinParts part, int frames, int interval);
+ ~QS60StyleAnimation();
+
+public:
+ QS60StyleEnums::SkinParts animationId() const {return m_currentData->m_id;}
+ int frameCount() const { return m_currentData->m_frames;}
+ int interval() const {return m_currentData->m_interval;}
+ QS60StyleEnums::AnimationMode playMode() const {return m_currentData->m_mode;}
+ CAknBitmapAnimation* animationObject() const {return m_currentData->m_animation;}
+ bool isResourceBased() const {return m_currentData->m_resourceBased;}
+ int timerId() const {return m_currentData->m_timerId;}
+ int currentFrame() const {return m_currentData->m_currentFrame;}
+
+ void setFrameCount(const int &frameCount) {m_currentData->m_frames = frameCount;}
+ void setInterval(const int &interval) {m_currentData->m_interval = interval;}
+ void setAnimationObject(CAknBitmapAnimation* animation);
+ void setResourceBased(bool resourceBased) {m_currentData->m_resourceBased = resourceBased;}
+ void setTimerId(const int &timerId) {m_currentData->m_timerId = timerId;}
+ void setCurrentFrame(const int &currentFrame) {m_currentData->m_currentFrame = currentFrame;}
+
+ void resetToDefaults();
+
+private: //data members
+ //TODO: consider changing these to non-pointers as the classes are rather small anyway
+ AnimationData *m_defaultData;
+ AnimationDataV2 *m_currentData;
+};
+
+#endif //Q_WS_S60
+
+
class QFocusFrame;
+class QProgressBar;
+class QS60StyleAnimation;
// Private class
#ifdef Q_OS_SYMBIAN
@@ -371,6 +457,7 @@ public:
SF_StateEnabled = 0x0010, // Enabled = the default
SF_StateDisabled = 0x0020,
SF_ColorSkinned = 0x0040, // pixmap is colored with foreground pen color
+ SF_Animation = 0x0080,
};
enum CacheClearReason {
@@ -412,6 +499,7 @@ public:
static bool isTouchSupported();
static bool isToolBarBackground();
static bool hasSliderGrooveGraphic();
+ static bool isSingleClickUi();
// calculates average color based on button skin graphics (minus borders).
QColor colorFromFrameGraphics(SkinFrameElements frame) const;
@@ -455,6 +543,16 @@ public:
//so that theme graphic background can be drawn.
static bool canDrawThemeBackground(const QBrush &backgroundBrush);
+ static int currentAnimationFrame(QS60StyleEnums::SkinParts part);
+#ifdef Q_WS_S60
+
+ //No support for animations on emulated style
+ void startAnimation(QS60StyleEnums::SkinParts animation);
+ void stopAnimation(QS60StyleEnums::SkinParts animation);
+ static QS60StyleAnimation* animationDefinition(QS60StyleEnums::SkinParts part);
+
+#endif
+
private:
static void drawPart(QS60StyleEnums::SkinParts part, QPainter *painter,
const QRect &rect, SkinElementFlags flags = KDefaultSkinElementFlags);
@@ -497,6 +595,12 @@ private:
QPalette m_originalPalette;
QPointer<QFocusFrame> m_focusFrame;
+
+#ifdef Q_WS_S60
+ //list of progress bars having animation running
+ QList<QProgressBar *> m_bars;
+#endif
+
};
QT_END_NAMESPACE
diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp
index be61073..a3bb169 100644
--- a/src/gui/styles/qs60style_s60.cpp
+++ b/src/gui/styles/qs60style_s60.cpp
@@ -63,6 +63,7 @@
#include <aknutils.h>
#include <aknnavi.h>
#include <gulicon.h>
+#include <AknBitmapAnimation.h>
#if !defined(QT_NO_STYLE_S60) || defined(QT_PLUGIN)
@@ -72,6 +73,7 @@ enum TDrawType {
EDrawIcon,
EDrawGulIcon,
EDrawBackground,
+ EDrawAnimation,
ENoDraw
};
@@ -97,6 +99,47 @@ typedef struct {
int newMinorSkinId;
} partMapEntry;
+AnimationData::AnimationData(const QS60StyleEnums::SkinParts part, int frames, int interval) : m_id(part),
+ m_frames(frames), m_interval(interval), m_mode(QS60StyleEnums::AM_Looping)
+{
+}
+
+AnimationDataV2::AnimationDataV2(const AnimationData &data) : AnimationData(data.m_id, data.m_frames, data.m_interval),
+ m_resourceBased(false), m_animation(0), m_timerId(0)
+{
+}
+AnimationDataV2::~AnimationDataV2()
+{
+ delete m_animation;
+}
+
+QS60StyleAnimation::QS60StyleAnimation(const QS60StyleEnums::SkinParts part, int frames, int interval)
+{
+ QT_TRAP_THROWING(m_defaultData = new (ELeave) AnimationData(part, frames, interval));
+ QT_TRAP_THROWING(m_currentData = new (ELeave) AnimationDataV2(*m_defaultData));
+}
+
+QS60StyleAnimation::~QS60StyleAnimation()
+{
+ delete m_currentData;
+ delete m_defaultData;
+}
+
+void QS60StyleAnimation::setAnimationObject(CAknBitmapAnimation* animation)
+{
+ Q_ASSERT(animation);
+ if (m_currentData->m_animation)
+ delete m_currentData->m_animation;
+ m_currentData->m_animation = animation;
+}
+
+void QS60StyleAnimation::resetToDefaults()
+{
+ delete m_currentData;
+ m_currentData = 0;
+ QT_TRAP_THROWING(m_currentData = new (ELeave) AnimationDataV2(*m_defaultData));
+}
+
class QS60StyleModeSpecifics
{
public:
@@ -113,6 +156,8 @@ public:
static QSize naviPaneSize();
static TAknsItemID partSpecificThemeId(int part);
+ static QVariant themeDefinition(QS60StyleEnums::ThemeDefinitions definition, QS60StyleEnums::SkinParts part);
+
private:
static QPixmap createSkinnedGraphicsLX(QS60StyleEnums::SkinParts part,
const QSize &size, QS60StylePrivate::SkinElementFlags flags);
@@ -128,7 +173,7 @@ private:
};
const partMapEntry QS60StyleModeSpecifics::m_partMap[] = {
- /* SP_QgnGrafBarWait */ {KAknsIIDQgnGrafBarWaitAnim, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafBarWaitAnim */ {KAknsIIDQgnGrafBarWaitAnim, EDrawAnimation, ES60_All, -1,-1},
/* SP_QgnGrafBarFrameCenter */ {KAknsIIDQgnGrafBarFrameCenter, EDrawIcon, ES60_All, -1,-1},
/* SP_QgnGrafBarFrameSideL */ {KAknsIIDQgnGrafBarFrameSideL, EDrawIcon, ES60_All, -1,-1},
/* SP_QgnGrafBarFrameSideR */ {KAknsIIDQgnGrafBarFrameSideR, EDrawIcon, ES60_All, -1,-1},
@@ -371,7 +416,7 @@ QPixmap QS60StyleModeSpecifics::colorSkinnedGraphics(
void QS60StyleModeSpecifics::fallbackInfo(const QS60StyleEnums::SkinParts &stylePart, TInt &fallbackIndex)
{
switch(stylePart) {
- case QS60StyleEnums::SP_QgnGrafBarWait:
+ case QS60StyleEnums::SP_QgnGrafBarWaitAnim:
fallbackIndex = EMbmAvkonQgn_graf_bar_wait_1;
break;
case QS60StyleEnums::SP_QgnGrafBarFrameCenter:
@@ -604,6 +649,11 @@ bool QS60StylePrivate::hasSliderGrooveGraphic()
return QSysInfo::s60Version() != QSysInfo::SV_S60_3_1;
}
+bool QS60StylePrivate::isSingleClickUi()
+{
+ return (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0);
+}
+
QPoint qt_s60_fill_background_offset(const QWidget *targetWidget)
{
CCoeControl *control = targetWidget->effectiveWinId();
@@ -709,6 +759,69 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(
// QS60WindowSurface::lockBitmapHeap();
break;
}
+ case EDrawAnimation: {
+ CFbsBitmap* animationFrame;
+ CFbsBitmap* frameMask;
+ CAknBitmapAnimation* aknAnimation = 0;
+ TBool constructedFromTheme = ETrue;
+
+ QS60StyleAnimation* animation = QS60StylePrivate::animationDefinition(part); //ownership is not passed
+ if (animation) {
+ if (!animation->animationObject() && !animation->isResourceBased()) {// no pre-made item exists, create new animation
+ CAknBitmapAnimation* newAnimation = CAknBitmapAnimation::NewL();
+ CleanupStack::PushL(newAnimation);
+ if (newAnimation)
+ constructedFromTheme = newAnimation->ConstructFromSkinL(skinId);
+ if (constructedFromTheme && newAnimation->BitmapAnimData()->FrameArray().Count() > 0) {
+ animation->setResourceBased(false);
+ animation->setAnimationObject(newAnimation); //animation takes ownership
+ }
+ CleanupStack::Pop(newAnimation);
+ }
+ //fill-in stored information
+ aknAnimation = animation->animationObject();
+ constructedFromTheme = !animation->isResourceBased();
+ }
+
+ const int currentFrame = QS60StylePrivate::currentAnimationFrame(part);
+ if (constructedFromTheme && aknAnimation && aknAnimation->BitmapAnimData()->FrameArray().Count() > 0) {
+ //Animation was created succesfully and contains frames, just fetch current frame
+ if(currentFrame >= aknAnimation->BitmapAnimData()->FrameArray().Count())
+ User::Leave(KErrOverflow);
+ const CBitmapFrameData* frameData = aknAnimation->BitmapAnimData()->FrameArray().At(currentFrame);
+ if (frameData) {
+ animationFrame = frameData->Bitmap();
+ frameMask = frameData->Mask();
+ }
+ } else {
+ //Theme does not contain animation theming, create frames from resource file
+ TInt fallbackGraphicID = -1;
+ fallbackInfo(part, fallbackGraphicID);
+ fallbackGraphicID = fallbackGraphicID + (currentFrame * 2); //skip masks
+ TInt fallbackGraphicsMaskID =
+ (fallbackGraphicID == KErrNotFound) ? KErrNotFound : fallbackGraphicID + 1; //masks are auto-generated as next in mif files
+ if (fallbackGraphicsMaskID != KErrNotFound)
+ fallbackGraphicsMaskID = fallbackGraphicsMaskID + (currentFrame * 2); //skip actual graphics
+
+ //Then draw animation frame
+ AknsUtils::CreateIconL(
+ skinInstance,
+ KAknsIIDDefault, //animation is not themed, lets force fallback graphics
+ animationFrame,
+ frameMask,
+ AknIconUtils::AvkonIconFileName(),
+ fallbackGraphicID ,
+ fallbackGraphicsMaskID);
+ }
+ result = fromFbsBitmap(animationFrame, frameMask, flags, targetSize);
+ if (!constructedFromTheme) {
+ delete animationFrame;
+ animationFrame = 0;
+ delete frameMask;
+ frameMask = 0;
+ }
+ break;
+ }
}
if (!result)
result = QPixmap();
@@ -731,7 +844,6 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(QS60StylePrivate::SkinFr
MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
QPixmap result;
-// QS60WindowSurface::unlockBitmapHeap();
static const TDisplayMode displayMode = S60->supportsPremultipliedAlpha ? Q_SYMBIAN_ECOLOR16MAP : EColor16MA;
static const TInt drawParam = S60->supportsPremultipliedAlpha ? KAknsDrawParamDefault : KAknsDrawParamNoClearUnderImage|KAknsDrawParamRGBOnly;
@@ -985,8 +1097,13 @@ void QS60StylePrivate::setActiveLayout()
m_pmPointer = data[activeLayoutIndex];
}
+Q_GLOBAL_STATIC(QList<QS60StyleAnimation *>, m_animations)
+
QS60StylePrivate::QS60StylePrivate()
{
+ //Animation defaults need to be created when style is instantiated
+ QS60StyleAnimation* progressBarAnimation = new QS60StyleAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim, 7, 100);
+ m_animations()->append(progressBarAnimation);
// No need to set active layout, if dynamic metrics API is available
setActiveLayout();
}
@@ -1187,6 +1304,11 @@ void QS60StylePrivate::handleSkinChange()
setThemePalette(topLevelWidget);
topLevelWidget->ensurePolished();
}
+#ifndef QT_NO_PROGRESSBAR
+ //re-start animation timer
+ stopAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); //todo: once we have more animations, we could say "stop all running ones"
+ startAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); //and "re-start all previously running ones"
+#endif
}
QSize QS60StylePrivate::naviPaneSize()
@@ -1206,6 +1328,121 @@ QSize QS60StyleModeSpecifics::naviPaneSize()
return QSize(0,0);
}
+int QS60StylePrivate::currentAnimationFrame(QS60StyleEnums::SkinParts part)
+{
+ QS60StyleAnimation *animation = animationDefinition(part);
+ // todo: looping could be done in QS60Style::timerEvent
+ if (animation->frameCount() == animation->currentFrame())
+ animation->setCurrentFrame(0);
+ return animation->currentFrame();
+}
+
+QS60StyleAnimation* QS60StylePrivate::animationDefinition(QS60StyleEnums::SkinParts part)
+{
+ int i = 0;
+ const int animationsCount = m_animations()->isEmpty() ? 0 : m_animations()->count();
+ for(; i < animationsCount; i++) {
+ if (part == m_animations()->at(i)->animationId())
+ break;
+ }
+ return m_animations()->at(i);
+}
+
+void QS60StylePrivate::startAnimation(QS60StyleEnums::SkinParts animationPart)
+{
+ Q_Q(QS60Style);
+
+ //Query animation data from theme and store values to local struct.
+ QVariant themeAnimationDataVariant = QS60StyleModeSpecifics::themeDefinition(
+ QS60StyleEnums::TD_AnimationData, animationPart);
+ QList<QVariant> themeAnimationData = themeAnimationDataVariant.toList();
+
+ QS60StyleAnimation *animation = QS60StylePrivate::animationDefinition(animationPart);
+ if (animation) {
+ if (themeAnimationData.at(QS60StyleEnums::AD_Interval).toInt() != 0)
+ animation->setInterval(themeAnimationData.at(QS60StyleEnums::AD_Interval).toInt());
+
+ if (themeAnimationData.at(QS60StyleEnums::AD_NumberOfFrames).toInt() != 0)
+ animation->setFrameCount(themeAnimationData.at(QS60StyleEnums::AD_NumberOfFrames).toInt());
+
+ //todo: playmode is ignored for now, since it seems to return invalid data on some themes
+ //lets use the table values for play mode
+
+ animation->setCurrentFrame(0); //always initialize
+ const int timerId = q->startTimer(animation->interval());
+ animation->setTimerId(timerId);
+ }
+}
+
+void QS60StylePrivate::stopAnimation(QS60StyleEnums::SkinParts animationPart)
+{
+ Q_Q(QS60Style);
+
+ QS60StyleAnimation *animation = QS60StylePrivate::animationDefinition(animationPart);
+ if (animation) {
+ animation->setCurrentFrame(0);
+ if (animation->timerId() != 0) {
+ q->killTimer(animation->timerId());
+ animation->setTimerId(0);
+ }
+ animation->resetToDefaults();
+ }
+}
+
+QVariant QS60StyleModeSpecifics::themeDefinition(
+ QS60StyleEnums::ThemeDefinitions definition, QS60StyleEnums::SkinParts part)
+{
+ MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
+
+ Q_ASSERT(skinInstance);
+
+ switch(definition) {
+ //Animation definitions
+ case QS60StyleEnums::TD_AnimationData:
+ {
+ CAknsBmpAnimItemData *animationData;
+ TAknsItemID animationSkinId = partSpecificThemeId(part);
+ QList<QVariant> list;
+
+ TRAPD( error, QT_TRYCATCH_LEAVING(
+ animationData = static_cast<CAknsBmpAnimItemData*>(skinInstance->CreateUncachedItemDataL(
+ animationSkinId, EAknsITBmpAnim))));
+ if (error)
+ return list;
+
+ if (animationData) {
+ list.append((int)animationData->FrameInterval());
+ list.append((int)animationData->NumberOfImages());
+
+ QS60StyleEnums::AnimationMode playMode;
+ switch(animationData->PlayMode()) {
+ case CBitmapAnimClientData::EPlay:
+ playMode = QS60StyleEnums::AM_PlayOnce;
+ break;
+ case CBitmapAnimClientData::ECycle:
+ playMode = QS60StyleEnums::AM_Looping;
+ break;
+ case CBitmapAnimClientData::EBounce:
+ playMode = QS60StyleEnums::AM_Bounce;
+ break;
+ default:
+ break;
+ }
+ list.append(QVariant((int)playMode));
+ delete animationData;
+ } else {
+ list.append(0);
+ list.append(0);
+ }
+ return list;
+ }
+ break;
+ default:
+ break;
+ }
+ return QVariant();
+}
+
#endif // Q_WS_S60
QT_END_NAMESPACE
diff --git a/src/gui/styles/qs60style_simulated.cpp b/src/gui/styles/qs60style_simulated.cpp
index bd43eb7..f87cf28 100644
--- a/src/gui/styles/qs60style_simulated.cpp
+++ b/src/gui/styles/qs60style_simulated.cpp
@@ -342,6 +342,11 @@ bool QS60StylePrivate::hasSliderGrooveGraphic()
return false;
}
+bool QS60StylePrivate::isSingleClickUi()
+{
+ return false;
+}
+
QFont QS60StylePrivate::s60Font_specific(
QS60StyleEnums::FontCategories fontCategory,
int pointSize, bool resolveFontSize)
@@ -364,6 +369,11 @@ QFont QS60StylePrivate::s60Font_specific(
return result;
}
+int QS60StylePrivate::currentAnimationFrame(QS60StyleEnums::SkinParts part)
+{
+ return 0;
+}
+
/*!
Constructs a QS60Style object.
*/
diff --git a/src/gui/styles/qstyle_s60.qrc b/src/gui/styles/qstyle_s60.qrc
new file mode 100644
index 0000000..dbee38b
--- /dev/null
+++ b/src/gui/styles/qstyle_s60.qrc
@@ -0,0 +1,137 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/trolltech/styles/commonstyle">
+<!-- <file>images/filelink-16.png</file> -->
+<file>images/filelink-32.png</file>
+<!-- <file>images/filelink-128.png</file> -->
+<!-- <file>images/file-16.png</file> -->
+<file>images/file-32.png</file>
+<!-- <file>images/file-128.png</file> -->
+<!-- <file>images/newdirectory-16.png</file> -->
+<file>images/newdirectory-32.png</file>
+<!-- <file>images/newdirectory-128.png</file> -->
+<!-- <file>images/parentdir-16.png</file> -->
+<file>images/parentdir-32.png</file>
+<!-- <file>images/parentdir-128.png</file> -->
+<!-- <file>images/dvd-16.png</file> -->
+<!-- <file>images/dvd-32.png</file> -->
+<!-- <file>images/dvd-128.png</file> -->
+<!-- <file>images/cdr-16.png</file> -->
+<!-- <file>images/cdr-32.png</file> -->
+<!-- <file>images/cdr-128.png</file> -->
+<!-- <file>images/floppy-16.png</file> -->
+<!-- <file>images/floppy-32.png</file> -->
+<!-- <file>images/floppy-128.png</file> -->
+<!-- <file>images/harddrive-16.png</file> -->
+<file>images/harddrive-32.png</file>
+<!-- <file>images/harddrive-128.png</file> -->
+<!-- <file>images/trash-16.png</file> -->
+<!-- <file>images/trash-32.png</file> -->
+<!-- <file>images/trash-128.png</file> -->
+<!-- <file>images/networkdrive-16.png</file> -->
+<!-- <file>images/networkdrive-32.png</file> -->
+<!-- <file>images/networkdrive-128.png</file> -->
+<!-- <file>images/computer-16.png</file> -->
+<!-- <file>images/computer-32.png</file> -->
+<!-- <file>images/desktop-16.png</file> -->
+<file>images/desktop-32.png</file>
+<!-- <file>images/dirclosed-16.png</file> -->
+<file>images/dirclosed-32.png</file>
+<!-- <file>images/dirclosed-128.png</file> -->
+<!-- <file>images/dirlink-16.png</file> -->
+<file>images/dirlink-32.png</file>
+<!-- <file>images/dirlink-128.png</file> -->
+<!-- <file>images/diropen-16.png</file> -->
+<file>images/diropen-32.png</file>
+<!-- <file>images/diropen-128.png</file> -->
+<!-- <file>images/left-16.png</file> -->
+<file>images/left-32.png</file>
+<!-- <file>images/left-128.png</file> -->
+<!-- <file>images/right-16.png</file> -->
+<file>images/right-32.png</file>
+<!-- <file>images/right-128.png</file> -->
+<!-- <file>images/up-16.png</file> -->
+<file>images/up-32.png</file>
+<!-- <file>images/up-128.png</file> -->
+<!-- <file>images/down-16.png</file> -->
+<file>images/down-32.png</file>
+<!-- <file>images/down-128.png</file> -->
+<!-- <file>images/filecontents-16.png</file> -->
+<file>images/filecontents-32.png</file>
+<!-- <file>images/filecontents-128.png</file> -->
+<!-- <file>images/fileinfo-16.png</file> -->
+<file>images/fileinfo-32.png</file>
+<!-- <file>images/fileinfo-128.png</file> -->
+<!-- <file>images/viewdetailed-16.png</file> -->
+<file>images/viewdetailed-32.png</file>
+<!-- <file>images/viewdetailed-128.png</file> -->
+<!-- <file>images/viewlist-16.png</file> -->
+<file>images/viewlist-32.png</file>
+<!-- <file>images/viewlist-128.png</file> -->
+<file>images/fontbitmap-16.png</file>
+<file>images/fonttruetype-16.png</file>
+<!-- <file>images/standardbutton-apply-128.png</file> -->
+<!-- <file>images/standardbutton-apply-16.png</file> -->
+<file>images/standardbutton-apply-32.png</file>
+<!-- <file>images/standardbutton-cancel-128.png</file> -->
+<!-- <file>images/standardbutton-cancel-16.png</file> -->
+<file>images/standardbutton-cancel-32.png</file>
+<!-- <file>images/standardbutton-clear-128.png</file> -->
+<!-- <file>images/standardbutton-clear-16.png</file> -->
+<file>images/standardbutton-clear-32.png</file>
+<!-- <file>images/standardbutton-close-128.png</file> -->
+<!-- <file>images/standardbutton-close-16.png</file> -->
+<file>images/standardbutton-close-32.png</file>
+<!-- <file>images/standardbutton-delete-128.png</file> -->
+<!-- <file>images/standardbutton-delete-16.png</file> -->
+<file>images/standardbutton-delete-32.png</file>
+<!-- <file>images/standardbutton-help-128.png</file> -->
+<!-- <file>images/standardbutton-help-16.png</file> -->
+<file>images/standardbutton-help-32.png</file>
+<!-- <file>images/standardbutton-no-128.png</file> -->
+<!-- <file>images/standardbutton-no-16.png</file> -->
+<file>images/standardbutton-no-32.png</file>
+<!-- <file>images/standardbutton-ok-128.png</file> -->
+<!-- <file>images/standardbutton-ok-16.png</file> -->
+<file>images/standardbutton-ok-32.png</file>
+<!-- <file>images/standardbutton-open-128.png</file> -->
+<!-- <file>images/standardbutton-open-16.png</file> -->
+<file>images/standardbutton-open-32.png</file>
+<!-- <file>images/standardbutton-save-128.png</file> -->
+<!-- <file>images/standardbutton-save-16.png</file> -->
+<file>images/standardbutton-save-32.png</file>
+<!-- <file>images/standardbutton-yes-128.png</file> -->
+<!-- <file>images/standardbutton-yes-16.png</file> -->
+<file>images/standardbutton-yes-32.png</file>
+<file>images/standardbutton-closetab-16.png</file>
+<file>images/standardbutton-closetab-down-16.png</file>
+<file>images/standardbutton-closetab-hover-16.png</file>
+<!-- <file>images/refresh-24.png</file> -->
+<file>images/refresh-32.png</file>
+<!-- <file>images/stop-24.png</file> -->
+<file>images/stop-32.png</file>
+<!-- <file>images/media-stop-16.png</file> -->
+<file>images/media-stop-32.png</file>
+<!-- <file>images/media-play-16.png</file> -->
+<file>images/media-play-32.png</file>
+<!-- <file>images/media-pause-16.png</file> -->
+<file>images/media-pause-32.png</file>
+<!-- <file>images/media-seek-forward-16.png</file> -->
+<file>images/media-seek-forward-32.png</file>
+<!-- <file>images/media-seek-backward-16.png</file> -->
+<file>images/media-seek-backward-32.png</file>
+<!-- <file>images/media-skip-forward-16.png</file> -->
+<file>images/media-skip-forward-32.png</file>
+<!-- <file>images/media-skip-backward-16.png</file> -->
+<file>images/media-skip-backward-32.png</file>
+<file>images/media-volume-16.png</file>
+<file>images/media-volume-muted-16.png</file>
+</qresource>
+<!--
+<qresource prefix="/trolltech/styles/macstyle">
+<file>images/closedock-16.png</file>
+<file>images/closedock-down-16.png</file>
+<file>images/dockdock-16.png</file>
+<file>images/dockdock-down-16.png</file>
+</qresource>
+-->
+</RCC>
diff --git a/src/gui/styles/styles.pri b/src/gui/styles/styles.pri
index 7e5c55a..676f59e 100644
--- a/src/gui/styles/styles.pri
+++ b/src/gui/styles/styles.pri
@@ -23,10 +23,12 @@ SOURCES += \
styles/qstylesheetstyle.cpp \
styles/qstylesheetstyle_default.cpp
-!wince* {
- RESOURCES += styles/qstyle.qrc
+wince* {
+ RESOURCES += styles/qstyle_wince.qrc
+} else:symbian {
+ RESOURCES += styles/qstyle_s60.qrc
} else {
- RESOURCES += styles/qstyle_wince.qrc
+ RESOURCES += styles/qstyle.qrc
}
contains( styles, all ) {
@@ -168,7 +170,7 @@ contains( styles, s60 ):contains(QT_CONFIG, s60) {
SOURCES += styles/qs60style.cpp
symbian {
SOURCES += styles/qs60style_s60.cpp
- LIBS += -laknicon -laknskins -laknskinsrv -lfontutils -legul
+ LIBS += -laknicon -laknskins -laknskinsrv -lfontutils -legul -lbmpanim
} else {
SOURCES += styles/qs60style_simulated.cpp
RESOURCES += styles/qstyle_s60_simulated.qrc
diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp
index 414c2ed..b0a64ea 100644
--- a/src/gui/widgets/qlinecontrol.cpp
+++ b/src/gui/widgets/qlinecontrol.cpp
@@ -524,8 +524,11 @@ void QLineControl::draw(QPainter *painter, const QPoint &offset, const QRect &cl
m_textLayout.draw(painter, offset, selections, clip);
if (flags & DrawCursor){
+ int cursor = m_cursor;
+ if (m_preeditCursor != -1)
+ cursor += m_preeditCursor;
if(!m_blinkPeriod || m_blinkStatus)
- m_textLayout.drawCursor(painter, offset, m_cursor, m_cursorWidth);
+ m_textLayout.drawCursor(painter, offset, cursor, m_cursorWidth);
}
}
diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h
index 301ff72..d6f2705 100644
--- a/src/gui/widgets/qlinecontrol_p.h
+++ b/src/gui/widgets/qlinecontrol_p.h
@@ -549,7 +549,10 @@ inline qreal QLineControl::cursorToX(int cursor) const
inline qreal QLineControl::cursorToX() const
{
- return cursorToX(m_cursor);
+ int cursor = m_cursor;
+ if (m_preeditCursor != -1)
+ cursor += m_preeditCursor;
+ return cursorToX(cursor);
}
inline bool QLineControl::isReadOnly() const