summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlan Alpert <alan.alpert@nokia.com>2009-09-15 23:45:32 (GMT)
committerAlan Alpert <alan.alpert@nokia.com>2009-09-15 23:45:32 (GMT)
commit4e2163a5c4eec9eeacf8c7260dbf8fb7c74d2b44 (patch)
tree31d86c91c526563302887e756ce5f7876f274223 /src
parentadfb5c6160b37a917f20b301366567c208ae52a0 (diff)
parentdcd4b15595a63864ee59a19d80f1ba33b4821aa3 (diff)
downloadQt-4e2163a5c4eec9eeacf8c7260dbf8fb7c74d2b44.zip
Qt-4e2163a5c4eec9eeacf8c7260dbf8fb7c74d2b44.tar.gz
Qt-4e2163a5c4eec9eeacf8c7260dbf8fb7c74d2b44.tar.bz2
Merge branch '4.6' of git@scm.dev.nokia.troll.no:qt/qt into 4.6
Diffstat (limited to 'src')
-rw-r--r--src/corelib/global/qglobal.h5
-rw-r--r--src/corelib/global/qnamespace.h8
-rw-r--r--src/corelib/global/qnamespace.qdoc26
-rw-r--r--src/corelib/tools/qhash.h1
-rw-r--r--src/corelib/tools/qmap.h1
-rw-r--r--src/corelib/tools/qmargins.cpp2
-rw-r--r--src/gui/effects/qgraphicseffect.cpp14
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout.cpp45
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp207
-rw-r--r--src/gui/graphicsview/qgraphicsitem.h4
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h14
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp18
-rw-r--r--src/gui/graphicsview/qgraphicsview.cpp4
-rw-r--r--src/gui/image/qimagereader.cpp55
-rw-r--r--src/gui/image/qimagereader.h3
-rw-r--r--src/gui/image/qpixmap_s60.cpp10
-rw-r--r--src/gui/kernel/qapplication.cpp90
-rw-r--r--src/gui/kernel/qapplication.h4
-rw-r--r--src/gui/kernel/qapplication_p.h16
-rw-r--r--src/gui/kernel/qapplication_s60.cpp307
-rw-r--r--src/gui/kernel/qapplication_x11.cpp2
-rw-r--r--src/gui/kernel/qcursor.h18
-rw-r--r--src/gui/kernel/qcursor_p.h14
-rw-r--r--src/gui/kernel/qcursor_qws.cpp2
-rw-r--r--src/gui/kernel/qcursor_s60.cpp471
-rw-r--r--src/gui/kernel/qcursor_win.cpp2
-rw-r--r--src/gui/kernel/qcursor_x11.cpp3
-rw-r--r--src/gui/kernel/qdnd_p.h7
-rw-r--r--src/gui/kernel/qdnd_s60.cpp148
-rw-r--r--src/gui/kernel/qkeysequence.cpp2
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac.mm4
-rw-r--r--src/gui/kernel/qt_s60_p.h23
-rw-r--r--src/gui/kernel/qwidget.cpp1
-rw-r--r--src/gui/kernel/qwidget_s60.cpp77
-rw-r--r--src/gui/kernel/qwidget_win.cpp2
-rw-r--r--src/gui/kernel/symbian.pri1
-rw-r--r--src/gui/painting/qdrawutil.cpp31
-rw-r--r--src/gui/painting/qdrawutil.h2
-rw-r--r--src/gui/painting/qpainter.cpp3
-rw-r--r--src/gui/symbian/images/blank.pngbin0 -> 91 bytes
-rw-r--r--src/gui/symbian/images/busy12.pngbin0 -> 253 bytes
-rw-r--r--src/gui/symbian/images/busy3.pngbin0 -> 251 bytes
-rw-r--r--src/gui/symbian/images/busy6.pngbin0 -> 253 bytes
-rw-r--r--src/gui/symbian/images/busy9.pngbin0 -> 255 bytes
-rw-r--r--src/gui/symbian/images/closehand.pngbin0 -> 190 bytes
-rw-r--r--src/gui/symbian/images/cross.pngbin0 -> 145 bytes
-rw-r--r--src/gui/symbian/images/forbidden.pngbin0 -> 256 bytes
-rw-r--r--src/gui/symbian/images/handpoint.pngbin0 -> 230 bytes
-rw-r--r--src/gui/symbian/images/ibeam.pngbin0 -> 176 bytes
-rw-r--r--src/gui/symbian/images/openhand.pngbin0 -> 201 bytes
-rw-r--r--src/gui/symbian/images/pointer.pngbin0 -> 222 bytes
-rw-r--r--src/gui/symbian/images/sizeall.pngbin0 -> 188 bytes
-rw-r--r--src/gui/symbian/images/sizebdiag.pngbin0 -> 192 bytes
-rw-r--r--src/gui/symbian/images/sizefdiag.pngbin0 -> 197 bytes
-rw-r--r--src/gui/symbian/images/sizehor.pngbin0 -> 175 bytes
-rw-r--r--src/gui/symbian/images/sizever.pngbin0 -> 171 bytes
-rw-r--r--src/gui/symbian/images/splith.pngbin0 -> 206 bytes
-rw-r--r--src/gui/symbian/images/splitv.pngbin0 -> 205 bytes
-rw-r--r--src/gui/symbian/images/uparrow.pngbin0 -> 157 bytes
-rw-r--r--src/gui/symbian/images/wait1.pngbin0 -> 219 bytes
-rw-r--r--src/gui/symbian/images/wait10.pngbin0 -> 220 bytes
-rw-r--r--src/gui/symbian/images/wait11.pngbin0 -> 220 bytes
-rw-r--r--src/gui/symbian/images/wait12.pngbin0 -> 213 bytes
-rw-r--r--src/gui/symbian/images/wait2.pngbin0 -> 219 bytes
-rw-r--r--src/gui/symbian/images/wait3.pngbin0 -> 210 bytes
-rw-r--r--src/gui/symbian/images/wait4.pngbin0 -> 215 bytes
-rw-r--r--src/gui/symbian/images/wait5.pngbin0 -> 217 bytes
-rw-r--r--src/gui/symbian/images/wait6.pngbin0 -> 213 bytes
-rw-r--r--src/gui/symbian/images/wait7.pngbin0 -> 215 bytes
-rw-r--r--src/gui/symbian/images/wait8.pngbin0 -> 217 bytes
-rw-r--r--src/gui/symbian/images/wait9.pngbin0 -> 209 bytes
-rw-r--r--src/gui/symbian/images/whatsthis.pngbin0 -> 254 bytes
-rw-r--r--src/gui/symbian/symbianresources.qrc37
-rw-r--r--src/gui/widgets/qlineedit.cpp6
-rw-r--r--src/gui/widgets/qlineedit_p.cpp5
-rw-r--r--src/multimedia/audio/qaudiodeviceinfo.cpp6
-rw-r--r--src/multimedia/audio/qaudioformat.cpp3
-rw-r--r--src/multimedia/audio/qaudioinput.cpp7
-rw-r--r--src/multimedia/audio/qaudiooutput.cpp7
-rw-r--r--src/network/kernel/qnetworkproxy_mac.cpp3
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp12
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp1
-rw-r--r--src/opengl/qglframebufferobject.cpp11
-rw-r--r--src/opengl/qglpixmapfilter.cpp77
-rw-r--r--src/opengl/qglshaderprogram.cpp52
-rw-r--r--src/opengl/qpaintengine_opengl.cpp14
-rw-r--r--src/opengl/qpaintengine_opengl_p.h2
-rw-r--r--src/opengl/qpixmapdata_gl.cpp34
-rw-r--r--src/plugins/gfxdrivers/directfb/directfb.pro2
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp33
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbscreen.h5
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp15
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h3
-rw-r--r--src/qbase.pri8
-rw-r--r--src/svg/qgraphicssvgitem.cpp17
-rw-r--r--src/testlib/qtest.h2
-rw-r--r--src/testlib/qtestcase.cpp2
97 files changed, 1580 insertions, 431 deletions
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 897dcea..6a781e8 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -2386,6 +2386,11 @@ QT3_SUPPORT Q_CORE_EXPORT const char *qInstallPathSysconf();
#if defined(Q_OS_SYMBIAN)
+#ifdef SYMBIAN_GRAPHICS_USE_GCE
+//RWsPointerCursor is fixed, so don't use low performance sprites
+#define Q_SYMBIAN_FIXED_POINTER_CURSORS
+#endif
+
//Symbian does not support data imports from a DLL
#define Q_NO_DATA_RELOCATION
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index c8e30d4..c39e602 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -1618,6 +1618,14 @@ public:
GestureFinished = 3
};
+ enum NavigationMode
+ {
+ NavigationModeNone,
+ NavigationModeKeypadTabOrder,
+ NavigationModeKeypadDirectional,
+ NavigationModeCursorAuto,
+ NavigationModeCursorForceVisible
+ };
}
#ifdef Q_MOC_RUN
;
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 52fed47..314dfb2 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -2781,3 +2781,29 @@
\sa QGesture
*/
+
+/*!
+ \enum Qt::NavigationMode
+ \since 4.6
+
+ This enum type describes the mode for moving focus.
+
+ \value NavigationModeNone Only the touch screen is used.
+ \value NavigationModeKeypadTabOrder Qt::Key_Up and Qt::Key_Down are used to change focus.
+ \value NavigationModeKeypadDirectional Qt::Key_Up, Qt::Key_Down, Qt::Key_Left and Qt::Key_Right are used to change focus.
+ \value NavigationModeCursorAuto The mouse cursor is used to change focus,
+ it is displayed only on non touchscreen devices.
+ The keypad is used to implement a virtual cursor, unless
+ the device has an analog mouse type of input device (e.g. touchpad).
+ This is the recommended setting for an application such as a web browser that
+ needs pointer control on both touch and non-touch devices.
+ \value NavigationModeCursorForceVisible The mouse cursor is used to change focus,
+ it is displayed regardless of device type.
+ The keypad is used to implement a virtual cursor, unless
+ the device has an analog mouse type of input device (e.g. touchpad)
+
+ \note: in 4.6, cursor navigation is only implemented for Symbian OS.
+ On other platforms, it behaves as NavigationModeNone.
+ \sa QApplication::setNavigationMode
+ \sa QApplication::navigationMode
+*/
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index 06f6688..b65f1d3 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -52,7 +52,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-#undef QT_QHASH_DEBUG
QT_MODULE(Core)
class QBitArray;
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
index 18d1f5c..c1be49a 100644
--- a/src/corelib/tools/qmap.h
+++ b/src/corelib/tools/qmap.h
@@ -51,7 +51,6 @@
#endif
#include <new>
-#undef QT_MAP_DEBUG
QT_BEGIN_HEADER
diff --git a/src/corelib/tools/qmargins.cpp b/src/corelib/tools/qmargins.cpp
index f5441a3..58cef4a 100644
--- a/src/corelib/tools/qmargins.cpp
+++ b/src/corelib/tools/qmargins.cpp
@@ -59,6 +59,8 @@ QT_BEGIN_NAMESPACE
QMargin objects can be streamed as well as compared.
+ \sa qDrawBorderPixmap
+
*/
diff --git a/src/gui/effects/qgraphicseffect.cpp b/src/gui/effects/qgraphicseffect.cpp
index 26489c5..ee87323 100644
--- a/src/gui/effects/qgraphicseffect.cpp
+++ b/src/gui/effects/qgraphicseffect.cpp
@@ -493,6 +493,12 @@ void QGraphicsGrayscaleEffect::setStrength(qreal strength)
emit strengthChanged(strength);
}
+/*! \fn void QGraphicsGrayscaleEffect::strengthChanged(qreal strength)
+ This signal is emitted whenever setStrength() changes the grayscale
+ strength property. \a strength contains the new strength value of
+ the grayscale effect.
+ */
+
/*!
\reimp
*/
@@ -602,6 +608,12 @@ void QGraphicsColorizeEffect::setStrength(qreal strength)
emit strengthChanged(strength);
}
+/*! \fn void QGraphicsColorizeEffect::strengthChanged(qreal strength)
+ This signal is emitted whenever setStrength() changes the colorize
+ strength property. \a strength contains the new strength value of
+ the colorize effect.
+ */
+
/*!
\fn void QGraphicsColorizeEffect::colorChanged(const QColor &color)
@@ -782,6 +794,8 @@ void QGraphicsPixelizeEffect::draw(QPainter *painter, QGraphicsEffectSource *sou
QGraphicsBlurEffect::QGraphicsBlurEffect(QObject *parent)
: QGraphicsEffect(*new QGraphicsBlurEffectPrivate, parent)
{
+ Q_D(QGraphicsBlurEffect);
+ d->filter->setQuality(Qt::SmoothTransformation);
}
/*!
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.cpp b/src/gui/graphicsview/qgraphicsanchorlayout.cpp
index f57f65f..5897ae4 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout.cpp
+++ b/src/gui/graphicsview/qgraphicsanchorlayout.cpp
@@ -257,9 +257,9 @@ void QGraphicsAnchorLayout::addCornerAnchors(QGraphicsLayoutItem *firstItem,
}
/*!
- Anchors two or four edges of \a firstItem with the corresponding edges of \secondItem,
- so that \a firstItem has the same size as \a secondItem in the dimensions specified by
- \a orientation.
+ Anchors two or four edges of \a firstItem with the corresponding
+ edges of \a secondItem, so that \a firstItem has the same size as
+ \a secondItem in the dimensions specified by \a orientations.
Calling this convenience function with the following arguments
\code
@@ -288,45 +288,6 @@ void QGraphicsAnchorLayout::addAnchors(QGraphicsLayoutItem *firstItem,
}
/*!
- \fn QGraphicsAnchorLayout::addLeftAndRightAnchors(QGraphicsLayoutItem *firstItem, QGraphicsLayoutItem *secondItem)
-
- Anchors the left and right edges of \a firstItem to the same edges of
- \a secondItem.
-
- This convenience function is equivalent to calling
- \code
- l->addAnchor(firstItem, Qt::AnchorLeft, secondItem, Qt::AnchorLeft);
- l->addAnchor(firstItem, Qt::AnchorRight, secondItem, Qt::AnchorRight);
- \endcode
-*/
-
-/*!
- \fn QGraphicsAnchorLayout::addTopAndBottomAnchors(QGraphicsLayoutItem *firstItem, QGraphicsLayoutItem *secondItem)
-
- Anchors the top and bottom edges of \a firstItem to the same edges of
- \a secondItem.
-
- This convenience function is equivalent to calling
- \code
- l->addAnchor(firstItem, Qt::AnchorTop, secondItem, Qt::AnchorTop);
- l->addAnchor(firstItem, Qt::AnchorBottom, secondItem, Qt::AnchorBottom);
- \endcode
-*/
-
-/*!
- \fn QGraphicsAnchorLayout::addAllAnchors(QGraphicsLayoutItem *firstItem, QGraphicsLayoutItem *secondItem)
-
- Anchors all edges (left, right, top and bottom) of \a firstItem to the same edges of
- \a secondItem.
-
- This convenience function is equivalent to calling
- \code
- l->addLeftAndRightAnchors(firstItem, secondItem);
- l->addTopAndBottomAnchors(firstItem, secondItem);
- \endcode
-*/
-
-/*!
Sets the default horizontal spacing for the anchor layout to \a spacing.
\sa horizontalSpacing(), setVerticalSpacing(), setSpacing()
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 9c0c649..81eeb39 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -341,6 +341,8 @@
activates all non-panel items. Window items (i.e.,
QGraphicsItem::isWindow() returns true) are panels. This flag was
introduced in Qt 4.6.
+
+ \omitvalue ItemIsFocusScope Internal only (for now).
*/
/*!
@@ -929,12 +931,9 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParentVariant);
}
- QGraphicsItem *lastSubFocusItem = subFocusItem;
- if (subFocusItem) {
- // Update the child focus chain; when reparenting an item that has a
- // focus child, ensure that that focus child clears its focus child
- // chain from our parents before it's reparented.
- subFocusItem->clearFocus();
+ if (subFocusItem && parent) {
+ // Make sure none of the old parents point to this guy.
+ subFocusItem->d_ptr->clearSubFocus(parent);
}
// We anticipate geometry changes. If the item is deleted, it will be
@@ -960,6 +959,41 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
}
}
+ // Ensure any last parent focus scope does not point to this item or any of
+ // its descendents.
+ QGraphicsItem *p = parent;
+ QGraphicsItem *parentFocusScopeItem = 0;
+ while (p) {
+ if (p->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;
+ if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) {
+ parentFocusScopeItem = fsi;
+ p->d_ptr->focusScopeItem = 0;
+ }
+ break;
+ }
+ p = p->d_ptr->parent;
+ }
+
+ // Update focus scope item ptr in new scope.
+ if (newParent) {
+ QGraphicsItem *p = newParent;
+ while (p) {
+ if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
+ // ### We really want the parent's focus scope item to point
+ // to this item's focusItem...
+ if (q_ptr->flags() & QGraphicsItem::ItemIsFocusScope)
+ p->d_ptr->focusScopeItem = q_ptr;
+ else
+ p->d_ptr->focusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem;
+ break;
+ }
+ p = p->d_ptr->parent;
+ }
+ }
+
if ((parent = newParent)) {
bool implicitUpdate = false;
if (parent->d_func()->scene && parent->d_func()->scene != scene) {
@@ -1026,11 +1060,10 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
dirtySceneTransform = 1;
// Restore the sub focus chain.
- if (lastSubFocusItem) {
+ if (subFocusItem) {
+ subFocusItem->d_ptr->setSubFocus(newParent);
if (parent && parent->isActive())
- lastSubFocusItem->setFocus();
- else
- lastSubFocusItem->d_ptr->setSubFocus();
+ subFocusItem->setFocus();
}
// Deliver post-change notification
@@ -1199,14 +1232,23 @@ QGraphicsItem::~QGraphicsItem()
clearFocus();
+ // Update focus scope item ptr.
+ QGraphicsItem *p = d_ptr->parent;
+ while (p) {
+ if (p->flags() & ItemIsFocusScope) {
+ if (p->d_ptr->focusScopeItem == this)
+ p->d_ptr->focusScopeItem = 0;
+ break;
+ }
+ p = p->d_ptr->parent;
+ }
+
if (!d_ptr->children.isEmpty()) {
QList<QGraphicsItem *> oldChildren = d_ptr->children;
qDeleteAll(oldChildren);
Q_ASSERT(d_ptr->children.isEmpty());
}
- d_ptr->subFocusItem = 0;
-
if (d_ptr->scene) {
d_ptr->scene->d_func()->removeItemHelper(this);
} else {
@@ -1940,11 +1982,28 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo
}
// Enable subfocus
- if (newVisible && isWidget) {
- QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(q_ptr);
- QGraphicsWidget *fw = widget->focusWidget();
- if (fw && fw != scene->focusItem())
- scene->setFocusItem(fw);
+ if (newVisible) {
+ QGraphicsItem *p = parent;
+ bool done = false;
+ while (p) {
+ if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
+ QGraphicsItem *fsi = p->d_ptr->focusScopeItem;
+ if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) {
+ done = true;
+ while (fsi->d_ptr->focusScopeItem && fsi->d_ptr->focusScopeItem->isVisible())
+ fsi = fsi->d_ptr->focusScopeItem;
+ scene->setFocusItem(fsi);
+ }
+ break;
+ }
+ p = p->d_ptr->parent;
+ }
+ if (!done) {
+ QGraphicsItem *fi = subFocusItem;
+ if (fi && fi != scene->focusItem()) {
+ scene->setFocusItem(fi);
+ }
+ }
}
// Deliver post-change notification.
@@ -2732,28 +2791,55 @@ bool QGraphicsItem::hasFocus() const
*/
void QGraphicsItem::setFocus(Qt::FocusReason focusReason)
{
+ d_ptr->setFocusHelper(focusReason, /* climb = */ true);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool climb)
+{
// Disabled / unfocusable items cannot accept focus.
- if (!isEnabled() || !(d_ptr->flags & QGraphicsItem::ItemIsFocusable))
+ if (!q_ptr->isEnabled() || !(flags & QGraphicsItem::ItemIsFocusable))
return;
// Find focus proxy.
- QGraphicsItem *f = this;
+ QGraphicsItem *f = q_ptr;
while (f->d_ptr->focusProxy)
f = f->d_ptr->focusProxy;
// Return if it already has focus.
- if (d_ptr->scene && d_ptr->scene->focusItem() == f)
+ if (scene && scene->focusItem() == f)
return;
// Update the child focus chain.
- d_ptr->setSubFocus();
+ setSubFocus();
+
+ // Update focus scope item ptr.
+ QGraphicsItem *p = parent;
+ while (p) {
+ if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
+ p->d_ptr->focusScopeItem = q_ptr;
+ if (!q_ptr->isActive())
+ return;
+ break;
+ }
+ p = p->d_ptr->parent;
+ }
+
+ if (climb) {
+ while (f->d_ptr->focusScopeItem && f->d_ptr->focusScopeItem->isVisible())
+ f = f->d_ptr->focusScopeItem;
+ if (f != q_ptr)
+ f->d_ptr->setSubFocus();
+ }
// Update the scene's focus item.
- if (d_ptr->scene) {
- QGraphicsItem *p = panel();
- if ((!p && d_ptr->scene->isActive()) || (p && p->isActive())) {
+ if (scene) {
+ QGraphicsItem *p = q_ptr->panel();
+ if ((!p && scene->isActive()) || (p && p->isActive())) {
// Visible items immediately gain focus from scene.
- d_ptr->scene->d_func()->setFocusItemHelper(f, focusReason);
+ scene->d_func()->setFocusItemHelper(f, focusReason);
}
}
}
@@ -2771,8 +2857,18 @@ void QGraphicsItem::setFocus(Qt::FocusReason focusReason)
*/
void QGraphicsItem::clearFocus()
{
+ // Pass focus to the closest parent focus scope.
+ QGraphicsItem *p = d_ptr->parent;
+ while (p) {
+ if (p->flags() & ItemIsFocusScope) {
+ p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ false);
+ return;
+ }
+ p = p->d_ptr->parent;
+ }
+
// Invisible items with focus must explicitly clear subfocus.
- d_ptr->clearSubFocus();
+ d_ptr->clearSubFocus(this);
if (hasFocus()) {
// If this item has the scene's input focus, clear it.
@@ -2856,6 +2952,16 @@ QGraphicsItem *QGraphicsItem::focusItem() const
}
/*!
+ \internal
+
+ Returns this item's focus scope item.
+*/
+QGraphicsItem *QGraphicsItem::focusScopeItem() const
+{
+ return d_ptr->focusScopeItem;
+}
+
+/*!
\since 4.4
Grabs the mouse input.
@@ -4830,33 +4936,25 @@ void QGraphicsItemPrivate::ensureSceneTransformRecursive(QGraphicsItem **topMost
return; // Continue backtrack.
}
+ // This item and all its descendants have dirty scene transforms.
+ // We're about to validate this item's scene transform, so we have to
+ // invalidate all the children; otherwise there's no way for the descendants
+ // to detect that the ancestor has changed.
+ invalidateChildrenSceneTransform();
+
// COMBINE my transform with the parent's scene transform.
updateSceneTransformFromParent();
Q_ASSERT(!dirtySceneTransform);
}
-void QGraphicsItemPrivate::ensureSceneTransform()
-{
- if (dirtySceneTransform) {
- // This item and all its descendants have dirty scene transforms.
- // We're about to validate this item's scene transform, so we have to
- // invalidate all the children; otherwise there's no way for the descendants
- // to detect that the ancestor has changed.
- invalidateChildrenSceneTransform();
- }
-
- QGraphicsItem *that = q_func();
- ensureSceneTransformRecursive(&that);
-}
-
/*!
\internal
*/
-void QGraphicsItemPrivate::setSubFocus()
+void QGraphicsItemPrivate::setSubFocus(QGraphicsItem *rootItem)
{
// Update focus child chain. Stop at panels, or if this item
// is hidden, stop at the first item with a visible parent.
- QGraphicsItem *parent = q_ptr;
+ QGraphicsItem *parent = rootItem ? rootItem : q_ptr;
do {
// Clear any existing ancestor's subFocusItem.
if (parent != q_ptr && parent->d_ptr->subFocusItem) {
@@ -4865,23 +4963,25 @@ void QGraphicsItemPrivate::setSubFocus()
parent->d_ptr->subFocusItem->d_ptr->clearSubFocus();
}
parent->d_ptr->subFocusItem = q_ptr;
+ parent->d_ptr->subFocusItemChange();
} while (!parent->isPanel() && (parent = parent->d_ptr->parent) && (visible || !parent->d_ptr->visible));
- if (!parent && scene && !scene->isActive())
- scene->d_func()->lastFocusItem = q_ptr;
+ if (scene && !scene->isActive())
+ scene->d_func()->lastFocusItem = subFocusItem;
}
/*!
\internal
*/
-void QGraphicsItemPrivate::clearSubFocus()
+void QGraphicsItemPrivate::clearSubFocus(QGraphicsItem *rootItem)
{
// Reset sub focus chain.
- QGraphicsItem *parent = q_ptr;
+ QGraphicsItem *parent = rootItem ? rootItem : q_ptr;
do {
if (parent->d_ptr->subFocusItem != q_ptr)
break;
parent->d_ptr->subFocusItem = 0;
+ parent->d_ptr->subFocusItemChange();
} while (!parent->isPanel() && (parent = parent->d_ptr->parent));
}
@@ -4901,6 +5001,16 @@ void QGraphicsItemPrivate::resetFocusProxy()
/*!
\internal
+ Subclasses can reimplement this function to be notified when subFocusItem
+ changes.
+*/
+void QGraphicsItemPrivate::subFocusItemChange()
+{
+}
+
+/*!
+ \internal
+
Tells us if it is a proxy widget
*/
bool QGraphicsItemPrivate::isProxyWidget() const
@@ -5809,6 +5919,8 @@ bool QGraphicsItem::isAncestorOf(const QGraphicsItem *child) const
{
if (!child || child == this)
return false;
+ if (child->d_ptr->depth() < d_ptr->depth())
+ return false;
const QGraphicsItem *ancestor = child;
while ((ancestor = ancestor->d_ptr->parent)) {
if (ancestor == this)
@@ -10557,6 +10669,9 @@ QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlag flag)
case QGraphicsItem::ItemIsPanel:
str = "ItemIsPanel";
break;
+ case QGraphicsItem::ItemIsFocusScope:
+ str = "ItemIsFocusScope";
+ break;
}
debug << str;
return debug;
diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h
index 1c969ba..665f33f 100644
--- a/src/gui/graphicsview/qgraphicsitem.h
+++ b/src/gui/graphicsview/qgraphicsitem.h
@@ -104,7 +104,8 @@ public:
ItemSendsGeometryChanges = 0x800,
ItemAcceptsInputMethod = 0x1000,
ItemNegativeZStacksBehindParent = 0x2000,
- ItemIsPanel = 0x4000
+ ItemIsPanel = 0x4000,
+ ItemIsFocusScope = 0x8000 // internal
// NB! Don't forget to increase the d_ptr->flags bit field by 1 when adding a new flag.
};
Q_DECLARE_FLAGS(GraphicsItemFlags, GraphicsItemFlag)
@@ -244,6 +245,7 @@ public:
void setFocusProxy(QGraphicsItem *item);
QGraphicsItem *focusItem() const;
+ QGraphicsItem *focusScopeItem() const;
void grabMouse();
void ungrabMouse();
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index b891de3..fd2ff34 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -129,6 +129,7 @@ public:
itemDepth(-1),
focusProxy(0),
subFocusItem(0),
+ focusScopeItem(0),
imHints(Qt::ImhNone),
acceptedMouseButtons(0x1f),
visible(1),
@@ -318,7 +319,11 @@ public:
void invalidateCachedClipPathRecursively(bool childrenOnly = false, const QRectF &emptyIfOutsideThisRect = QRectF());
void updateCachedClipPathFromSetPosHelper(const QPointF &newPos);
void ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem);
- void ensureSceneTransform();
+ inline void ensureSceneTransform()
+ {
+ QGraphicsItem *that = q_func();
+ ensureSceneTransformRecursive(&that);
+ }
inline bool hasTranslateOnlySceneTransform()
{
@@ -408,9 +413,11 @@ public:
|| (childrenCombineOpacity() && isFullyTransparent());
}
- void setSubFocus();
- void clearSubFocus();
+ void setFocusHelper(Qt::FocusReason focusReason, bool climb);
+ void setSubFocus(QGraphicsItem *rootItem = 0);
+ void clearSubFocus(QGraphicsItem *rootItem = 0);
void resetFocusProxy();
+ virtual void subFocusItemChange();
inline QTransform transformToParent() const;
inline void ensureSortedChildren();
@@ -435,6 +442,7 @@ public:
QGraphicsItem *focusProxy;
QList<QGraphicsItem **> focusProxyRefs;
QGraphicsItem *subFocusItem;
+ QGraphicsItem *focusScopeItem;
Qt::InputMethodHints imHints;
// Packed 32 bits
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index fbd78d9..f6e0aaf 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -581,6 +581,9 @@ void QGraphicsScenePrivate::setActivePanelHelper(QGraphicsItem *item, bool durin
return;
}
+ // Ensure the scene has focus when we change panel activation.
+ q->setFocus(Qt::ActiveWindowFocusReason);
+
// Find the item's panel.
QGraphicsItem *panel = item ? item->panel() : 0;
lastActivePanel = panel ? activePanel : 0;
@@ -2431,8 +2434,17 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
// Ensure that newly added items that have subfocus set, gain
// focus automatically if there isn't a focus item already.
- if (!d->focusItem && item->focusItem() && item->isActive())
- item->focusItem()->setFocus();
+ if (!d->focusItem) {
+ if (item->focusItem() == item && item != d->lastFocusItem) {
+ QGraphicsItem *fi = item->focusItem() ? item->focusItem() : item->focusScopeItem();
+ if (fi) {
+ QGraphicsItem *fsi;
+ while ((fsi = fi->focusScopeItem()) && fsi->isVisible())
+ fi = fsi;
+ fi->setFocus();
+ }
+ }
+ }
d->updateInputMethodSensitivityInViews();
}
@@ -2780,7 +2792,7 @@ bool QGraphicsScene::hasFocus() const
void QGraphicsScene::setFocus(Qt::FocusReason focusReason)
{
Q_D(QGraphicsScene);
- if (d->hasFocus)
+ if (d->hasFocus || !isActive())
return;
QFocusEvent event(QEvent::FocusIn, focusReason);
QCoreApplication::sendEvent(this, &event);
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index 1ea0a33..b0829c5 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -1537,6 +1537,9 @@ void QGraphicsView::setScene(QGraphicsScene *scene)
}
d->updateInputMethodSensitivity();
+
+ if (d->scene && hasFocus())
+ d->scene->setFocus();
}
/*!
@@ -2607,7 +2610,6 @@ bool QGraphicsView::event(QEvent *event)
bool QGraphicsView::viewportEvent(QEvent *event)
{
Q_D(QGraphicsView);
-
if (!d->scene)
return QAbstractScrollArea::viewportEvent(event);
diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index 41df852..aff186b 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -195,7 +195,9 @@ static const _qt_BuiltInFormatStruct _qt_BuiltInFormats[] = {
};
static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
- const QByteArray &format, bool autoDetectImageFormat)
+ const QByteArray &format,
+ bool autoDetectImageFormat,
+ bool ignoresFormatAndExtension)
{
if (!autoDetectImageFormat && format.isEmpty())
return 0;
@@ -217,7 +219,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
int suffixPluginIndex = -1;
- if (device && format.isEmpty() && autoDetectImageFormat) {
+ if (device && format.isEmpty() && autoDetectImageFormat && !ignoresFormatAndExtension) {
// if there's no format, see if \a device is a file, and if so, find
// the file suffix and find support for that format among our plugins.
// this allows plugins to override our built-in handlers.
@@ -241,6 +243,9 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
QByteArray testFormat = !form.isEmpty() ? form : suffix;
+ if (ignoresFormatAndExtension)
+ testFormat = QByteArray();
+
#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
if (suffixPluginIndex != -1) {
// check if the plugin that claims support for this format can load
@@ -258,7 +263,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
device->seek(pos);
}
- if (!handler && !testFormat.isEmpty() && autoDetectImageFormat) {
+ if (!handler && !testFormat.isEmpty() && autoDetectImageFormat && !ignoresFormatAndExtension) {
// check if any plugin supports the format (they are not allowed to
// read from the device yet).
const qint64 pos = device ? device->pos() : 0;
@@ -315,7 +320,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
}
#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
- if (!handler && autoDetectImageFormat) {
+ if (!handler && (autoDetectImageFormat || ignoresFormatAndExtension)) {
// check if any of our plugins recognize the file from its contents.
const qint64 pos = device ? device->pos() : 0;
for (int i = 0; i < keys.size(); ++i) {
@@ -335,7 +340,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
}
#endif
- if (!handler && autoDetectImageFormat) {
+ if (!handler && (autoDetectImageFormat || ignoresFormatAndExtension)) {
// check if any of our built-in handlers recognize the file from its
// contents.
int currentFormat = 0;
@@ -434,6 +439,7 @@ public:
// device
QByteArray format;
bool autoDetectImageFormat;
+ bool ignoresFormatAndExtension;
QIODevice *device;
bool deleteDevice;
QImageIOHandler *handler;
@@ -458,7 +464,7 @@ public:
\internal
*/
QImageReaderPrivate::QImageReaderPrivate(QImageReader *qq)
- : autoDetectImageFormat(true)
+ : autoDetectImageFormat(true), ignoresFormatAndExtension(false)
{
device = 0;
deleteDevice = false;
@@ -522,7 +528,7 @@ bool QImageReaderPrivate::initHandler()
}
// assign a handler
- if (!handler && (handler = createReadHandlerHelper(device, format, autoDetectImageFormat)) == 0) {
+ if (!handler && (handler = createReadHandlerHelper(device, format, autoDetectImageFormat, ignoresFormatAndExtension)) == 0) {
imageReaderError = QImageReader::UnsupportedFormatError;
errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageReader, "Unsupported image format"));
return false;
@@ -664,7 +670,7 @@ QByteArray QImageReader::format() const
\o Finally, if all above approaches fail, QImageReader will report failure
when trying to read the image.
- \endlist
+ \endlist
By disabling image format autodetection, QImageReader will only query the
plugins and built-in handlers based on the format string (i.e., no file
@@ -681,13 +687,42 @@ void QImageReader::setAutoDetectImageFormat(bool enabled)
Returns true if image format autodetection is enabled on this image
reader; otherwise returns false. By default, autodetection is enabled.
- \sa setAutoDetectImageFormat()
+ \sa setAutoDetectImageFormat()
*/
bool QImageReader::autoDetectImageFormat() const
{
return d->autoDetectImageFormat;
}
+
+/*!
+ Specifies that the image reader should decide which plugin to use
+ solely based on the contents in the datastream.
+
+ Setting this flag means that all image plugins gets loaded. Each
+ plugin will read the first bytes in the image data and decide if
+ the plugin is compatible or not. The flag is set to \a ignored.
+
+ This also disables auto detecting image format.
+*/
+
+void QImageReader::setDecideFormatFromContent(bool ignored)
+{
+ d->ignoresFormatAndExtension = ignored;
+}
+
+
+/*!
+ Returns wether the image reader should decide which plugin to use
+ sloley based on the contents of the datastream
+*/
+
+bool QImageReader::decideFormatFromContent() const
+{
+ return d->ignoresFormatAndExtension;
+}
+
+
/*!
Sets QImageReader's device to \a device. If a device has already
been set, the old device is removed from QImageReader and is
@@ -1309,7 +1344,7 @@ QByteArray QImageReader::imageFormat(const QString &fileName)
QByteArray QImageReader::imageFormat(QIODevice *device)
{
QByteArray format;
- QImageIOHandler *handler = createReadHandlerHelper(device, format, /* autoDetectImageFormat = */ true);
+ QImageIOHandler *handler = createReadHandlerHelper(device, format, /* autoDetectImageFormat = */ true, false);
if (handler) {
if (handler->canRead())
format = handler->format();
diff --git a/src/gui/image/qimagereader.h b/src/gui/image/qimagereader.h
index 86031ec..11affb8 100644
--- a/src/gui/image/qimagereader.h
+++ b/src/gui/image/qimagereader.h
@@ -81,6 +81,9 @@ public:
void setAutoDetectImageFormat(bool enabled);
bool autoDetectImageFormat() const;
+ void setDecideFormatFromContent(bool ignored);
+ bool decideFormatFromContent() const;
+
void setDevice(QIODevice *device);
QIODevice *device() const;
diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp
index 493e440..666e557 100644
--- a/src/gui/image/qpixmap_s60.cpp
+++ b/src/gui/image/qpixmap_s60.cpp
@@ -178,7 +178,12 @@ CFbsBitmap *QPixmap::toSymbianCFbsBitmap() const
return 0;
}
- const QImage converted = img.convertToFormat(destFormat);
+ QImage converted = img.convertToFormat(destFormat);
+
+ //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
+ //So invert mono bitmaps so that masks work correctly.
+ if (mode == EGray2)
+ converted.invertPixels();
bitmap->LockHeap();
const uchar *sptr = converted.bits();
@@ -220,6 +225,9 @@ QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap)
image.setNumColors(2);
image.setColor(0, QColor(Qt::color0).rgba());
image.setColor(1, QColor(Qt::color1).rgba());
+ //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
+ //So invert mono bitmaps so that masks work correctly.
+ image.invertPixels();
} else if (displayMode == EGray256) {
for (int i=0; i < 256; ++i)
image.setColor(i, qRgb(i, i, i));
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index a19e022..1fd2d39 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -458,10 +458,10 @@ bool QApplicationPrivate::widgetCount = false;
bool QApplicationPrivate::inSizeMove = false;
#endif
#ifdef QT_KEYPAD_NAVIGATION
-# if defined(Q_OS_SYMBIAN)
-bool QApplicationPrivate::keypadNavigation = true;
+# ifdef Q_OS_SYMBIAN
+Qt::NavigationMode QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadDirectional;
# else
-bool QApplicationPrivate::keypadNavigation = false;
+Qt::NavigationMode QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadTabOrder;
# endif
QWidget *QApplicationPrivate::oldEditFocus = 0;
#endif
@@ -2521,12 +2521,6 @@ QWidget *QApplicationPrivate::focusNextPrevChild_helper(QWidget *toplevel, bool
Creates the proper Enter/Leave event when widget \a enter is entered and
widget \a leave is left.
*/
-#if defined(Q_WS_WIN)
- extern void qt_win_set_cursor(QWidget *, bool);
-#elif defined(Q_WS_X11)
- extern void qt_x11_enforce_cursor(QWidget *, bool);
-#endif
-
void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave) {
#if 0
if (leave) {
@@ -2676,6 +2670,8 @@ void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave) {
qt_win_set_cursor(cursorWidget, true);
#elif defined(Q_WS_X11)
qt_x11_enforce_cursor(cursorWidget, true);
+#elif defined(Q_WS_S60)
+ qt_symbian_set_cursor(cursorWidget, true);
#endif
}
}
@@ -4777,10 +4773,36 @@ void QApplicationPrivate::emitLastWindowClosed()
#ifdef QT_KEYPAD_NAVIGATION
/*!
- Sets whether Qt should use focus navigation suitable for use with a
- minimal keypad.
+ Sets what kind of focus navigation Qt should use.
+
+ This feature is available in Qt for Embedded Linux, Symbian and Windows CE
+ only.
+
+ \note On Windows CE this feature is disabled by default for touch device
+ mkspecs. To enable keypad navigation, build Qt with
+ QT_KEYPAD_NAVIGATION defined.
+
+ \note On Symbian, setting the mode to Qt::NavigationModeCursorAuto will enable a
+ virtual mouse cursor on non touchscreen devices, which is controlled
+ by the cursor keys if there is no analog pointer device.
+ On other platforms and on touchscreen devices, it has the same
+ meaning as Qt::NavigationModeNone.
+
+ \since 4.6
+
+ \sa keypadNavigationEnabled()
+*/
+void QApplication::setNavigationMode(Qt::NavigationMode mode)
+{
+#ifdef Q_OS_SYMBIAN
+ QApplicationPrivate::setNavigationMode(mode);
+#else
+ QApplicationPrivate::navigationMode = mode;
+#endif
+}
- If \a enable is true, Qt::Key_Up and Qt::Key_Down are used to change focus.
+/*!
+ Returns what kind of focus navigation Qt is using.
This feature is available in Qt for Embedded Linux, Symbian and Windows CE
only.
@@ -4788,12 +4810,47 @@ void QApplicationPrivate::emitLastWindowClosed()
\note On Windows CE this feature is disabled by default for touch device
mkspecs. To enable keypad navigation, build Qt with
QT_KEYPAD_NAVIGATION defined.
+
+ \note On Symbian, the default mode is Qt::NavigationModeNone for touch
+ devices, and Qt::NavigationModeKeypadDirectional.
+
+ \since 4.6
\sa keypadNavigationEnabled()
*/
+Qt::NavigationMode QApplication::navigationMode()
+{
+ return QApplicationPrivate::navigationMode;
+}
+
+/*!
+ Sets whether Qt should use focus navigation suitable for use with a
+ minimal keypad.
+
+ This feature is available in Qt for Embedded Linux, Symbian and Windows CE
+ only.
+
+
+ \note On Windows CE this feature is disabled by default for touch device
+ mkspecs. To enable keypad navigation, build Qt with
+ QT_KEYPAD_NAVIGATION defined.
+
+ \deprecated
+
+ \sa setNavigationMode()
+*/
void QApplication::setKeypadNavigationEnabled(bool enable)
{
- QApplicationPrivate::keypadNavigation = enable;
+ if (enable) {
+#ifdef Q_OS_SYMBIAN
+ QApplication::setNavigationMode(Qt::NavigationModeKeypadDirectional);
+#else
+ QApplication::setNavigationMode(Qt::NavigationModeKeypadTabOrder);
+#endif
+ }
+ else {
+ QApplication::setNavigationMode(Qt::NavigationModeNone);
+ }
}
/*!
@@ -4806,12 +4863,15 @@ void QApplication::setKeypadNavigationEnabled(bool enable)
\note On Windows CE this feature is disabled by default for touch device
mkspecs. To enable keypad navigation, build Qt with
QT_KEYPAD_NAVIGATION defined.
+
+ \deprecated
- \sa setKeypadNavigationEnabled()
+ \sa navigationMode()
*/
bool QApplication::keypadNavigationEnabled()
{
- return QApplicationPrivate::keypadNavigation;
+ return QApplicationPrivate::navigationMode == Qt::NavigationModeKeypadTabOrder ||
+ QApplicationPrivate::navigationMode == Qt::NavigationModeKeypadDirectional;
}
#endif
diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h
index 216cfff..0562251 100644
--- a/src/gui/kernel/qapplication.h
+++ b/src/gui/kernel/qapplication.h
@@ -272,8 +272,10 @@ public:
static bool quitOnLastWindowClosed();
#ifdef QT_KEYPAD_NAVIGATION
- static void setKeypadNavigationEnabled(bool);
+ static Q_DECL_DEPRECATED void setKeypadNavigationEnabled(bool);
static bool keypadNavigationEnabled();
+ static void setNavigationMode(Qt::NavigationMode mode);
+ static Qt::NavigationMode navigationMode();
#endif
Q_SIGNALS:
diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h
index c33eb1a..707caaa 100644
--- a/src/gui/kernel/qapplication_p.h
+++ b/src/gui/kernel/qapplication_p.h
@@ -71,6 +71,9 @@
#include "QtGui/qscreen_qws.h"
#include <private/qgraphicssystem_qws_p.h>
#endif
+#ifdef Q_OS_SYMBIAN
+#include <w32std.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -492,8 +495,8 @@ public:
static int app_compile_version;
#ifdef QT_KEYPAD_NAVIGATION
- static bool keypadNavigation;
static QWidget *oldEditFocus;
+ static Qt::NavigationMode navigationMode;
#endif
#if defined(Q_WS_MAC) || defined(Q_WS_X11)
@@ -511,7 +514,9 @@ public:
QWidget *native, QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver,
bool spontaneous = true);
#ifdef Q_OS_SYMBIAN
+ static void setNavigationMode(Qt::NavigationMode mode);
static TUint resolveS60ScanCode(TInt scanCode, TUint keysym);
+ QSet<WId> nativeWindows;
#endif
#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS)
void sendSyntheticEnterLeave(QWidget *widget);
@@ -595,6 +600,15 @@ Q_GUI_EXPORT void qt_translateRawTouchEvent(QWidget *window,
QTouchEvent::DeviceType deviceType,
const QList<QTouchEvent::TouchPoint> &touchPoints);
+#if defined(Q_WS_WIN)
+ extern void qt_win_set_cursor(QWidget *, bool);
+#elif defined(Q_WS_X11)
+ extern void qt_x11_enforce_cursor(QWidget *, bool);
+ extern void qt_x11_enforce_cursor(QWidget *);
+#elif defined(Q_OS_SYMBIAN)
+ extern void qt_symbian_set_cursor(QWidget *, bool);
+#endif
+
QT_END_NAMESPACE
#endif // QAPPLICATION_P_H
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 00932a0..fd889fc 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -73,6 +73,9 @@
#include "private/qstylesheetstyle_p.h"
+#include <hal.h>
+#include <hal_data.h>
+
QT_BEGIN_NAMESPACE
#if defined(QT_DEBUG)
@@ -151,21 +154,21 @@ void QS60Beep::ConstructL(TInt aFrequency, TTimeIntervalMicroSeconds aDuration)
void QS60Beep::Play()
{
- if(iState!=EBeepNotPrepared){
- if(iState==EBeepPlaying) {
+ if (iState != EBeepNotPrepared) {
+ if (iState == EBeepPlaying) {
iToneUtil->CancelPlay();
- iState=EBeepPrepared;
+ iState = EBeepPrepared;
}
}
iToneUtil->Play();
- iState=EBeepPlaying;
+ iState = EBeepPlaying;
}
void QS60Beep::MatoPrepareComplete(TInt aError)
{
- if(aError==KErrNone) {
- iState=EBeepPrepared;
+ if (aError == KErrNone) {
+ iState = EBeepPrepared;
}
}
@@ -320,8 +323,9 @@ void QSymbianControl::ConstructL(bool topLevel, bool desktop)
{
if (!desktop)
{
- if (topLevel)
+ if (topLevel) {
CreateWindowL(S60->windowGroup());
+ }
SetFocusing(true);
m_longTapDetector = QLongTapTimer::NewL(this);
@@ -330,6 +334,8 @@ void QSymbianControl::ConstructL(bool topLevel, bool desktop)
QSymbianControl::~QSymbianControl()
{
+ if (S60->curWin == this)
+ S60->curWin = 0;
S60->appUi()->RemoveFromStack(this);
delete m_longTapDetector;
}
@@ -392,14 +398,15 @@ void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent)
TPoint controlScreenPos = PositionRelativeToScreen();
QPoint globalPos = QPoint(controlScreenPos.iX, controlScreenPos.iY) + widgetPos;
- if (type == QEvent::MouseButtonPress || type == QEvent::MouseButtonDblClick)
+ if (type == QEvent::MouseButtonPress || type == QEvent::MouseButtonDblClick || type == QEvent::MouseMove)
{
- // get the button press target
+ // get the widget where the event happened
alienWidget = qwidget->childAt(widgetPos);
if (!alienWidget)
alienWidget = qwidget;
S60->mousePressTarget = alienWidget;
}
+
alienWidget = S60->mousePressTarget;
if (alienWidget != S60->lastPointerEventTarget)
@@ -412,12 +419,30 @@ void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent)
button, QApplicationPrivate::mouse_buttons, mapToQtModifiers(pEvent.iModifiers));
events.append(Event(S60->lastPointerEventTarget,mEventLeave));
}
- QMouseEvent mEventEnter(QEvent::Enter, alienWidget->mapFromGlobal(globalPos), globalPos,
- button, QApplicationPrivate::mouse_buttons, mapToQtModifiers(pEvent.iModifiers));
-
- events.append(Event(alienWidget,mEventEnter));
+ if (alienWidget) {
+ QMouseEvent mEventEnter(QEvent::Enter, alienWidget->mapFromGlobal(globalPos),
+ globalPos, button, QApplicationPrivate::mouse_buttons, mapToQtModifiers(
+ pEvent.iModifiers));
+
+ events.append(Event(alienWidget, mEventEnter));
+#ifndef QT_NO_CURSOR
+ S60->curWin = alienWidget->effectiveWinId();
+ if (!QApplication::overrideCursor()) {
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors)
+ qt_symbian_set_pointer_sprite(alienWidget->cursor());
+ else
+#endif
+ qt_symbian_setWindowCursor(alienWidget->cursor(), S60->curWin);
+ }
+#endif
+ }
}
S60->lastCursorPos = globalPos;
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors)
+ qt_symbian_move_cursor_sprite();
+#endif
S60->lastPointerEventPos = widgetPos;
S60->lastPointerEventTarget = alienWidget;
if (alienWidget)
@@ -494,6 +519,82 @@ TKeyResponse QSymbianControl::OfferKeyEvent(const TKeyEvent& keyEvent, TEventCod
// Special S60 keys.
keyCode = qt_keymapper_private()->mapS60KeyToQt(s60Keysym);
}
+
+#ifndef QT_NO_CURSOR
+ if (S60->mouseInteractionEnabled && S60->virtualMouseRequired) {
+ //translate keys to pointer
+ if (keyCode >= Qt::Key_Left && keyCode <= Qt::Key_Down || keyCode == Qt::Key_Select) {
+ /*Explanation about virtualMouseAccel:
+ Tapping an arrow key allows precise pixel positioning
+ Holding an arrow key down, acceleration is applied to allow cursor
+ to be quickly moved to another part of the screen by key repeats.
+ */
+ if (S60->virtualMouseLastKey == keyCode) {
+ S60->virtualMouseAccel *= 2;
+ if (S60->virtualMouseAccel > S60->virtualMouseMaxAccel)
+ S60->virtualMouseAccel = S60->virtualMouseMaxAccel;
+ }
+ else
+ S60->virtualMouseAccel = 1;
+ S60->virtualMouseLastKey = keyCode;
+
+ QPoint pos = QCursor::pos();
+ TPointerEvent fakeEvent;
+ TInt x = pos.x();
+ TInt y = pos.y();
+ if (type == EEventKeyUp) {
+ if (keyCode == Qt::Key_Select)
+ fakeEvent.iType = TPointerEvent::EButton1Up;
+ S60->virtualMouseAccel = 1;
+ S60->virtualMouseLastKey = 0;
+ }
+ else if (type == EEventKey) {
+ switch (keyCode) {
+ case Qt::Key_Left:
+ x -= S60->virtualMouseAccel;
+ fakeEvent.iType = TPointerEvent::EMove;
+ break;
+ case Qt::Key_Right:
+ x += S60->virtualMouseAccel;
+ fakeEvent.iType = TPointerEvent::EMove;
+ break;
+ case Qt::Key_Up:
+ y -= S60->virtualMouseAccel;
+ fakeEvent.iType = TPointerEvent::EMove;
+ break;
+ case Qt::Key_Down:
+ y += S60->virtualMouseAccel;
+ fakeEvent.iType = TPointerEvent::EMove;
+ break;
+ case Qt::Key_Select:
+ fakeEvent.iType = TPointerEvent::EButton1Down;
+ break;
+ }
+ }
+ //clip to screen size (window server allows a sprite hotspot to be outside the screen)
+ if (x < 0)
+ x = 0;
+ else if (x >= S60->screenWidthInPixels)
+ x = S60->screenWidthInPixels - 1;
+ if (y < 0)
+ y = 0;
+ else if (y >= S60->screenHeightInPixels)
+ y = S60->screenHeightInPixels - 1;
+ TPoint epos(x, y);
+ TPoint cpos = epos - PositionRelativeToScreen();
+ fakeEvent.iModifiers = keyEvent.iModifiers;
+ fakeEvent.iPosition = cpos;
+ fakeEvent.iParentPosition = epos;
+ HandlePointerEvent(fakeEvent);
+ return EKeyWasConsumed;
+ }
+ else {
+ S60->virtualMouseLastKey = keyCode;
+ S60->virtualMouseAccel = 1;
+ }
+ }
+#endif
+
Qt::KeyboardModifiers mods = mapToQtModifiers(keyEvent.iModifiers);
QKeyEventEx qKeyEvent(type == EEventKeyUp ? QEvent::KeyRelease : QEvent::KeyPress, keyCode,
mods, qt_keymapper_private()->translateKeyEvent(keyCode, mods),
@@ -557,7 +658,7 @@ TKeyResponse QSymbianControl::sendKeyEvent(QWidget *widget, QKeyEvent *keyEvent)
#if !defined(QT_NO_IM) && defined(Q_WS_S60)
if (widget && widget->isEnabled() && widget->testAttribute(Qt::WA_InputMethodEnabled)) {
QInputContext *qic = widget->inputContext();
- if(qic && qic->filterEvent(keyEvent))
+ if (qic && qic->filterEvent(keyEvent))
return EKeyWasConsumed;
}
#endif // !defined(QT_NO_IM) && defined(Q_WS_S60)
@@ -574,11 +675,10 @@ TCoeInputCapabilities QSymbianControl::InputCapabilities() const
{
QWidget *w = 0;
- if(qwidget->hasFocus()) {
+ if (qwidget->hasFocus())
w = qwidget;
- } else {
+ else
w = qwidget->focusWidget();
- }
QCoeFepInputContext *ic;
if (w && w->isEnabled() && w->testAttribute(Qt::WA_InputMethodEnabled)
@@ -749,6 +849,70 @@ void qt_init(QApplicationPrivate * /* priv */, int)
TSecureId securId = me.SecureId();
S60->uid = securId.operator TUid();
+ // enable focus events - used to re-enable mouse after focus changed between mouse and non mouse app,
+ // and for dimming behind modal windows
+ S60->windowGroup().EnableFocusChangeEvents();
+
+ //Check if mouse interaction is supported (either EMouse=1 in the HAL, or EMachineUID is one of the phones known to support this)
+ const TInt KMachineUidSamsungI8510 = 0x2000C51E;
+ const TInt KMachineUidSamsungI550 = 0x2000A678;
+ TInt machineUID;
+ TInt mouse;
+ TInt touch;
+ TInt err;
+ err = HAL::Get(HALData::EMouse, mouse);
+ if (err != KErrNone)
+ mouse = 0;
+ err = HAL::Get(HALData::EMachineUid, machineUID);
+ if (err != KErrNone)
+ machineUID = 0;
+ err = HAL::Get(HALData::EPen, touch);
+ if (err != KErrNone)
+ touch = 0;
+ if (mouse || machineUID == KMachineUidSamsungI8510) {
+ S60->hasTouchscreen = false;
+ S60->virtualMouseRequired = false;
+ }
+ else if (!touch) {
+ S60->hasTouchscreen = false;
+ S60->virtualMouseRequired = true;
+ }
+ else {
+ S60->hasTouchscreen = true;
+ S60->virtualMouseRequired = false;
+ }
+
+ if (touch) {
+ QApplicationPrivate::navigationMode = Qt::NavigationModeNone;
+ } else {
+ QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadDirectional;
+ }
+
+ //Check if window server pointer cursors are supported or not
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ //In generic binary, use the HAL and OS version
+ //Any other known good phones should be added here.
+ if (machineUID == KMachineUidSamsungI8510 || (QSysInfo::symbianVersion() != QSysInfo::SV_9_4
+ && QSysInfo::symbianVersion() != QSysInfo::SV_9_3 && QSysInfo::symbianVersion()
+ != QSysInfo::SV_9_2)) {
+ S60->brokenPointerCursors = false;
+ qt_symbian_setWindowGroupCursor(Qt::ArrowCursor, S60->windowGroup());
+ }
+ else
+ S60->brokenPointerCursors = true;
+#endif
+
+ if (S60->mouseInteractionEnabled) {
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors) {
+ qt_symbian_set_pointer_sprite(Qt::ArrowCursor);
+ qt_symbian_show_pointer_sprite();
+ }
+ else
+#endif
+ S60->wsSession().SetPointerCursorMode(EPointerCursorNormal);
+ }
+
/*
### Commented out for now as parameter handling not needed in SOS(yet). Code below will break testlib with -o flag
int argc = priv->argc;
@@ -785,6 +949,9 @@ void qt_cleanup()
// it dies.
delete QApplicationPrivate::inputContext;
QApplicationPrivate::inputContext = 0;
+
+ //Change mouse pointer back
+ S60->wsSession().SetPointerCursorMode(EPointerCursorNone);
if (S60->qtOwnsS60Environment) {
CEikonEnv* coe = CEikonEnv::Static();
@@ -1016,9 +1183,8 @@ void QApplication::beep()
TTimeIntervalMicroSeconds duration(500000);
QS60Beep* beep=NULL;
TRAPD(err, beep=QS60Beep::NewL(frequency, duration));
- if(!err) {
+ if (!err)
beep->Play();
- }
delete beep;
beep=NULL;
}
@@ -1108,7 +1274,31 @@ int QApplication::s60ProcessEvent(TWsEvent *event)
return 1;
}
break;
- default:
+ case EEventFocusGained:
+ RDebug::Printf("focus gained %x", control);
+ //re-enable mouse interaction
+ if (S60->mouseInteractionEnabled) {
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors)
+ qt_symbian_show_pointer_sprite();
+ else
+#endif
+ S60->wsSession().SetPointerCursorMode(EPointerCursorNormal);
+ }
+ break;
+ case EEventFocusLost:
+ RDebug::Printf("focus lost %x", control);
+ //disable mouse as may be moving to application that does not support it
+ if (S60->mouseInteractionEnabled) {
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors)
+ qt_symbian_hide_pointer_sprite();
+ else
+#endif
+ S60->wsSession().SetPointerCursorMode(EPointerCursorNone);
+ }
+ break;
+ default:
break;
}
@@ -1279,4 +1469,81 @@ void QSessionManager::cancel()
}
#endif //QT_NO_SESSIONMANAGER
+
+#ifdef QT_KEYPAD_NAVIGATION
+/*
+ * Show/Hide the mouse cursor depending on phone type and chosen mode
+ */
+void QApplicationPrivate::setNavigationMode(Qt::NavigationMode mode)
+{
+#ifndef QT_NO_CURSOR
+ const bool wasCursorOn = (QApplicationPrivate::navigationMode == Qt::NavigationModeCursorAuto
+ && !S60->hasTouchscreen)
+ || QApplicationPrivate::navigationMode == Qt::NavigationModeCursorForceVisible;
+ const bool isCursorOn = (mode == Qt::NavigationModeCursorAuto
+ && !S60->hasTouchscreen)
+ || mode == Qt::NavigationModeCursorForceVisible;
+
+ if (!wasCursorOn && isCursorOn) {
+ //Show the cursor, when changing from another mode to cursor mode
+ qt_symbian_set_cursor_visible(true);
+ }
+ else if (wasCursorOn && !isCursorOn) {
+ //Hide the cursor, when leaving cursor mode
+ qt_symbian_set_cursor_visible(false);
+ }
+#endif
+ QApplicationPrivate::navigationMode = mode;
+}
+#endif
+
+#ifndef QT_NO_CURSOR
+/*****************************************************************************
+ QApplication cursor stack
+ *****************************************************************************/
+
+void QApplication::setOverrideCursor(const QCursor &cursor)
+{
+ qApp->d_func()->cursor_list.prepend(cursor);
+ qt_symbian_setGlobalCursor(cursor);
+}
+
+void QApplication::restoreOverrideCursor()
+{
+ if (qApp->d_func()->cursor_list.isEmpty())
+ return;
+ qApp->d_func()->cursor_list.removeFirst();
+
+ if (!qApp->d_func()->cursor_list.isEmpty()) {
+ qt_symbian_setGlobalCursor(qApp->d_func()->cursor_list.first());
+ }
+ else {
+ //determine which widget has focus
+ QWidget *w = QApplication::widgetAt(QCursor::pos());
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors) {
+ qt_symbian_set_pointer_sprite(w ? w->cursor() : Qt::ArrowCursor);
+ }
+ else
+#endif
+ {
+ //because of the internals of window server, we need to force the cursor
+ //to be set in all child windows too, otherwise when the cursor is over
+ //the child window it may show a widget cursor or arrow cursor instead,
+ //depending on construction order.
+ QListIterator<WId> iter(QWidgetPrivate::mapper->uniqueKeys());
+ while (iter.hasNext()) {
+ CCoeControl *ctrl = iter.next();
+ ctrl->DrawableWindow()->ClearPointerCursor();
+ }
+ if (w)
+ qt_symbian_setWindowCursor(w->cursor(), w->effectiveWinId());
+ else
+ qt_symbian_setWindowGroupCursor(Qt::ArrowCursor, S60->windowGroup());
+ }
+ }
+}
+
+#endif // QT_NO_CURSOR
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
index 1ce799c..601cd11 100644
--- a/src/gui/kernel/qapplication_x11.cpp
+++ b/src/gui/kernel/qapplication_x11.cpp
@@ -2820,8 +2820,6 @@ void QApplicationPrivate::applyX11SpecificCommandLineArguments(QWidget *main_wid
QApplication cursor stack
*****************************************************************************/
-extern void qt_x11_enforce_cursor(QWidget * w);
-
void QApplication::setOverrideCursor(const QCursor &cursor)
{
qApp->d_func()->cursor_list.prepend(cursor);
diff --git a/src/gui/kernel/qcursor.h b/src/gui/kernel/qcursor.h
index 389a110..2b2aa4a 100644
--- a/src/gui/kernel/qcursor.h
+++ b/src/gui/kernel/qcursor.h
@@ -72,13 +72,19 @@ private:
#ifndef QT_NO_CURSOR
-struct QCursorData;
+class QCursorData;
class QBitmap;
class QPixmap;
#if defined(Q_WS_MAC)
void qt_mac_set_cursor(const QCursor *c, const QPoint &p);
#endif
+#if defined(Q_OS_SYMBIAN)
+extern void qt_symbian_show_pointer_sprite();
+extern void qt_symbian_hide_pointer_sprite();
+extern void qt_symbian_set_pointer_sprite(const QCursor& cursor);
+extern void qt_symbian_move_cursor_sprite();
+#endif
class Q_GUI_EXPORT QCursor
{
@@ -103,7 +109,7 @@ public:
static QPoint pos();
static void setPos(int x, int y);
inline static void setPos(const QPoint &p) { setPos(p.x(), p.y()); }
-
+
#ifdef qdoc
HCURSOR_or_HANDLE handle() const;
QCursor(HCURSOR cursor);
@@ -122,6 +128,8 @@ public:
Qt::HANDLE handle() const;
#elif defined(Q_WS_QWS)
int handle() const;
+#elif defined(Q_OS_SYMBIAN)
+ Qt::HANDLE handle() const;
#endif
#endif
@@ -131,6 +139,12 @@ private:
friend void *qt_mac_nsCursorForQCursor(const QCursor &c);
friend void qt_mac_set_cursor(const QCursor *c, const QPoint &p);
#endif
+#if defined(Q_OS_SYMBIAN)
+ friend void qt_symbian_show_pointer_sprite();
+ friend void qt_symbian_hide_pointer_sprite();
+ friend void qt_symbian_set_pointer_sprite(const QCursor& cursor);
+ friend void qt_symbian_move_cursor_sprite();
+#endif
};
#ifdef QT3_SUPPORT
diff --git a/src/gui/kernel/qcursor_p.h b/src/gui/kernel/qcursor_p.h
index aa4f4b2..12166c8 100644
--- a/src/gui/kernel/qcursor_p.h
+++ b/src/gui/kernel/qcursor_p.h
@@ -64,6 +64,8 @@
# include "private/qt_x11_p.h"
# elif defined(Q_WS_WIN)
# include "QtCore/qt_windows.h"
+# elif defined(Q_OS_SYMBIAN)
+# include "private/qt_s60_p.h"
#endif
QT_BEGIN_NAMESPACE
@@ -74,7 +76,8 @@ class QMacAnimateCursor;
#endif
class QBitmap;
-struct QCursorData {
+class QCursorData {
+public:
QCursorData(Qt::CursorShape s = Qt::ArrowCursor);
~QCursorData();
@@ -111,12 +114,21 @@ struct QCursorData {
} curs;
void initCursorFromBitmap();
void initCursorFromPixmap();
+#elif defined Q_OS_SYMBIAN
+ void loadShapeFromResource(RWsSpriteBase& target, QString resource, int hx, int hy, int interval=0);
+ void constructShapeSprite(RWsSpriteBase& target);
+ void constructCursorSprite(RWsSpriteBase& target);
+ RWsPointerCursor pcurs;
+ RWsSprite scurs;
+ RPointerArray<TSpriteMember> nativeSpriteMembers;
#endif
static bool initialized;
void update();
static QCursorData *setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY);
};
+extern QCursorData *qt_cursorTable[Qt::LastCursor + 1]; // qcursor.cpp
+
QT_END_NAMESPACE
#endif // QCURSOR_P_H
diff --git a/src/gui/kernel/qcursor_qws.cpp b/src/gui/kernel/qcursor_qws.cpp
index eda826b..0eeb187 100644
--- a/src/gui/kernel/qcursor_qws.cpp
+++ b/src/gui/kernel/qcursor_qws.cpp
@@ -78,8 +78,6 @@ QCursorData::~QCursorData()
Global cursors
*****************************************************************************/
-extern QCursorData *qt_cursorTable[Qt::LastCursor + 1]; // qcursor.cpp
-
int QCursor::handle() const
{
return d->id;
diff --git a/src/gui/kernel/qcursor_s60.cpp b/src/gui/kernel/qcursor_s60.cpp
index b812994..757eaa8 100644
--- a/src/gui/kernel/qcursor_s60.cpp
+++ b/src/gui/kernel/qcursor_s60.cpp
@@ -40,12 +40,22 @@
****************************************************************************/
#include <private/qcursor_p.h>
+#include <private/qwidget_p.h>
+#include <private/qapplication_p.h>
+#include <coecntrl.h>
#include <qcursor.h>
#include <qt_s60_p.h>
+#include <qbitmap.h>
+#include <w32std.h>
+#include <qapplication.h>
+#include <qwidget.h>
-#ifdef QT_NO_CURSOR
QT_BEGIN_NAMESPACE
+static QCursor cursorSprite;
+static int cursorSpriteVisible;
+
+//pos and setpos are required whether cursors are configured or not.
QPoint QCursor::pos()
{
return S60->lastCursorPos;
@@ -53,8 +63,467 @@ QPoint QCursor::pos()
void QCursor::setPos(int x, int y)
{
+ //clip to screen size (window server allows a sprite hotspot to be outside the screen)
+ if (x < 0)
+ x=0;
+ else if (x >= S60->screenWidthInPixels)
+ x = S60->screenWidthInPixels - 1;
+ if (y < 0)
+ y = 0;
+ else if (y >= S60->screenHeightInPixels)
+ y = S60->screenHeightInPixels - 1;
+
+#ifndef QT_NO_CURSOR
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors && cursorSpriteVisible)
+ cursorSprite.d->scurs.SetPosition(TPoint(x,y));
+ else
+#endif
+ S60->wsSession().SetPointerCursorPosition(TPoint(x, y));
+#endif
S60->lastCursorPos = QPoint(x, y);
+ //send a fake mouse move event, so that enter/leave events go to the widget hierarchy
+ QWidget *w = QApplication::topLevelAt(S60->lastCursorPos);
+ if (w) {
+ CCoeControl* ctrl = w->effectiveWinId();
+ TPoint epos(x, y);
+ TPoint cpos = epos - ctrl->PositionRelativeToScreen();
+ TPointerEvent fakeEvent;
+ fakeEvent.iType = TPointerEvent::EMove;
+ fakeEvent.iModifiers = 0U;
+ fakeEvent.iPosition = cpos;
+ fakeEvent.iParentPosition = epos;
+ ctrl->HandlePointerEventL(fakeEvent);
+ }
+}
+
+#ifndef QT_NO_CURSOR
+/*
+ * Request cursor to be turned on or off.
+ * Reference counted, so 2 on + 1 off = on, for example
+ */
+void qt_symbian_set_cursor_visible(bool visible) {
+ if (visible)
+ cursorSpriteVisible++;
+ else
+ cursorSpriteVisible--;
+ Q_ASSERT(cursorSpriteVisible >=0);
+
+ if (cursorSpriteVisible && !S60->mouseInteractionEnabled) {
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors)
+ qt_symbian_show_pointer_sprite();
+ else
+#endif
+ S60->wsSession().SetPointerCursorMode(EPointerCursorNormal);
+ } else if (!cursorSpriteVisible && S60->mouseInteractionEnabled) {
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors)
+ qt_symbian_hide_pointer_sprite();
+ else
+#endif
+ S60->wsSession().SetPointerCursorMode(EPointerCursorNone);
+ }
+ S60->mouseInteractionEnabled = ((cursorSpriteVisible > 0) ? true : false);
+}
+
+/*
+ * Check if the cursor is on or off
+ */
+bool qt_symbian_is_cursor_visible() {
+ return S60->mouseInteractionEnabled;
+}
+
+QCursorData::QCursorData(Qt::CursorShape s) :
+ cshape(s), bm(0), bmm(0), hx(0), hy(0), pcurs()
+{
+ ref = 1;
+}
+
+QCursorData::~QCursorData()
+{
+ for(int i=0;i<nativeSpriteMembers.Count();i++) {
+ delete nativeSpriteMembers[i]->iBitmap;
+ delete nativeSpriteMembers[i]->iMaskBitmap;
+ }
+ nativeSpriteMembers.ResetAndDestroy();
+ pcurs.Close();
+ delete bm;
+ delete bmm;
+}
+
+/* Create a bitmap cursor, this is called by public constructors in the
+ * generic QCursor code.
+ */
+QCursorData *QCursorData::setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY)
+{
+ if (!QCursorData::initialized)
+ QCursorData::initialize();
+ if (bitmap.depth() != 1 || mask.depth() != 1 || bitmap.size() != mask.size()) {
+ qWarning("QCursor: Cannot create bitmap cursor; invalid bitmap(s)");
+ QCursorData *c = qt_cursorTable[0];
+ c->ref.ref();
+ return c;
+ }
+ QCursorData *d = new QCursorData;
+ d->bm = new QBitmap(bitmap);
+ d->bmm = new QBitmap(mask);
+ d->cshape = Qt::BitmapCursor;
+ d->hx = hotX >= 0 ? hotX : bitmap.width() / 2;
+ d->hy = hotY >= 0 ? hotY : bitmap.height() / 2;
+ return d;
+}
+
+/*
+ * returns an opaque native handle to a cursor.
+ * It happens to be the address of the native handle, as window server handles
+ * are not POD types. Note there is no QCursor(HANDLE) constructor on Symbian,
+ * Mac or QWS.
+ */
+Qt::HANDLE QCursor::handle() const
+{
+ if (d->pcurs.WsHandle())
+ return reinterpret_cast<Qt::HANDLE> (&(d->pcurs));
+
+#ifdef Q_SYMBIAN_HAS_SYSTEM_CURSORS
+ // don't construct shape cursors, QApplication_s60 will use the system cursor instead
+ if (!(d->bm))
+ return 0;
+#endif
+
+ d->pcurs = RWsPointerCursor(S60->wsSession());
+ d->pcurs.Construct(0);
+ d->constructCursorSprite(d->pcurs);
+ d->pcurs.Activate();
+
+ return reinterpret_cast<Qt::HANDLE> (&(d->pcurs));
+}
+
+#ifndef Q_SYMBIAN_HAS_SYSTEM_CURSORS
+/*
+ * Loads a single cursor shape from resources and appends it to a native sprite.
+ * Animated cursors (e.g. the busy cursor) have multiple members.
+ */
+void QCursorData::loadShapeFromResource(RWsSpriteBase& target, QString resource, int hx, int hy, int interval)
+{
+ QPixmap pix;
+ CFbsBitmap* native;
+ QScopedPointer<TSpriteMember> member(new TSpriteMember);
+ member->iInterval = interval;
+ member->iInvertMask = false;
+ member->iMaskBitmap = 0; // all shapes are RGBA
+ member->iDrawMode = CGraphicsContext::EDrawModePEN;
+ member->iOffset = TPoint(-hx, -hy);
+ QString res(QLatin1String(":/trolltech/symbian/cursors/images/%1.png"));
+ pix.load(res.arg(resource));
+ native = pix.toSymbianCFbsBitmap();
+ member->iBitmap = native;
+ qt_symbian_throwIfError(nativeSpriteMembers.Append(member.data()));
+ target.AppendMember(*(member.take()));
+}
+
+//TODO: after 4.6, connect with style & skins?
+/*
+ * Constructs the native cursor from resources compiled into QtGui
+ * This is needed only when the platform doesn't have system cursors.
+ *
+ * System cursors are higher performance, since they are constructed once
+ * and shared by all applications by specifying the shape number.
+ * Due to symbian platform security considerations, and the fact most
+ * existing phones have a broken RWsPointerCursor, system cursors are not
+ * being used.
+ */
+void QCursorData::constructShapeSprite(RWsSpriteBase& target)
+{
+ int i;
+ switch (cshape) {
+ default:
+ qWarning("QCursorData::constructShapeSprite unknown shape %d", cshape);
+ //fall through and give arrow cursor
+ case Qt::ArrowCursor:
+ loadShapeFromResource(target, QLatin1String("pointer"), 1, 1);
+ break;
+ case Qt::UpArrowCursor:
+ loadShapeFromResource(target, QLatin1String("uparrow"), 4, 0);
+ break;
+ case Qt::CrossCursor:
+ loadShapeFromResource(target, QLatin1String("cross"), 7, 7);
+ break;
+ case Qt::WaitCursor:
+ for (i = 1; i <= 12; i++) {
+ loadShapeFromResource(target, QString(QLatin1String("wait%1")).arg(i), 7, 7, 1000000);
+ }
+ break;
+ case Qt::IBeamCursor:
+ loadShapeFromResource(target, QLatin1String("ibeam"), 3, 10);
+ break;
+ case Qt::SizeVerCursor:
+ loadShapeFromResource(target, QLatin1String("sizever"), 4, 8);
+ break;
+ case Qt::SizeHorCursor:
+ loadShapeFromResource(target, QLatin1String("sizehor"), 8, 4);
+ break;
+ case Qt::SizeBDiagCursor:
+ loadShapeFromResource(target, QLatin1String("sizebdiag"), 8, 8);
+ break;
+ case Qt::SizeFDiagCursor:
+ loadShapeFromResource(target, QLatin1String("sizefdiag"), 8, 8);
+ break;
+ case Qt::SizeAllCursor:
+ loadShapeFromResource(target, QLatin1String("sizeall"), 7, 7);
+ break;
+ case Qt::BlankCursor:
+ loadShapeFromResource(target, QLatin1String("blank"), 0, 0);
+ break;
+ case Qt::SplitVCursor:
+ loadShapeFromResource(target, QLatin1String("splitv"), 7, 7);
+ break;
+ case Qt::SplitHCursor:
+ loadShapeFromResource(target, QLatin1String("splith"), 7, 7);
+ break;
+ case Qt::PointingHandCursor:
+ loadShapeFromResource(target, QLatin1String("handpoint"), 5, 0);
+ break;
+ case Qt::ForbiddenCursor:
+ loadShapeFromResource(target, QLatin1String("forbidden"), 7, 7);
+ break;
+ case Qt::WhatsThisCursor:
+ loadShapeFromResource(target, QLatin1String("whatsthis"), 1, 1);
+ break;
+ case Qt::BusyCursor:
+ loadShapeFromResource(target, QLatin1String("busy3"), 1, 1, 1000000);
+ loadShapeFromResource(target, QLatin1String("busy6"), 1, 1, 1000000);
+ loadShapeFromResource(target, QLatin1String("busy9"), 1, 1, 1000000);
+ loadShapeFromResource(target, QLatin1String("busy12"), 1, 1, 1000000);
+ break;
+ case Qt::OpenHandCursor:
+ loadShapeFromResource(target, QLatin1String("openhand"), 7, 7);
+ break;
+ case Qt::ClosedHandCursor:
+ loadShapeFromResource(target, QLatin1String("closehand"), 7, 7);
+ break;
+ }
+}
+#endif
+
+/*
+ * Common code between the sprite workaround and standard modes of operation.
+ * RWsSpriteBase is the base class for both RWsSprite and RWsPointerCursor.
+ * It is called from both handle() and qt_s60_show_pointer_sprite()
+ */
+void QCursorData::constructCursorSprite(RWsSpriteBase& target)
+{
+ int count = nativeSpriteMembers.Count();
+ if (count) {
+ // already constructed
+ for (int i = 0; i < count; i++)
+ target.AppendMember(*(nativeSpriteMembers[i]));
+
+ return;
+ }
+ if (pixmap.isNull() && !bm) {
+#ifndef Q_SYMBIAN_HAS_SYSTEM_CURSORS
+ //shape cursor
+ constructShapeSprite(target);
+#endif
+ return;
+ }
+ QScopedPointer<TSpriteMember> member(new TSpriteMember);
+ if (pixmap.isNull()) {
+ //construct mono cursor
+ member->iBitmap = bm->toSymbianCFbsBitmap();
+ member->iMaskBitmap = bmm->toSymbianCFbsBitmap();
+ }
+ else {
+ //construct normal cursor
+ member->iBitmap = pixmap.toSymbianCFbsBitmap();
+ if (pixmap.hasAlphaChannel()) {
+ member->iMaskBitmap = 0; //use alpha blending
+ }
+ else if (pixmap.hasAlpha()) {
+ member->iMaskBitmap = pixmap.mask().toSymbianCFbsBitmap();
+ }
+ else {
+ member->iMaskBitmap = pixmap.createHeuristicMask().toSymbianCFbsBitmap();
+ }
+ }
+
+ member->iDrawMode = CGraphicsContext::EDrawModePEN;
+ member->iInvertMask = EFalse;
+ member->iInterval = 0;
+ member->iOffset = TPoint(-(hx), -(hy)); //Symbian hotspot coordinates are negative
+ qt_symbian_throwIfError(nativeSpriteMembers.Append(member.data()));
+ target.AppendMember(*(member.take()));
+}
+
+/*
+ * shows the pointer sprite by constructing a native handle, and registering
+ * it with the window server.
+ * Only used when the sprite workaround is in use.
+ */
+void qt_symbian_show_pointer_sprite()
+{
+ if (cursorSprite.d) {
+ if (cursorSprite.d->scurs.WsHandle())
+ cursorSprite.d->scurs.Close();
+ } else {
+ cursorSprite = QCursor(Qt::ArrowCursor);
+ }
+
+ cursorSprite.d->scurs = RWsSprite(S60->wsSession());
+ QPoint pos = QCursor::pos();
+ cursorSprite.d->scurs.Construct(S60->windowGroup(), TPoint(pos.x(), pos.y()), ESpriteNoChildClip | ESpriteNoShadows);
+
+ cursorSprite.d->constructCursorSprite(cursorSprite.d->scurs);
+ cursorSprite.d->scurs.Activate();
+}
+
+/*
+ * hides the pointer sprite by closing the native handle.
+ * Only used when the sprite workaround is in use.
+ */
+void qt_symbian_hide_pointer_sprite()
+{
+ if (cursorSprite.d) {
+ cursorSprite.d->scurs.Close();
+ }
+}
+
+/*
+ * Changes the cursor sprite to the cursor specified.
+ * Only used when the sprite workaround is in use.
+ */
+void qt_symbian_set_pointer_sprite(const QCursor& cursor)
+{
+ if (S60->mouseInteractionEnabled)
+ qt_symbian_hide_pointer_sprite();
+ cursorSprite = cursor;
+ if (S60->mouseInteractionEnabled)
+ qt_symbian_show_pointer_sprite();
+}
+
+/*
+ * When using sprites as a workaround on phones that have a broken
+ * RWsPointerCursor, this function is called in response to pointer events
+ * and when QCursor::setPos() is called.
+ * Performance is worse than a real pointer cursor, due to extra context
+ * switches vs. the window server moving the cursor by itself.
+ */
+void qt_symbian_move_cursor_sprite()
+{
+ if (S60->mouseInteractionEnabled) {
+ cursorSprite.d->scurs.SetPosition(TPoint(S60->lastCursorPos.x(), S60->lastCursorPos.y()));
+ }
+}
+
+/*
+ * Translate from Qt::CursorShape to OS system pointer cursor list index.
+ * Currently we control the implementation of the system pointer cursor list,
+ * so this function is trivial. That may not always be the case.
+ */
+TInt qt_symbian_translate_cursor_shape(Qt::CursorShape shape)
+{
+ return (TInt) shape;
+}
+
+/*
+ Internal function called from QWidget::setCursor()
+ force is true if this function is called from dispatchEnterLeave, it means that the
+ mouse is actually directly under this widget.
+*/
+void qt_symbian_set_cursor(QWidget *w, bool force)
+{
+ static QPointer<QWidget> lastUnderMouse = 0;
+ if (force) {
+ lastUnderMouse = w;
+ }
+ else if (w->testAttribute(Qt::WA_WState_Created) && lastUnderMouse
+ && lastUnderMouse->effectiveWinId() == w->effectiveWinId()) {
+ w = lastUnderMouse;
+ }
+
+ if (!S60->curWin && w && w->internalWinId())
+ return;
+ QWidget* cW = w && !w->internalWinId() ? w : QWidget::find(S60->curWin);
+ if (!cW || cW->window() != w->window() || !cW->isVisible() || !cW->underMouse()
+ || QApplication::overrideCursor())
+ return;
+
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors)
+ qt_symbian_set_pointer_sprite(cW->cursor());
+ else
+#endif
+ qt_symbian_setWindowCursor(cW->cursor(), w->effectiveWinId());
}
+/*
+ * Makes the specified cursor appear above a specific native window group
+ * Called from QSymbianControl and QApplication::restoreOverrideCursor
+ *
+ * Window server is needed for this, so there is no equivalent when using
+ * the sprite workaround.
+ */
+void qt_symbian_setWindowGroupCursor(const QCursor &cursor, RWindowTreeNode &node)
+{
+ Qt::HANDLE handle = cursor.handle();
+ if (handle) {
+ RWsPointerCursor *pcurs = reinterpret_cast<RWsPointerCursor *> (handle);
+ node.SetCustomPointerCursor(*pcurs);
+ }
+#ifdef Q_SYMBIAN_HAS_SYSTEM_CURSORS
+ else {
+ TInt shape = qt_symbian_translate_cursor_shape(cursor.shape());
+ node.SetPointerCursor(shape);
+ }
+#else
+ qWarning("qt_s60_setWindowGroupCursor - null handle");
+#endif
+}
+
+/*
+ * Makes the specified cursor appear above a specific native window
+ * Called from QSymbianControl and QApplication::restoreOverrideCursor
+ *
+ * Window server is needed for this, so there is no equivalent when using
+ * the sprite workaround.
+ */
+void qt_symbian_setWindowCursor(const QCursor &cursor, const CCoeControl* wid)
+{
+ //find the window for this control
+ while (!wid->OwnsWindow()) {
+ wid = wid->Parent();
+ if (!wid)
+ return;
+ }
+ RWindowTreeNode *node = wid->DrawableWindow();
+ qt_symbian_setWindowGroupCursor(cursor, *node);
+}
+
+/*
+ * Makes the specified cursor appear everywhere.
+ * Called from QApplication::setOverrideCursor
+ */
+void qt_symbian_setGlobalCursor(const QCursor &cursor)
+{
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors) {
+ qt_symbian_set_pointer_sprite(cursor);
+ } else
+#endif
+ {
+ //because of the internals of window server, we need to force the cursor
+ //to be set in all child windows too, otherwise when the cursor is over
+ //the child window it may show a widget cursor or arrow cursor instead,
+ //depending on construction order.
+ QListIterator<WId> iter(QWidgetPrivate::mapper->uniqueKeys());
+ while(iter.hasNext())
+ {
+ CCoeControl *ctrl = iter.next();
+ RWindowTreeNode *node = ctrl->DrawableWindow();
+ qt_symbian_setWindowGroupCursor(cursor, *node);
+ }
+ }
+}
QT_END_NAMESPACE
#endif // QT_NO_CURSOR
diff --git a/src/gui/kernel/qcursor_win.cpp b/src/gui/kernel/qcursor_win.cpp
index 430f587..26cde1a 100644
--- a/src/gui/kernel/qcursor_win.cpp
+++ b/src/gui/kernel/qcursor_win.cpp
@@ -50,8 +50,6 @@
QT_BEGIN_NAMESPACE
-extern QCursorData *qt_cursorTable[Qt::LastCursor + 1]; // qcursor.cpp
-
/*****************************************************************************
Internal QCursorData class
*****************************************************************************/
diff --git a/src/gui/kernel/qcursor_x11.cpp b/src/gui/kernel/qcursor_x11.cpp
index d8cc2fc..3e53f04 100644
--- a/src/gui/kernel/qcursor_x11.cpp
+++ b/src/gui/kernel/qcursor_x11.cpp
@@ -63,8 +63,6 @@ QT_BEGIN_NAMESPACE
// Define QT_USE_APPROXIMATE_CURSORS when compiling if you REALLY want to
// use the ugly X11 cursors.
-extern QCursorData *qt_cursorTable[Qt::LastCursor + 1]; // qcursor.cpp
-
/*****************************************************************************
Internal QCursorData class
*****************************************************************************/
@@ -100,6 +98,7 @@ QCursor::QCursor(Qt::HANDLE cursor)
d = new QCursorData(Qt::CustomCursor);
d->hcurs = cursor;
}
+
#endif
QCursorData *QCursorData::setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY)
diff --git a/src/gui/kernel/qdnd_p.h b/src/gui/kernel/qdnd_p.h
index 4ee484c..b635685 100644
--- a/src/gui/kernel/qdnd_p.h
+++ b/src/gui/kernel/qdnd_p.h
@@ -58,6 +58,7 @@
#include "QtGui/qmime.h"
#include "QtGui/qdrag.h"
#include "QtGui/qpixmap.h"
+#include "QtGui/qcursor.h"
#include "QtCore/qpoint.h"
#include "private/qobject_p.h"
#ifdef Q_WS_MAC
@@ -265,7 +266,11 @@ private:
#ifdef Q_WS_QWS
Qt::DropAction currentActionForOverrideCursor;
#endif
-
+#ifdef Q_OS_SYMBIAN
+#ifndef QT_NO_CURSOR
+ QCursor overrideCursor;
+#endif
+#endif
QWidget *currentDropTarget;
static QDragManager *instance;
diff --git a/src/gui/kernel/qdnd_s60.cpp b/src/gui/kernel/qdnd_s60.cpp
index fb2e426..2456185 100644
--- a/src/gui/kernel/qdnd_s60.cpp
+++ b/src/gui/kernel/qdnd_s60.cpp
@@ -50,11 +50,14 @@
#include "qevent.h"
#include "qpainter.h"
#include "qdnd_p.h"
+#include "qt_s60_p.h"
#include <COECNTRL.H>
// pointer cursor
#include <w32std.h>
#include <gdi.h>
+#include <QCursor>
+
QT_BEGIN_NAMESPACE
//### artistic impression of Symbians default DnD cursor ?
@@ -89,82 +92,24 @@ static bool qt_symbian_dnd_dragging = false;
static Qt::KeyboardModifiers oldstate;
-class QShapedPixmapWidget
-{
-public:
- QShapedPixmapWidget(RWsSession aWsSession,RWindowTreeNode* aNode)
- {
- sprite = RWsSprite(aWsSession);
- cursorSprite.iBitmap = 0;
- cursorSprite.iMaskBitmap = 0;
- cursorSprite.iInvertMask = EFalse;
- cursorSprite.iOffset = TPoint(0,0);
- cursorSprite.iInterval = TTimeIntervalMicroSeconds32(0);
- cursorSprite.iDrawMode = CGraphicsContext::EDrawModePEN;
- sprite.Construct(*aNode,TPoint(0,0), ESpriteNoShadows | ESpriteNoChildClip);
- sprite.AppendMember(cursorSprite);
- sprite.Activate();
- }
- ~QShapedPixmapWidget()
- {
- sprite.Close();
- cursorSprite.iBitmap = 0;
- delete cursorBitmap;
- cursorBitmap = 0; //redundant...
- }
- void disableCursor()
- {
- cursorSprite.iBitmap = 0;
- sprite.UpdateMember(0,cursorSprite);
- }
- void enableCursor()
- {
- cursorSprite.iBitmap = cursorBitmap;
- sprite.UpdateMember(0,cursorSprite);
- }
- void setPixmap(QPixmap pm)
- {
- //### heaplock centralized.
- QImage temp = pm.toImage();
- QSize size = pm.size();
- temp.bits();
- CFbsBitmap *curbm = q_check_ptr(new CFbsBitmap()); // CBase derived object needs check on new
- curbm->Create(TSize(size.width(),size.height()),EColor16MA);
- curbm->LockHeap(ETrue);
- memcpy((uchar*)curbm->DataAddress(),temp.bits(),temp.numBytes());
- curbm->UnlockHeap(ETrue);
- delete cursorSprite.iBitmap;
- cursorSprite.iBitmap = curbm;
- cursorBitmap = curbm;
- sprite.UpdateMember(0,cursorSprite);
- }
- CFbsBitmap *cursorBitmap;
- RWsPointerCursor pointerCursor;
- RWsSprite sprite;
- TSpriteMember cursorSprite;
-
-};
-
-
-static QShapedPixmapWidget *qt_symbian_dnd_deco = 0;
-
void QDragManager::updatePixmap()
{
- if (qt_symbian_dnd_deco) {
- QPixmap pm;
- QPoint pm_hot(default_pm_hotx,default_pm_hoty);
- if (drag_object) {
- pm = drag_object->pixmap();
- if (!pm.isNull())
- pm_hot = drag_object->hotSpot();
- }
- if (pm.isNull()) {
- if (!defaultPm)
- defaultPm = new QPixmap(default_pm);
- pm = *defaultPm;
- }
- qt_symbian_dnd_deco->setPixmap(pm);
+ QPixmap pm;
+ QPoint pm_hot(default_pm_hotx,default_pm_hoty);
+ if (drag_object) {
+ pm = drag_object->pixmap();
+ if (!pm.isNull())
+ pm_hot = drag_object->hotSpot();
+ }
+ if (pm.isNull()) {
+ if (!defaultPm)
+ defaultPm = new QPixmap(default_pm);
+ pm = *defaultPm;
}
+#ifndef QT_NO_CURSOR
+ QCursor cursor(pm, pm_hot.x(), pm_hot.y());
+ overrideCursor = cursor;
+#endif
}
void QDragManager::timerEvent(QTimerEvent *) { }
@@ -174,6 +119,16 @@ void QDragManager::move(const QPoint&) {
void QDragManager::updateCursor()
{
+#ifndef QT_NO_CURSOR
+ QCursor cursor = willDrop ? overrideCursor : Qt::ForbiddenCursor;
+ if (!restoreCursor) {
+ QApplication::setOverrideCursor(cursor);
+ restoreCursor = true;
+ }
+ else {
+ QApplication::changeOverrideCursor(cursor);
+ }
+#endif
}
@@ -210,20 +165,19 @@ bool QDragManager::eventFilter(QObject *o, QEvent *e)
// map the Coords relative to the window.
if (!cw)
return true;
- TPoint windowPos = cw->effectiveWinId()->PositionRelativeToScreen();
- qt_symbian_dnd_deco->sprite.SetPosition(TPoint(me->globalX()- windowPos.iX,me->globalY()- windowPos.iY));
while (cw && !cw->acceptDrops() && !cw->isWindow())
cw = cw->parentWidget();
+ bool oldWillDrop = willDrop;
if (object->target() != cw) {
if (object->target()) {
QDragLeaveEvent dle;
QApplication::sendEvent(object->target(), &dle);
willDrop = false;
global_accepted_action = Qt::IgnoreAction;
- updateCursor();
- restoreCursor = true;
+ if (oldWillDrop != willDrop)
+ updateCursor();
object->d_func()->target = 0;
}
if (cw && cw->acceptDrops()) {
@@ -233,8 +187,8 @@ bool QDragManager::eventFilter(QObject *o, QEvent *e)
QApplication::sendEvent(object->target(), &dee);
willDrop = dee.isAccepted() && dee.dropAction() != Qt::IgnoreAction;
global_accepted_action = willDrop ? dee.dropAction() : Qt::IgnoreAction;
- updateCursor();
- restoreCursor = true;
+ if (oldWillDrop != willDrop)
+ updateCursor();
}
} else if (cw) {
QDragMoveEvent dme(cw->mapFromGlobal(me->globalPos()), possible_actions, dropData,
@@ -246,8 +200,10 @@ bool QDragManager::eventFilter(QObject *o, QEvent *e)
QApplication::sendEvent(cw, &dme);
willDrop = dme.isAccepted();
global_accepted_action = willDrop ? dme.dropAction() : Qt::IgnoreAction;
- updatePixmap();
- updateCursor();
+ if (oldWillDrop != willDrop) {
+ updatePixmap();
+ updateCursor();
+ }
}
if (global_accepted_action != prevAction)
emitActionChanged(global_accepted_action);
@@ -259,7 +215,7 @@ bool QDragManager::eventFilter(QObject *o, QEvent *e)
{
qApp->removeEventFilter(this);
if (restoreCursor) {
- qt_symbian_dnd_deco->disableCursor();
+ QApplication::restoreOverrideCursor();
willDrop = false;
restoreCursor = false;
}
@@ -305,23 +261,15 @@ Qt::DropAction QDragManager::drag(QDrag *o)
}
object = drag_object = o;
- RWsSession winSession = o->source()->effectiveWinId()->ControlEnv()->WsSession();
- Q_ASSERT(!qt_symbian_dnd_deco);
- qt_symbian_dnd_deco = new QShapedPixmapWidget(winSession, o->source()->effectiveWinId()->DrawableWindow());
oldstate = Qt::NoModifier; // #### Should use state that caused the drag
willDrop = false;
updatePixmap();
updateCursor();
- restoreCursor = true;
- object->d_func()->target = 0;
- TPoint windowPos = source()->effectiveWinId()->PositionRelativeToScreen();
- qt_symbian_dnd_deco->sprite.SetPosition(TPoint(QCursor::pos().x()- windowPos.iX ,QCursor::pos().y() - windowPos.iY));
+ qt_symbian_set_cursor_visible(true); //force cursor on even for touch phone
- QPoint hotspot = drag_object->hotSpot();
- qt_symbian_dnd_deco->cursorSprite.iOffset = TPoint(- hotspot.x(),- hotspot.y());
- qt_symbian_dnd_deco->sprite.UpdateMember(0,qt_symbian_dnd_deco->cursorSprite);
+ object->d_func()->target = 0;
qApp->installEventFilter(this);
@@ -334,11 +282,11 @@ Qt::DropAction QDragManager::drag(QDrag *o)
delete eventLoop;
eventLoop = 0;
- delete qt_symbian_dnd_deco;
- qt_symbian_dnd_deco = 0;
+ qt_symbian_set_cursor_visible(false);
+
+ overrideCursor = QCursor(); //deref the cursor data
qt_symbian_dnd_dragging = false;
-
return global_accepted_action;
}
@@ -358,8 +306,10 @@ void QDragManager::cancel(bool deleteSource)
drag_object = object = 0;
}
- delete qt_symbian_dnd_deco;
- qt_symbian_dnd_deco = 0;
+ if (restoreCursor) {
+ QApplication::restoreOverrideCursor();
+ restoreCursor = false;
+ }
global_accepted_action = Qt::IgnoreAction;
}
@@ -367,6 +317,10 @@ void QDragManager::cancel(bool deleteSource)
void QDragManager::drop()
{
+ if (restoreCursor) {
+ QApplication::restoreOverrideCursor();
+ restoreCursor = false;
+ }
}
QVariant QDropData::retrieveData_sys(const QString &mimetype, QVariant::Type type) const
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index 2530f38..aec757f 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -145,7 +145,7 @@ static int qtkeyForMacSymbol(const QChar ch)
#else
static bool qt_sequence_no_mnemonics = false;
#endif
-void Q_AUTOTEST_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemonics = !b; }
+void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemonics = !b; }
/*!
\class QKeySequence
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm
index d27c775..2b2259c 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac.mm
+++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm
@@ -876,6 +876,10 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev
QWidget *widgetToGetMouse = qwidget;
QWidget *popup = qAppInstance()->activePopupWidget();
NSView *tmpView = theView;
+ if (mac_mouse_grabber && mac_mouse_grabber != widgetToGetMouse) {
+ widgetToGetMouse = mac_mouse_grabber;
+ tmpView = qt_mac_nativeview_for(widgetToGetMouse);
+ }
if (popup && popup != qwidget->window()) {
widgetToGetMouse = popup;
diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
index d85023b..794d15a 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/gui/kernel/qt_s60_p.h
@@ -83,6 +83,7 @@ const TInt KInternalStatusPaneChange = 0x50000000;
class QS60Data
{
public:
+ QS60Data();
TUid uid;
int screenDepth;
QPoint lastCursorPos;
@@ -95,6 +96,16 @@ public:
int screenHeightInTwips;
int defaultDpiX;
int defaultDpiY;
+ WId curWin;
+ int virtualMouseLastKey;
+ int virtualMouseAccel;
+ int virtualMouseMaxAccel;
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ bool brokenPointerCursors;
+#endif
+ bool hasTouchscreen;
+ bool mouseInteractionEnabled;
+ bool virtualMouseRequired;
int qtOwnsS60Environment : 1;
static inline void updateScreenSize();
static inline RWsSession& wsSession();
@@ -164,6 +175,11 @@ private:
bool m_previousEventLongTap;
};
+inline QS60Data::QS60Data()
+{
+ memclr(this, sizeof(QS60Data)); //zero init data
+}
+
inline void QS60Data::updateScreenSize()
{
TPixelsTwipsAndRotation params;
@@ -173,6 +189,8 @@ inline void QS60Data::updateScreenSize()
S60->screenHeightInPixels = params.iPixelSize.iHeight;
S60->screenWidthInTwips = params.iTwipsSize.iWidth;
S60->screenHeightInTwips = params.iTwipsSize.iHeight;
+
+ S60->virtualMouseMaxAccel = qMax(S60->screenHeightInPixels, S60->screenWidthInPixels) / 20;
TReal inches = S60->screenHeightInTwips / (TReal)KTwipsPerInch;
S60->defaultDpiY = S60->screenHeightInPixels / inches;
@@ -286,6 +304,11 @@ static inline QImage::Format qt_TDisplayMode2Format(TDisplayMode mode)
return format;
}
+void qt_symbian_setWindowCursor(const QCursor &cursor, const CCoeControl* wid);
+void qt_symbian_setWindowGroupCursor(const QCursor &cursor, RWindowTreeNode &node);
+void qt_symbian_setGlobalCursor(const QCursor &cursor);
+void qt_symbian_set_cursor_visible(bool visible);
+bool qt_symbian_is_cursor_visible();
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index fd89cb9..c86012d 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -3048,7 +3048,6 @@ void QWidgetPrivate::setEnabled_helper(bool enable)
if (q->testAttribute(Qt::WA_SetCursor) || q->isWindow()) {
// enforce the windows behavior of clearing the cursor on
// disabled widgets
- extern void qt_x11_enforce_cursor(QWidget * w); // defined in qwidget_x11.cpp
qt_x11_enforce_cursor(q);
}
#endif
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index 744d20f..522ce33 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -188,7 +188,7 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
if (isResize)
data.window_state &= ~Qt::WindowMaximized;
- if(q->isWindow()) {
+ if (q->isWindow()) {
if (w == 0 || h == 0) {
q->setAttribute(Qt::WA_OutsideWSRange, true);
if (q->isVisible() && q->testAttribute(Qt::WA_Mapped))
@@ -287,7 +287,7 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de
TSize screenSize = S60->screenDevice()->SizeInPixels();
data.crect.setRect(0, 0, screenSize.iWidth, screenSize.iHeight);
q->setAttribute(Qt::WA_DontShowOnScreen);
- } else if(topLevel && !q->testAttribute(Qt::WA_Resized)){
+ } else if (topLevel && !q->testAttribute(Qt::WA_Resized)){
int width = sw;
int height = sh;
if (extra) {
@@ -300,7 +300,7 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de
CCoeControl *destroyw = 0;
createExtra();
- if(window) {
+ if (window) {
if (destroyOldWindow)
destroyw = data.winid;
id = window;
@@ -416,7 +416,7 @@ void QWidgetPrivate::hide_sys()
deactivateWidgetCleanup();
WId id = q->internalWinId();
if (q->isWindow() && id) {
- if(id->IsFocused()) // Avoid unnecessary calls to FocusChanged()
+ if (id->IsFocused()) // Avoid unnecessary calls to FocusChanged()
id->SetFocus(false);
id->MakeVisible(false);
if (QWidgetBackingStore *bs = maybeBackingStore())
@@ -432,7 +432,7 @@ void QWidgetPrivate::setFocus_sys()
{
Q_Q(QWidget);
if (q->testAttribute(Qt::WA_WState_Created) && q->window()->windowType() != Qt::Popup)
- if(!q->effectiveWinId()->IsFocused()) // Avoid unnecessry calls to FocusChanged()
+ if (!q->effectiveWinId()->IsFocused()) // Avoid unnecessry calls to FocusChanged()
q->effectiveWinId()->SetFocus(true);
}
@@ -482,7 +482,7 @@ void QWidgetPrivate::lower_sys()
if (q->internalWinId() && tlwExtra) {
tlwExtra->rwindow->SetOrdinalPosition(-1);
}
- if(!q->isWindow())
+ if (!q->isWindow())
invalidateBuffer(q->rect());
}
@@ -499,7 +499,7 @@ void QWidgetPrivate::stackUnder_sys(QWidget* w)
QTLWExtra *tlwExtraSibling = w->d_func()->maybeTopData();
if (q->internalWinId() && tlwExtra && w->internalWinId() && tlwExtraSibling)
tlwExtra->rwindow->SetOrdinalPosition(tlwExtraSibling->rwindow->OrdinalPosition() + 1);
- if(!q->isWindow() || !w->internalWinId())
+ if (!q->isWindow() || !w->internalWinId())
invalidateBuffer(q->rect());
}
@@ -553,7 +553,7 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
// destroyed when emitting the child remove event below. See QWorkspace.
if (wasCreated && old_winid) {
old_winid->MakeVisible(false);
- if(old_winid->IsFocused()) // Avoid unnecessary calls to FocusChanged()
+ if (old_winid->IsFocused()) // Avoid unnecessary calls to FocusChanged()
old_winid->SetFocus(false);
old_winid->SetParent(0);
}
@@ -660,7 +660,7 @@ CFbsBitmap* qt_pixmapToNativeBitmap(QPixmap pixmap, bool invert)
fbsBitmap->LockHeap();
QImage image = pixmap.toImage();
- if(invert)
+ if (invert)
image.invertPixels();
int height = pixmap.size().height();
@@ -764,8 +764,8 @@ void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
if (q->isWindow()) {
Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
CAknTitlePane* titlePane = S60->titlePane();
- if(titlePane) {
- if(caption.isEmpty()) {
+ if (titlePane) {
+ if (caption.isEmpty()) {
QT_TRAP_THROWING(titlePane->SetTextToDefaultL());
} else {
QT_TRAP_THROWING(titlePane->SetTextL(qt_QString2TPtrC(caption)));
@@ -996,7 +996,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
// The window decoration visibility has to be changed before doing actual
// window state change since in that order the availableGeometry will return
// directly the right size and we will avoid unnecessarty redraws
- if((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen) ||
+ if ((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen) ||
oldstate == Qt::WindowNoState) {
CEikStatusPane* statusPane = S60->statusPane();
CEikButtonGroupContainer* buttonGroup = S60->buttonGroupContainer();
@@ -1061,7 +1061,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
if (newstate & Qt::WindowMinimized) {
if (isVisible()) {
WId id = effectiveWinId();
- if(id->IsFocused()) // Avoid unnecessary calls to FocusChanged()
+ if (id->IsFocused()) // Avoid unnecessary calls to FocusChanged()
id->SetFocus(false);
id->MakeVisible(false);
}
@@ -1069,7 +1069,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
if (isVisible()) {
WId id = effectiveWinId();
id->MakeVisible(true);
- if(!id->IsFocused()) // Avoid unnecessary calls to FocusChanged()
+ if (!id->IsFocused()) // Avoid unnecessary calls to FocusChanged()
id->SetFocus(true);
}
const QRect normalGeometry = geometry();
@@ -1111,6 +1111,10 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
}
#endif
+ if (QWidgetPrivate::mouseGrabber == this)
+ releaseMouse();
+ if (QWidgetPrivate::keyboardGrabber == this)
+ releaseKeyboard();
setAttribute(Qt::WA_WState_Created, false);
QObjectList childList = children();
for (int i = 0; i < childList.size(); ++i) { // destroy all widget children
@@ -1119,12 +1123,8 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
static_cast<QWidget*>(obj)->destroy(destroySubWindows,
destroySubWindows);
}
- if (QWidgetPrivate::mouseGrabber == this)
- releaseMouse();
- if (QWidgetPrivate::keyboardGrabber == this)
- releaseKeyboard();
if (destroyWindow && !(windowType() == Qt::Desktop) && id) {
- if(id->IsFocused()) // Avoid unnecessry calls to FocusChanged()
+ if (id->IsFocused()) // Avoid unnecessry calls to FocusChanged()
id->SetFocus(false);
id->ControlEnv()->AppUi()->RemoveFromStack(id);
@@ -1192,8 +1192,28 @@ void QWidget::grabMouse()
WId id = effectiveWinId();
id->SetPointerCapture(true);
QWidgetPrivate::mouseGrabber = this;
+
+#ifndef QT_NO_CURSOR
+ QApplication::setOverrideCursor(cursor());
+#endif
+ }
+}
+
+#ifndef QT_NO_CURSOR
+void QWidget::grabMouse(const QCursor &cursor)
+{
+ if (!qt_nograb()) {
+ if (QWidgetPrivate::mouseGrabber && QWidgetPrivate::mouseGrabber != this)
+ QWidgetPrivate::mouseGrabber->releaseMouse();
+ Q_ASSERT(testAttribute(Qt::WA_WState_Created));
+ WId id = effectiveWinId();
+ id->SetPointerCapture(true);
+ QWidgetPrivate::mouseGrabber = this;
+
+ QApplication::setOverrideCursor(cursor);
}
}
+#endif
void QWidget::releaseMouse()
{
@@ -1202,6 +1222,8 @@ void QWidget::releaseMouse()
WId id = effectiveWinId();
id->SetPointerCapture(false);
QWidgetPrivate::mouseGrabber = 0;
+
+ QApplication::restoreOverrideCursor();
}
}
@@ -1215,4 +1237,21 @@ void QWidget::activateWindow()
id->SetFocus(true);
}
}
+
+#ifndef QT_NO_CURSOR
+
+void QWidgetPrivate::setCursor_sys(const QCursor &cursor)
+{
+ Q_UNUSED(cursor);
+ Q_Q(QWidget);
+ qt_symbian_set_cursor(q, false);
+}
+
+void QWidgetPrivate::unsetCursor_sys()
+{
+ Q_Q(QWidget);
+ qt_symbian_set_cursor(q, false);
+}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp
index c9ebccf..211e9d4 100644
--- a/src/gui/kernel/qwidget_win.cpp
+++ b/src/gui/kernel/qwidget_win.cpp
@@ -722,8 +722,6 @@ QPoint QWidget::mapFromGlobal(const QPoint &pos) const
void QWidgetPrivate::updateSystemBackground() {}
-extern void qt_win_set_cursor(QWidget *, bool); // qapplication_win.cpp
-
#ifndef QT_NO_CURSOR
void QWidgetPrivate::setCursor_sys(const QCursor &cursor)
{
diff --git a/src/gui/kernel/symbian.pri b/src/gui/kernel/symbian.pri
index d267a53..5497ccb 100644
--- a/src/gui/kernel/symbian.pri
+++ b/src/gui/kernel/symbian.pri
@@ -1,3 +1,4 @@
symbian {
contains(QT_CONFIG, s60): LIBS+= $$QMAKE_LIBS_S60
+ RESOURCES += symbian/symbianresources.qrc
}
diff --git a/src/gui/painting/qdrawutil.cpp b/src/gui/painting/qdrawutil.cpp
index 17cf196..c4a9373 100644
--- a/src/gui/painting/qdrawutil.cpp
+++ b/src/gui/painting/qdrawutil.cpp
@@ -49,10 +49,17 @@
QT_BEGIN_NAMESPACE
/*!
+ \headerfile <qdrawutil.h>
+ \title Drawing Utility Functions
+
+ \sa QPainter
+*/
+
+/*!
\fn void qDrawShadeLine(QPainter *painter, int x1, int y1, int x2, int y2,
const QPalette &palette, bool sunken,
int lineWidth, int midLineWidth)
- \relates QPainter
+ \relates <qdrawutil.h>
Draws a horizontal (\a y1 == \a y2) or vertical (\a x1 == \a x2)
shaded line using the given \a painter. Note that nothing is
@@ -166,7 +173,7 @@ void qDrawShadeLine(QPainter *p, int x1, int y1, int x2, int y2,
const QPalette &palette, bool sunken,
int lineWidth, int midLineWidth,
const QBrush *fill)
- \relates QPainter
+ \relates <qdrawutil.h>
Draws the shaded rectangle beginning at (\a x, \a y) with the
given \a width and \a height using the provided \a painter.
@@ -270,7 +277,7 @@ void qDrawShadeRect(QPainter *p, int x, int y, int w, int h,
\fn void qDrawShadePanel(QPainter *painter, int x, int y, int width, int height,
const QPalette &palette, bool sunken,
int lineWidth, const QBrush *fill)
- \relates QPainter
+ \relates <qdrawutil.h>
Draws the shaded panel beginning at (\a x, \a y) with the given \a
width and \a height using the provided \a painter and the given \a
@@ -406,7 +413,7 @@ static void qDrawWinShades(QPainter *p,
\fn void qDrawWinButton(QPainter *painter, int x, int y, int width, int height,
const QPalette &palette, bool sunken,
const QBrush *fill)
- \relates QPainter
+ \relates <qdrawutil.h>
Draws the Windows-style button specified by the given point (\a x,
\a y}, \a width and \a height using the provided \a painter with a
@@ -444,7 +451,7 @@ void qDrawWinButton(QPainter *p, int x, int y, int w, int h,
\fn void qDrawWinPanel(QPainter *painter, int x, int y, int width, int height,
const QPalette &palette, bool sunken,
const QBrush *fill)
- \relates QPainter
+ \relates <qdrawutil.h>
Draws the Windows-style panel specified by the given point(\a x,
\a y), \a width and \a height using the provided \a painter with a
@@ -483,7 +490,7 @@ void qDrawWinPanel(QPainter *p, int x, int y, int w, int h,
/*!
\fn void qDrawPlainRect(QPainter *painter, int x, int y, int width, int height, const QColor &lineColor,
int lineWidth, const QBrush *fill)
- \relates QPainter
+ \relates <qdrawutil.h>
Draws the plain rectangle beginning at (\a x, \a y) with the given
\a width and \a height, using the specified \a painter, \a lineColor
@@ -532,7 +539,7 @@ void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &c,
/*!
\fn void qDrawShadeLine(QPainter *painter, const QPoint &p1, const QPoint &p2,
const QPalette &palette, bool sunken, int lineWidth, int midLineWidth)
- \relates QPainter
+ \relates <qdrawutil.h>
\overload
Draws a horizontal or vertical shaded line between \a p1 and \a p2
@@ -572,7 +579,7 @@ void qDrawShadeLine(QPainter *p, const QPoint &p1, const QPoint &p2,
/*!
\fn void qDrawShadeRect(QPainter *painter, const QRect &rect, const QPalette &palette,
bool sunken, int lineWidth, int midLineWidth, const QBrush *fill)
- \relates QPainter
+ \relates <qdrawutil.h>
\overload
Draws the shaded rectangle specified by \a rect using the given \a painter.
@@ -612,7 +619,7 @@ void qDrawShadeRect(QPainter *p, const QRect &r,
/*!
\fn void qDrawShadePanel(QPainter *painter, const QRect &rect, const QPalette &palette,
bool sunken, int lineWidth, const QBrush *fill)
- \relates QPainter
+ \relates <qdrawutil.h>
\overload
Draws the shaded panel at the rectangle specified by \a rect using the
@@ -648,7 +655,7 @@ void qDrawShadePanel(QPainter *p, const QRect &r,
/*!
\fn void qDrawWinButton(QPainter *painter, const QRect &rect, const QPalette &palette,
bool sunken, const QBrush *fill)
- \relates QPainter
+ \relates <qdrawutil.h>
\overload
Draws the Windows-style button at the rectangle specified by \a rect using
@@ -706,7 +713,7 @@ void qDrawWinPanel(QPainter *p, const QRect &r,
/*!
\fn void qDrawPlainRect(QPainter *painter, const QRect &rect, const QColor &lineColor, int lineWidth, const QBrush *fill)
- \relates QPainter
+ \relates <qdrawutil.h>
\overload
Draws the plain rectangle specified by \a rect using the given \a painter,
@@ -1060,7 +1067,7 @@ void qDrawItem(QPainter *p, Qt::GUIStyle gs,
/*!
\fn void qDrawBorderPixmap(QPainter *painter, const QRect &target, const QMargins &margins, const QPixmap &pixmap)
\since 4.6
- \relates QMargins
+ \relates <qdrawutil.h>
Draws the given \a pixmap into the given \a target rectangle, using the
given \a painter. The pixmap will be split into nine segments and drawn
diff --git a/src/gui/painting/qdrawutil.h b/src/gui/painting/qdrawutil.h
index ce89e22..3a2dd0e 100644
--- a/src/gui/painting/qdrawutil.h
+++ b/src/gui/painting/qdrawutil.h
@@ -135,7 +135,7 @@ Q_GUI_EXPORT QT3_SUPPORT void qDrawArrow(QPainter *p, Qt::ArrowType type, Qt::GU
struct QTileRules
{
- inline QTileRules(Qt::TileRule horizontalRule, Qt::TileRule verticalRule = Qt::Stretch)
+ inline QTileRules(Qt::TileRule horizontalRule, Qt::TileRule verticalRule)
: horizontal(horizontalRule), vertical(verticalRule) {}
inline QTileRules(Qt::TileRule rule = Qt::Stretch)
: horizontal(rule), vertical(rule) {}
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index beda9d6..b3aef71 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -1317,7 +1317,8 @@ void QPainterPrivate::updateState(QPainterState *newState)
Another workaround is to convert the paths to polygons first and then draw the
polygons instead.
- \sa QPaintDevice, QPaintEngine, {QtSvg Module}, {Basic Drawing Example}
+ \sa QPaintDevice, QPaintEngine, {QtSvg Module}, {Basic Drawing Example},
+ {Drawing Utility Functions}
*/
/*!
diff --git a/src/gui/symbian/images/blank.png b/src/gui/symbian/images/blank.png
new file mode 100644
index 0000000..bd396de
--- /dev/null
+++ b/src/gui/symbian/images/blank.png
Binary files differ
diff --git a/src/gui/symbian/images/busy12.png b/src/gui/symbian/images/busy12.png
new file mode 100644
index 0000000..909e70f
--- /dev/null
+++ b/src/gui/symbian/images/busy12.png
Binary files differ
diff --git a/src/gui/symbian/images/busy3.png b/src/gui/symbian/images/busy3.png
new file mode 100644
index 0000000..983f5d8
--- /dev/null
+++ b/src/gui/symbian/images/busy3.png
Binary files differ
diff --git a/src/gui/symbian/images/busy6.png b/src/gui/symbian/images/busy6.png
new file mode 100644
index 0000000..b2e8780
--- /dev/null
+++ b/src/gui/symbian/images/busy6.png
Binary files differ
diff --git a/src/gui/symbian/images/busy9.png b/src/gui/symbian/images/busy9.png
new file mode 100644
index 0000000..e093d01
--- /dev/null
+++ b/src/gui/symbian/images/busy9.png
Binary files differ
diff --git a/src/gui/symbian/images/closehand.png b/src/gui/symbian/images/closehand.png
new file mode 100644
index 0000000..05534f5
--- /dev/null
+++ b/src/gui/symbian/images/closehand.png
Binary files differ
diff --git a/src/gui/symbian/images/cross.png b/src/gui/symbian/images/cross.png
new file mode 100644
index 0000000..50da7aa
--- /dev/null
+++ b/src/gui/symbian/images/cross.png
Binary files differ
diff --git a/src/gui/symbian/images/forbidden.png b/src/gui/symbian/images/forbidden.png
new file mode 100644
index 0000000..a3a0fd6
--- /dev/null
+++ b/src/gui/symbian/images/forbidden.png
Binary files differ
diff --git a/src/gui/symbian/images/handpoint.png b/src/gui/symbian/images/handpoint.png
new file mode 100644
index 0000000..a221548
--- /dev/null
+++ b/src/gui/symbian/images/handpoint.png
Binary files differ
diff --git a/src/gui/symbian/images/ibeam.png b/src/gui/symbian/images/ibeam.png
new file mode 100644
index 0000000..ace2fad
--- /dev/null
+++ b/src/gui/symbian/images/ibeam.png
Binary files differ
diff --git a/src/gui/symbian/images/openhand.png b/src/gui/symbian/images/openhand.png
new file mode 100644
index 0000000..6f232f0
--- /dev/null
+++ b/src/gui/symbian/images/openhand.png
Binary files differ
diff --git a/src/gui/symbian/images/pointer.png b/src/gui/symbian/images/pointer.png
new file mode 100644
index 0000000..677404e
--- /dev/null
+++ b/src/gui/symbian/images/pointer.png
Binary files differ
diff --git a/src/gui/symbian/images/sizeall.png b/src/gui/symbian/images/sizeall.png
new file mode 100644
index 0000000..2950067
--- /dev/null
+++ b/src/gui/symbian/images/sizeall.png
Binary files differ
diff --git a/src/gui/symbian/images/sizebdiag.png b/src/gui/symbian/images/sizebdiag.png
new file mode 100644
index 0000000..f565a3a
--- /dev/null
+++ b/src/gui/symbian/images/sizebdiag.png
Binary files differ
diff --git a/src/gui/symbian/images/sizefdiag.png b/src/gui/symbian/images/sizefdiag.png
new file mode 100644
index 0000000..9493f12
--- /dev/null
+++ b/src/gui/symbian/images/sizefdiag.png
Binary files differ
diff --git a/src/gui/symbian/images/sizehor.png b/src/gui/symbian/images/sizehor.png
new file mode 100644
index 0000000..217bf39
--- /dev/null
+++ b/src/gui/symbian/images/sizehor.png
Binary files differ
diff --git a/src/gui/symbian/images/sizever.png b/src/gui/symbian/images/sizever.png
new file mode 100644
index 0000000..2c99038
--- /dev/null
+++ b/src/gui/symbian/images/sizever.png
Binary files differ
diff --git a/src/gui/symbian/images/splith.png b/src/gui/symbian/images/splith.png
new file mode 100644
index 0000000..343bed5
--- /dev/null
+++ b/src/gui/symbian/images/splith.png
Binary files differ
diff --git a/src/gui/symbian/images/splitv.png b/src/gui/symbian/images/splitv.png
new file mode 100644
index 0000000..69ee416
--- /dev/null
+++ b/src/gui/symbian/images/splitv.png
Binary files differ
diff --git a/src/gui/symbian/images/uparrow.png b/src/gui/symbian/images/uparrow.png
new file mode 100644
index 0000000..92dd933
--- /dev/null
+++ b/src/gui/symbian/images/uparrow.png
Binary files differ
diff --git a/src/gui/symbian/images/wait1.png b/src/gui/symbian/images/wait1.png
new file mode 100644
index 0000000..5aebaab
--- /dev/null
+++ b/src/gui/symbian/images/wait1.png
Binary files differ
diff --git a/src/gui/symbian/images/wait10.png b/src/gui/symbian/images/wait10.png
new file mode 100644
index 0000000..3b549b0
--- /dev/null
+++ b/src/gui/symbian/images/wait10.png
Binary files differ
diff --git a/src/gui/symbian/images/wait11.png b/src/gui/symbian/images/wait11.png
new file mode 100644
index 0000000..24a943f
--- /dev/null
+++ b/src/gui/symbian/images/wait11.png
Binary files differ
diff --git a/src/gui/symbian/images/wait12.png b/src/gui/symbian/images/wait12.png
new file mode 100644
index 0000000..15afd4d
--- /dev/null
+++ b/src/gui/symbian/images/wait12.png
Binary files differ
diff --git a/src/gui/symbian/images/wait2.png b/src/gui/symbian/images/wait2.png
new file mode 100644
index 0000000..f2022b2
--- /dev/null
+++ b/src/gui/symbian/images/wait2.png
Binary files differ
diff --git a/src/gui/symbian/images/wait3.png b/src/gui/symbian/images/wait3.png
new file mode 100644
index 0000000..5b73e57
--- /dev/null
+++ b/src/gui/symbian/images/wait3.png
Binary files differ
diff --git a/src/gui/symbian/images/wait4.png b/src/gui/symbian/images/wait4.png
new file mode 100644
index 0000000..17a0339
--- /dev/null
+++ b/src/gui/symbian/images/wait4.png
Binary files differ
diff --git a/src/gui/symbian/images/wait5.png b/src/gui/symbian/images/wait5.png
new file mode 100644
index 0000000..16a5c23
--- /dev/null
+++ b/src/gui/symbian/images/wait5.png
Binary files differ
diff --git a/src/gui/symbian/images/wait6.png b/src/gui/symbian/images/wait6.png
new file mode 100644
index 0000000..2870093
--- /dev/null
+++ b/src/gui/symbian/images/wait6.png
Binary files differ
diff --git a/src/gui/symbian/images/wait7.png b/src/gui/symbian/images/wait7.png
new file mode 100644
index 0000000..54f75a1
--- /dev/null
+++ b/src/gui/symbian/images/wait7.png
Binary files differ
diff --git a/src/gui/symbian/images/wait8.png b/src/gui/symbian/images/wait8.png
new file mode 100644
index 0000000..1d370c7
--- /dev/null
+++ b/src/gui/symbian/images/wait8.png
Binary files differ
diff --git a/src/gui/symbian/images/wait9.png b/src/gui/symbian/images/wait9.png
new file mode 100644
index 0000000..c28096f
--- /dev/null
+++ b/src/gui/symbian/images/wait9.png
Binary files differ
diff --git a/src/gui/symbian/images/whatsthis.png b/src/gui/symbian/images/whatsthis.png
new file mode 100644
index 0000000..3386ef0
--- /dev/null
+++ b/src/gui/symbian/images/whatsthis.png
Binary files differ
diff --git a/src/gui/symbian/symbianresources.qrc b/src/gui/symbian/symbianresources.qrc
new file mode 100644
index 0000000..0a4fc36
--- /dev/null
+++ b/src/gui/symbian/symbianresources.qrc
@@ -0,0 +1,37 @@
+<RCC>
+ <qresource prefix="/trolltech/symbian/cursors" >
+ <file>images/blank.png</file>
+ <file>images/busy3.png</file>
+ <file>images/busy6.png</file>
+ <file>images/busy9.png</file>
+ <file>images/busy12.png</file>
+ <file>images/closehand.png</file>
+ <file>images/cross.png</file>
+ <file>images/forbidden.png</file>
+ <file>images/handpoint.png</file>
+ <file>images/ibeam.png</file>
+ <file>images/openhand.png</file>
+ <file>images/pointer.png</file>
+ <file>images/sizeall.png</file>
+ <file>images/sizebdiag.png</file>
+ <file>images/sizefdiag.png</file>
+ <file>images/sizehor.png</file>
+ <file>images/sizever.png</file>
+ <file>images/splith.png</file>
+ <file>images/splitv.png</file>
+ <file>images/uparrow.png</file>
+ <file>images/wait1.png</file>
+ <file>images/wait2.png</file>
+ <file>images/wait3.png</file>
+ <file>images/wait4.png</file>
+ <file>images/wait5.png</file>
+ <file>images/wait6.png</file>
+ <file>images/wait7.png</file>
+ <file>images/wait8.png</file>
+ <file>images/wait9.png</file>
+ <file>images/wait10.png</file>
+ <file>images/wait11.png</file>
+ <file>images/wait12.png</file>
+ <file>images/whatsthis.png</file>
+ </qresource>
+</RCC>
diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp
index b4cea1b..e536928 100644
--- a/src/gui/widgets/qlineedit.cpp
+++ b/src/gui/widgets/qlineedit.cpp
@@ -2051,7 +2051,11 @@ void QLineEdit::changeEvent(QEvent *ev)
d->control->setFont(font());
break;
case QEvent::StyleChange:
- d->control->setPasswordCharacter(style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter));
+ {
+ QStyleOptionFrameV2 opt;
+ initStyleOption(&opt);
+ d->control->setPasswordCharacter(style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, this));
+ }
update();
break;
case QEvent::LayoutDirectionChange:
diff --git a/src/gui/widgets/qlineedit_p.cpp b/src/gui/widgets/qlineedit_p.cpp
index 4fe02a2..148da1b 100644
--- a/src/gui/widgets/qlineedit_p.cpp
+++ b/src/gui/widgets/qlineedit_p.cpp
@@ -159,7 +159,10 @@ void QLineEditPrivate::init(const QString& txt)
QObject::connect(control, SIGNAL(updateNeeded(const QRect &)),
q, SLOT(update()));
- control->setPasswordCharacter(q->style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter));
+
+ QStyleOptionFrameV2 opt;
+ q->initStyleOption(&opt);
+ control->setPasswordCharacter(q->style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, q));
#ifndef QT_NO_CURSOR
q->setCursor(Qt::IBeamCursor);
#endif
diff --git a/src/multimedia/audio/qaudiodeviceinfo.cpp b/src/multimedia/audio/qaudiodeviceinfo.cpp
index e349733..e38a91e 100644
--- a/src/multimedia/audio/qaudiodeviceinfo.cpp
+++ b/src/multimedia/audio/qaudiodeviceinfo.cpp
@@ -71,7 +71,11 @@ QT_BEGIN_NAMESPACE
audio plugins installed and the audio device capabilities. If you need a specific format, you can check if
the device supports it with isFormatSupported(), or fetch a
supported format that is as close as possible to the format with
- nearestFormat().
+ nearestFormat(). For instance:
+
+ \snippet doc/src/snippets/audio/main.cpp 1
+ \dots 8
+ \snippet doc/src/snippets/audio/main.cpp 2
A QAudioDeviceInfo is constructed with a QAudioDeviceId, which is
an identifier for a physical device. It is used by Qt to construct
diff --git a/src/multimedia/audio/qaudioformat.cpp b/src/multimedia/audio/qaudioformat.cpp
index ddfcc2c..c23e454 100644
--- a/src/multimedia/audio/qaudioformat.cpp
+++ b/src/multimedia/audio/qaudioformat.cpp
@@ -134,7 +134,8 @@ public:
through functions in QAudioDeviceInfo. This class also lets you
query available parameter values for a device, so that you can set
the parameters yourself. See the QAudioDeviceInfo class
- description for details.
+ description for details. You need to know the format of the audio
+ streams you wish to play. Qt does not set up formats for you.
*/
/*!
diff --git a/src/multimedia/audio/qaudioinput.cpp b/src/multimedia/audio/qaudioinput.cpp
index edf6dd6..3c0d98e 100644
--- a/src/multimedia/audio/qaudioinput.cpp
+++ b/src/multimedia/audio/qaudioinput.cpp
@@ -128,7 +128,12 @@ QT_BEGIN_NAMESPACE
which states the QAudioInput has been in.
If an error should occur, you can fetch its reason with error().
- The possible error reasons are described by the QAudio::Error enum.
+ The possible error reasons are described by the QAudio::Error
+ enum. The QAudioInput will enter the \l{QAudio::}{StopState} when
+ an error is encountered. Connect to the stateChanged() signal to
+ handle the error:
+
+ \snippet doc/src/snippets/audio/main.cpp 0
\sa QAudioOutput, QAudioDeviceInfo
*/
diff --git a/src/multimedia/audio/qaudiooutput.cpp b/src/multimedia/audio/qaudiooutput.cpp
index 556b616..8a8edb4 100644
--- a/src/multimedia/audio/qaudiooutput.cpp
+++ b/src/multimedia/audio/qaudiooutput.cpp
@@ -129,9 +129,12 @@ QT_BEGIN_NAMESPACE
If an error occurs, you can fetch the \l{QAudio::Error}{error
type} with the error() function. Please see the QAudio::Error enum
- for a description of the possible errors that are reported.
+ for a description of the possible errors that are reported. When
+ an error is encountered, the state changes to QAudio::StopState.
+ You can check for errors by connecting to the stateChanged()
+ signal:
- If an error is encountered state changes to QAudio::StopState.
+ \snippet doc/src/snippets/audio/main.cpp 3
\sa QAudioInput, QAudioDeviceInfo
*/
diff --git a/src/network/kernel/qnetworkproxy_mac.cpp b/src/network/kernel/qnetworkproxy_mac.cpp
index 9e2b0e4..2c7e250 100644
--- a/src/network/kernel/qnetworkproxy_mac.cpp
+++ b/src/network/kernel/qnetworkproxy_mac.cpp
@@ -170,8 +170,7 @@ QList<QNetworkProxy> macQueryInternal(const QNetworkProxyQuery &query)
(CFStringRef)CFDictionaryGetValue(dict, kSCPropNetProxiesProxyAutoConfigURLString);
QString url = QCFString::toQString(pacUrl);
- // ### Use PAC somehow
- qDebug("Mac system proxy: found PAC script at \"%s\"", qPrintable(url));
+ // ### TODO: Use PAC somehow
}
}
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index 3478130..63fe78e 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -917,9 +917,15 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxL
int wsaRet = ::WSARecvFrom(socketDescriptor, &buf, 1, &bytesRead, &flags, &aa.a, &sz,0,0);
if (wsaRet == SOCKET_ERROR) {
int err = WSAGetLastError();
- WS_ERROR_DEBUG(err);
- setError(QAbstractSocket::NetworkError, ReceiveDatagramErrorString);
- ret = -1;
+ if (err == WSAEMSGSIZE) {
+ // it is ok the buffer was to small if bytesRead is larger than
+ // maxLength then assume bytes read is really maxLenth
+ ret = qint64(bytesRead) > maxLength ? maxLength : qint64(bytesRead);
+ } else {
+ WS_ERROR_DEBUG(err);
+ setError(QAbstractSocket::NetworkError, ReceiveDatagramErrorString);
+ ret = -1;
+ }
} else {
ret = qint64(bytesRead);
}
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 5e790cf..e41d0b4 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -1385,6 +1385,7 @@ void QGL2PaintEngineEx::ensureActive()
d->device->ensureActiveTarget();
if (d->needsSync) {
+ d->transferMode(BrushDrawingMode);
glViewport(0, 0, d->width, d->height);
glDepthMask(false);
glDepthFunc(GL_LESS);
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index 4b8a67e..e4cef5f 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -66,6 +66,11 @@ extern QImage qt_gl_read_framebuffer(const QSize&, bool, bool);
#define QGL_FUNC_CONTEXT QGLContextGroup *ctx = d_ptr->ctx;
+#ifndef QT_NO_DEBUG
+#define QT_RESET_GLERROR() \
+{ \
+ while (glGetError() != GL_NO_ERROR) {} \
+}
#define QT_CHECK_GLERROR() \
{ \
GLenum err = glGetError(); \
@@ -74,6 +79,10 @@ extern QImage qt_gl_read_framebuffer(const QSize&, bool, bool);
__FILE__, __LINE__, (int)err); \
} \
}
+#else
+#define QT_RESET_GLERROR() {}
+#define QT_CHECK_GLERROR() {}
+#endif
/*!
\class QGLFramebufferObjectFormat
@@ -407,7 +416,7 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
target = texture_target;
// texture dimensions
- while (glGetError() != GL_NO_ERROR) {} // reset error state
+ QT_RESET_GLERROR(); // reset error state
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo);
diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp
index 6ebc397..43f1990 100644
--- a/src/opengl/qglpixmapfilter.cpp
+++ b/src/opengl/qglpixmapfilter.cpp
@@ -68,17 +68,15 @@ void QGLPixmapFilterBase::drawImpl(QPainter *painter, const QPointF &pos, const
processGL(painter, pos, src, source);
}
-class QGLPixmapColorizeFilter: public QGLPixmapFilter<QPixmapColorizeFilter>
+class QGLPixmapColorizeFilter: public QGLCustomShaderStage, public QGLPixmapFilter<QPixmapColorizeFilter>
{
public:
QGLPixmapColorizeFilter();
+ void setUniforms(QGLShaderProgram *program);
+
protected:
bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &pixmap, const QRectF &srcRect) const;
-
-private:
- mutable QGLShaderProgram m_program;
- int m_colorUniform;
};
class QGLPixmapConvolutionFilter: public QGLPixmapFilter<QPixmapConvolutionFilter>
@@ -105,7 +103,6 @@ class QGLPixmapBlurFilter : public QGLCustomShaderStage, public QGLPixmapFilter<
{
public:
QGLPixmapBlurFilter();
- ~QGLPixmapBlurFilter();
void setUniforms(QGLShaderProgram *program);
@@ -115,13 +112,13 @@ protected:
private:
static QByteArray generateBlurShader(int radius, bool gaussianBlur);
- mutable QGLShader *m_shader;
-
mutable QSize m_textureSize;
mutable bool m_horizontalBlur;
- QGLShaderProgram *m_program;
+ mutable bool m_haveCached;
+ mutable int m_cachedRadius;
+ mutable Qt::TransformationMode m_cachedQuality;
};
extern QGLWidget *qt_gl_share_widget();
@@ -183,41 +180,38 @@ static void qgl_drawTexture(const QRectF &rect, int tx_width, int tx_height, con
}
static const char *qt_gl_colorize_filter =
- "uniform sampler2D texture;"
- "uniform vec3 color;"
- "void main(void)"
+ "uniform lowp vec4 colorizeColor;"
+ "uniform lowp float colorizeStrength;"
+ "lowp vec4 customShader(lowp sampler2D src, highp vec2 srcCoords)"
"{"
- " vec2 coords = gl_TexCoord[0].st;"
- " vec4 src = texture2D(texture, coords);"
- " float gray = dot(src.rgb, vec3(0.212671, 0.715160, 0.072169));"
- " vec3 colorizeed = 1.0-((1.0-gray)*(1.0-color));"
- " gl_FragColor = vec4(colorizeed, src.a);"
+ " lowp vec4 srcPixel = texture2D(src, srcCoords);"
+ " lowp float gray = dot(srcPixel.rgb, vec3(0.212671, 0.715160, 0.072169));"
+ " lowp vec3 colorized = 1.0-((1.0-gray)*(1.0-colorizeColor.rgb));"
+ " return vec4(mix(srcPixel.rgb, colorized * srcPixel.a, colorizeStrength), srcPixel.a);"
"}";
QGLPixmapColorizeFilter::QGLPixmapColorizeFilter()
{
- m_program.addShader(QGLShader::FragmentShader, qt_gl_colorize_filter);
- m_program.link();
- m_program.enable();
- m_program.setUniformValue(m_program.uniformLocation("texture"), GLint(0)); // GL_TEXTURE_0
- m_colorUniform = m_program.uniformLocation("color");
+ setSource(qt_gl_colorize_filter);
}
-bool QGLPixmapColorizeFilter::processGL(QPainter *, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const
+bool QGLPixmapColorizeFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &) const
{
- bindTexture(src);
-
- QColor col = color();
- m_program.enable();
- m_program.setUniformValue(m_colorUniform, col.redF(), col.greenF(), col.blueF());
+ QGLPixmapColorizeFilter *filter = const_cast<QGLPixmapColorizeFilter *>(this);
- QRectF target = (srcRect.isNull() ? QRectF(src.rect()) : srcRect).translated(pos);
- qgl_drawTexture(target, src.width(), src.height(), srcRect);
- m_program.disable();
+ filter->setOnPainter(painter);
+ painter->drawPixmap(pos, src);
+ filter->removeFromPainter(painter);
return true;
}
+void QGLPixmapColorizeFilter::setUniforms(QGLShaderProgram *program)
+{
+ program->setUniformValue("colorizeColor", color());
+ program->setUniformValue("colorizeStrength", float(strength()));
+}
+
// generates convolution filter code for arbitrary sized kernel
QByteArray QGLPixmapConvolutionFilter::generateConvolutionShader() const {
QByteArray code;
@@ -311,17 +305,26 @@ bool QGLPixmapConvolutionFilter::processGL(QPainter *, const QPointF &pos, const
}
QGLPixmapBlurFilter::QGLPixmapBlurFilter()
-{
-}
-
-QGLPixmapBlurFilter::~QGLPixmapBlurFilter()
+ : m_haveCached(false), m_cachedRadius(5),
+ m_cachedQuality(Qt::FastTransformation)
{
}
bool QGLPixmapBlurFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &) const
{
QGLPixmapBlurFilter *filter = const_cast<QGLPixmapBlurFilter *>(this);
- filter->setSource(generateBlurShader(radius(), quality() == Qt::SmoothTransformation));
+
+ int radius = this->radius();
+ Qt::TransformationMode quality = this->quality();
+
+ if (!m_haveCached || radius != m_cachedRadius ||
+ quality != m_cachedQuality) {
+ // Only regenerate the shader from source if parameters have changed.
+ m_haveCached = true;
+ m_cachedRadius = radius;
+ m_cachedQuality = quality;
+ filter->setSource(generateBlurShader(radius, quality == Qt::SmoothTransformation));
+ }
QGLFramebufferObjectFormat format;
format.setInternalTextureFormat(GLenum(src.hasAlphaChannel() ? GL_RGBA : GL_RGB));
@@ -384,8 +387,6 @@ void QGLPixmapBlurFilter::setUniforms(QGLShaderProgram *program)
program->setUniformValue("delta", 1.0, 0.0);
else
program->setUniformValue("delta", 0.0, 1.0);
-
- m_program = program;
}
static inline qreal gaussian(qreal dx, qreal sigma)
diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp
index 0b7fe87..ebcd723 100644
--- a/src/opengl/qglshaderprogram.cpp
+++ b/src/opengl/qglshaderprogram.cpp
@@ -70,16 +70,7 @@ QT_BEGIN_NAMESPACE
program is activated in the current QGLContext by calling
QGLShaderProgram::enable():
- \code
- QGLShader shader(QGLShader::VertexShader);
- shader.compile(code);
-
- QGLShaderProgram program(context);
- program.addShader(shader);
- program.link();
-
- program.enable();
- \endcode
+ \snippet doc/src/snippets/code/src_opengl_qglshaderprogram.cpp 0
\section1 Writing portable shaders
@@ -107,49 +98,12 @@ QT_BEGIN_NAMESPACE
\section1 Simple shader example
- \code
- program.addShader(QGLShader::VertexShader,
- "attribute highp vec4 vertex;\n"
- "attribute mediump mat4 matrix;\n"
- "void main(void)\n"
- "{\n"
- " gl_Position = matrix * vertex;\n"
- "}");
- program.addShader(QGLShader::FragmentShader,
- "uniform mediump vec4 color;\n"
- "void main(void)\n"
- "{\n"
- " gl_FragColor = color;\n"
- "}");
- program.link();
- program.enable();
-
- int vertexLocation = program.attributeLocation("vertex");
- int matrixLocation = program.attributeLocation("matrix");
- int colorLocation = program.uniformLocation("color");
- \endcode
+ \snippet doc/src/snippets/code/src_opengl_qglshaderprogram.cpp 1
With the above shader program active, we can draw a green triangle
as follows:
- \code
- static GLfloat const triangleVertices[] = {
- 60.0f, 10.0f, 0.0f,
- 110.0f, 110.0f, 0.0f,
- 10.0f, 110.0f, 0.0f
- };
-
- QColor color(0, 255, 0, 255);
-
- QMatrix4x4 pmvMatrix;
- pmvMatrix.ortho(rect());
-
- program.setAttributeArray(vertexLocation, triangleVertices, 3);
- program.setUniformValue(matrixLocation, pmvMatrix);
- program.setUniformValue(colorLocation, color);
-
- glDrawArrays(GL_TRIANGLES, 0, 3);
- \endcode
+ \snippet doc/src/snippets/code/src_opengl_qglshaderprogram.cpp 2
\section1 Partial shaders
diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp
index ff00f29..bd3883a 100644
--- a/src/opengl/qpaintengine_opengl.cpp
+++ b/src/opengl/qpaintengine_opengl.cpp
@@ -5625,20 +5625,6 @@ void QOpenGLPaintEnginePrivate::ensureDrawableTexture()
#endif
}
-QPixmapFilter *QOpenGLPaintEngine::createPixmapFilter(int type) const
-{
-#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
- if (QGLContext::currentContext())
- return QGLContext::currentContext()->d_func()->createPixmapFilter(type);
- else
- return 0;
-#else
- Q_UNUSED(type);
- return 0;
-#endif
-}
-
-
QT_END_NAMESPACE
#include "qpaintengine_opengl.moc"
diff --git a/src/opengl/qpaintengine_opengl_p.h b/src/opengl/qpaintengine_opengl_p.h
index c8f460a..4fea638 100644
--- a/src/opengl/qpaintengine_opengl_p.h
+++ b/src/opengl/qpaintengine_opengl_p.h
@@ -136,8 +136,6 @@ public:
void drawEllipse(const QRectF &rect);
- QPixmapFilter *createPixmapFilter(int type) const;
-
#ifdef Q_WS_WIN
HDC handle() const;
#else
diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp
index 0bc46e1..3bc0d4f 100644
--- a/src/opengl/qpixmapdata_gl.cpp
+++ b/src/opengl/qpixmapdata_gl.cpp
@@ -98,7 +98,7 @@ QGLFramebufferObject *QGLFramebufferObjectPool::acquire(const QSize &requestSize
sz.setHeight(qMax(requestSize.height(), qRound(sz.height() * 1.5)));
// wasting too much space?
- if (sz.width() * sz.height() > requestSize.width() * requestSize.height() * 2.5)
+ if (sz.width() * sz.height() > requestSize.width() * requestSize.height() * 4)
sz = requestSize;
if (sz != fboSize) {
@@ -149,6 +149,7 @@ void QGLPixmapGLPaintDevice::beginPaint()
if (data->needsFill()) {
const QColor &c = data->fillColor();
float alpha = c.alphaF();
+ glDisable(GL_SCISSOR_TEST);
glClearColor(c.redF() * alpha, c.greenF() * alpha, c.blueF() * alpha, alpha);
glClear(GL_COLOR_BUFFER_BIT);
}
@@ -157,8 +158,23 @@ void QGLPixmapGLPaintDevice::beginPaint()
// uploaded from an image or rendered into before), we need to
// copy it from the texture to the render FBO.
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_SCISSOR_TEST);
+ glDisable(GL_BLEND);
+
+#if !defined(QT_OPENGL_ES_2)
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, data->width(), data->height(), 0, -999999, 999999);
+#endif
+
+ glViewport(0, 0, data->width(), data->height());
+
// Pass false to bind so it doesn't copy the FBO into the texture!
- context()->drawTexture(QPointF(0.0, 0.0), data->bind(false));
+ context()->drawTexture(QRect(0, 0, data->width(), data->height()), data->bind(false));
}
}
@@ -169,12 +185,11 @@ void QGLPixmapGLPaintDevice::endPaint()
data->copyBackFromRenderFbo(false);
- data->m_renderFbo->release();
- qgl_fbo_pool()->release(data->m_renderFbo);
- data->m_renderFbo = 0;
-
// Base's endPaint will restore the previous FBO binding
QGLPaintDevice::endPaint();
+
+ qgl_fbo_pool()->release(data->m_renderFbo);
+ data->m_renderFbo = 0;
}
QGLContext* QGLPixmapGLPaintDevice::context() const
@@ -452,8 +467,8 @@ void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const
if (!ctx->d_ptr->fbo)
glGenFramebuffers(1, &ctx->d_ptr->fbo);
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->fbo);
- glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, ctx->d_ptr->fbo);
+ glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, m_texture.id, 0);
const int x0 = 0;
@@ -461,7 +476,8 @@ void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const
const int y0 = 0;
const int y1 = h;
- glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, m_renderFbo->handle());
+ if (!m_renderFbo->isBound())
+ glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, m_renderFbo->handle());
glDisable(GL_SCISSOR_TEST);
diff --git a/src/plugins/gfxdrivers/directfb/directfb.pro b/src/plugins/gfxdrivers/directfb/directfb.pro
index d397050..0706f01 100644
--- a/src/plugins/gfxdrivers/directfb/directfb.pro
+++ b/src/plugins/gfxdrivers/directfb/directfb.pro
@@ -11,5 +11,5 @@ SOURCES += qdirectfbscreenplugin.cpp
QMAKE_CXXFLAGS += $$QT_CFLAGS_DIRECTFB
LIBS += $$QT_LIBS_DIRECTFB
-DEFINES += $$QT_DEFINES_DIRECTFB
+DEFINES += $$QT_DEFINES_DIRECTFB QT_DIRECTFB_PLUGIN
contains(gfx-plugins, directfb):DEFINES += QT_QWS_DIRECTFB
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
index 4413858..0f7a6de 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
@@ -1652,6 +1652,19 @@ void QDirectFBScreen::waitIdle()
d_ptr->dfb->WaitIdle(d_ptr->dfb);
}
+#ifdef QT_DIRECTFB_WM
+IDirectFBWindow *QDirectFBScreen::windowForWidget(const QWidget *widget) const
+{
+ if (widget) {
+ const QWSWindowSurface *surface = static_cast<const QWSWindowSurface*>(widget->windowSurface());
+ if (surface && surface->key() == QLatin1String("directfb")) {
+ return static_cast<const QDirectFBWindowSurface*>(surface)->directFBWindow();
+ }
+ }
+ return 0;
+}
+#endif
+
IDirectFBSurface * QDirectFBScreen::surfaceForWidget(const QWidget *widget, QRect *rect) const
{
Q_ASSERT(widget);
@@ -1687,6 +1700,26 @@ IDirectFBSurface *QDirectFBScreen::subSurfaceForWidget(const QWidget *widget, co
}
#endif
+#ifndef QT_DIRECTFB_PLUGIN
+Q_GUI_EXPORT IDirectFBSurface *qt_directfb_surface_for_widget(const QWidget *widget, QRect *rect)
+{
+ return QDirectFBScreen::instance() ? QDirectFBScreen::instance()->surfaceForWidget(widget, rect) : 0;
+}
+#ifdef QT_DIRECTFB_SUBSURFACE
+Q_GUI_EXPORT IDirectFBSurface *qt_directfb_subsurface_for_widget(const QWidget *widget, const QRect &area)
+{
+ return QDirectFBScreen::instance() ? QDirectFBScreen::instance()->subSurfaceForWidget(widget, area) : 0;
+}
+#endif
+#ifdef QT_DIRECTFB_WM
+Q_GUI_EXPORT IDirectFBWindow *qt_directfb_window_for_widget(const QWidget *widget)
+{
+ return QDirectFBScreen::instance() ? QDirectFBScreen::instance()->windowForWidget(widget) : 0;
+}
+
+#endif
+#endif
+
QT_END_NAMESPACE
#include "qdirectfbscreen.moc"
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h
index 79a01d3..febb2b2 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h
@@ -174,9 +174,10 @@ public:
#ifdef QT_DIRECTFB_SUBSURFACE
IDirectFBSurface *subSurfaceForWidget(const QWidget *widget, const QRect &area = QRect()) const;
#endif
-
IDirectFB *dfb();
-#ifdef QT_NO_DIRECTFB_WM
+#ifdef QT_DIRECTFB_WM
+ IDirectFBWindow *windowForWidget(const QWidget *widget) const;
+#else
IDirectFBSurface *primarySurface();
#endif
#ifndef QT_NO_DIRECTFB_LAYER
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
index ff9f7bd..4cebc96 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
@@ -113,13 +113,17 @@ bool QDirectFBWindowSurface::isValid() const
#ifdef QT_DIRECTFB_WM
void QDirectFBWindowSurface::raise()
{
- if (dfbWindow) {
- dfbWindow->RaiseToTop(dfbWindow);
- } else if (sibling && (!sibling->sibling || sibling->dfbWindow)) {
- sibling->raise();
+ if (IDirectFBWindow *window = directFBWindow()) {
+ window->RaiseToTop(window);
}
}
+IDirectFBWindow *QDirectFBWindowSurface::directFBWindow() const
+{
+ return (dfbWindow ? dfbWindow : (sibling ? sibling->dfbWindow : 0));
+}
+
+
void QDirectFBWindowSurface::createWindow(const QRect &rect)
{
IDirectFBDisplayLayer *layer = screen->dfbDisplayLayer();
@@ -411,7 +415,8 @@ IDirectFBSurface *QDirectFBWindowSurface::surfaceForWidget(const QWidget *widget
*rect = QRect(widget->mapTo(win, QPoint(0, 0)), widget->size());
}
}
- Q_ASSERT(win == widget || widget->isAncestorOf(win));
+
+ Q_ASSERT(win == widget || win->isAncestorOf(widget));
return dfbSurface;
}
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h
index 036830a..0dd3a3b 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h
@@ -93,6 +93,9 @@ public:
IDirectFBSurface *surfaceForWidget(const QWidget *widget, QRect *rect) const;
IDirectFBSurface *directFBSurface() const;
+#ifdef QT_DIRECTFB_WM
+ IDirectFBWindow *directFBWindow() const;
+#endif
private:
void updateFormat();
void releaseSurface();
diff --git a/src/qbase.pri b/src/qbase.pri
index 27e4992..4639ca1 100644
--- a/src/qbase.pri
+++ b/src/qbase.pri
@@ -101,7 +101,15 @@ symbian {
"DEFFILE ../s60installs/eabi/$${TARGET}.def" \
"$${LITERAL_HASH}endif"
+ #with defBlock enabled, removed exported symbols are treated as errors
+ #and there is binary compatibility between successive builds.
+ #with defBlock disabled, binary compatibility is broken every time you build
#MMP_RULES += defBlock
+
+ #with EXPORTUNFROZEN enabled, new exports are included in the dll without
+ #needing to run abld freeze, however binary compatibility is only maintained
+ #for symbols that are frozen (and only if defBlock is also enabled)
+ #the downside of EXPORTUNFROZEN is that the linker gets run twice
MMP_RULES += EXPORTUNFROZEN
}
load(armcc_warnings)
diff --git a/src/svg/qgraphicssvgitem.cpp b/src/svg/qgraphicssvgitem.cpp
index ea26c78..bcdd821 100644
--- a/src/svg/qgraphicssvgitem.cpp
+++ b/src/svg/qgraphicssvgitem.cpp
@@ -265,6 +265,12 @@ int QGraphicsSvgItem::type() const
return Type;
}
+/*!
+ \property QGraphicsSvgItem::maximumCacheSize
+
+ This property holds the maximum size of the device coordinate cache
+ for this item.
+ */
/*!
Sets the maximum device coordinate cache size of the item to \a size.
@@ -305,8 +311,13 @@ QSize QGraphicsSvgItem::maximumCacheSize() const
}
/*!
- Sets the XML ID of the element that this item should render to \a
- id.
+ \property QGraphicsSvgItem::elementId
+
+ This property holds the element's XML ID.
+ */
+
+/*!
+ Sets the XML ID of the element to \a id.
*/
void QGraphicsSvgItem::setElementId(const QString &id)
{
@@ -318,7 +329,7 @@ void QGraphicsSvgItem::setElementId(const QString &id)
/*!
Returns the XML ID the element that is currently
- being renderer. Returns an empty string if the whole
+ being rendered. Returns an empty string if the whole
file is being rendered.
*/
QString QGraphicsSvgItem::elementId() const
diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h
index 5171d3a..f2d865b 100644
--- a/src/testlib/qtest.h
+++ b/src/testlib/qtest.h
@@ -252,7 +252,7 @@ int main(int argc, char *argv[]) \
#include <QtTest/qtest_gui.h>
#ifdef QT_KEYPAD_NAVIGATION
-# define QTEST_DISABLE_KEYPAD_NAVIGATION QApplication::setKeypadNavigationEnabled(false);
+# define QTEST_DISABLE_KEYPAD_NAVIGATION QApplication::setNavigationMode(Qt::NavigationModeNone);
#else
# define QTEST_DISABLE_KEYPAD_NAVIGATION
#endif
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index b7b2327..74c3af9 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -311,7 +311,7 @@ QT_BEGIN_NAMESPACE
Example:
\snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 11
- \sa QTEST_APPLESS_MAIN(), QTest::qExec(), QApplication::setKeypadNavigationEnabled()
+ \sa QTEST_APPLESS_MAIN(), QTest::qExec(), QApplication::setNavigationMode()
*/
/*! \macro QTEST_APPLESS_MAIN(TestClass)